hotdata
Official Python client for the Hotdata HTTP API: workspaces, connections, instant databases, SQL queries, results, uploads, indexes, jobs, embedding providers, and database context.
Requirements
Python 3.10+
Install
pip install hotdata
For an unreleased revision:
pip install "git+https://github.com/hotdata-dev/sdk-python.git"
From a local checkout (editable):
pip install -e .
Authentication
The API uses an API key sent as Authorization: Bearer <key>, plus an X-Workspace-Id header on requests scoped to a workspace.
import hotdata
configuration = hotdata.Configuration(
api_key="YOUR_API_KEY",
workspace_id="YOUR_WORKSPACE_ID",
)
host defaults to https://api.hotdata.dev. Override it if you target another environment.
Usage
import hotdata
from hotdata.rest import ApiException
configuration = hotdata.Configuration(
api_key="YOUR_API_KEY",
workspace_id="YOUR_WORKSPACE_ID",
)
with hotdata.ApiClient(configuration) as api_client:
workspaces = hotdata.WorkspacesApi(api_client)
try:
response = workspaces.list_workspaces()
except ApiException as e:
print(f"API error: {e.status} {e.reason}\n{e.body}")
Each Api class groups endpoints by resource. Construct the client, then call the typed methods you need.
Arrow results
Query results can be fetched as an Apache Arrow IPC stream instead of JSON, which is faster and far more memory-efficient for large result sets. Install the optional extra:
pip install 'hotdata[arrow]'
Use hotdata.arrow.ResultsApi (a drop-in subclass of ResultsApi that adds Arrow methods):
from hotdata import ApiClient, Configuration
from hotdata.arrow import ResultsApi
with ApiClient(Configuration(api_key="...", workspace_id="...")) as client:
results = ResultsApi(client)
# Results are scoped to a database via the required `X-Database-Id` header,
# so pass the id of the database the query ran in.
database_id = "your_database_id"
# Buffered: returns a pyarrow.Table.
table = results.get_result_arrow(result_id, database_id)
# Streaming: yields a pyarrow.RecordBatchStreamReader without
# materializing the full table in memory.
with results.stream_result_arrow(result_id, database_id) as reader:
for batch in reader:
...
Both methods accept offset and limit for pagination. They raise hotdata.arrow.ResultNotReadyError if the result is still pending or processing — poll results.get_result(result_id, database_id) until status == "ready" first.
File uploads
hotdata.uploads.UploadsApi (also the default hotdata.UploadsApi) adds
upload_file, which uploads a local file directly to object storage and
finalizes it in one call. It opens an upload session, PUTs the bytes straight
to storage — a single PUT for a small file, concurrent part PUTs for a large
one — then finalizes. The bytes never round-trip through the API.
from hotdata import ApiClient, Configuration, UploadsApi
with ApiClient(Configuration(api_key="...", workspace_id="...")) as client:
uploads = UploadsApi(client)
finalized = uploads.upload_file(
"data.parquet",
content_type="application/parquet",
progress=lambda done, total: print(f"{done}/{total} bytes"),
)
# Pass finalized.upload_id to the managed-table load endpoint.
print(finalized.upload_id)
upload_file accepts a path, raw bytes, or a seekable binary file object
(size is inferred for all three; a file object is read from its current
position to the end). The SDK picks single vs. multipart from the size,
auto-scales the part size, and bounds part concurrency to a peak-memory budget
(override with part_size / max_concurrency / part_retry). A file larger than
8 MiB uploads via a streaming session — the SDK mints each part's URL just
before its PUT, so a presigned URL can't expire mid-transfer on a slow upload.
Storage PUTs go through a dedicated, header-isolated connection pool (auth and
workspace headers never reach object storage, which would otherwise reject the
upload) with a 30s connect timeout so a dead endpoint fails fast. Finalize is sent
with retries disabled so the exactly-once call is never accidentally replayed.
Every failure is a subclass of hotdata.uploads.UploadError (also importable as
from hotdata import UploadError), so a single except UploadError catches the
whole flow: SessionCreateError (opening the session — check .status for a
501 PRESIGN_UNSUPPORTED), StorageError (storage returned a non-2xx; .exhausted
is True if it outlived every retry round), StorageTransportError (the PUT
failed before any response), MissingETagError, MintPartError (minting a part
URL), FinalizeError, MalformedSessionError, SizeLimitError, and
UploadCancelledError. The phase errors that wrap a control-plane call chain the
underlying hotdata.exceptions.ApiException as __cause__ (and expose it as
.api_exception / .status). A local file read error surfaces as OSError.
The progress callback receives a cumulative (bytes_done, total) — for a
tqdm bar (whose update(n) wants a delta, and which isn't thread-safe under
multipart) use the ready-made adapter:
from hotdata import tqdm_progress
from tqdm import tqdm
with tqdm(total=size, unit="B", unit_scale=True) as bar:
uploads.upload_file("data.parquet", progress=tqdm_progress(bar))
Pass a threading.Event as cancel_event to abort an in-flight upload; tune the
control-plane calls with request_timeout (storage-PUT timeouts are automatic and
size-scaled).
API reference
Generated Markdown for every operation and model is in docs/:
- Resource APIs:
docs/*Api.md(for exampleQueryApi.md) - Request and response models:
docs/<ModelName>.md
Support
Questions and issues: github.com/hotdata-dev/sdk-python.
Metadata
Release files for hotdata 0.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hotdata-0.11.0.tar.gz | 207.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hotdata-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 499.9 kB
Release files / hotdata-0.11.0.tar.gz
| Download URL | hotdata-0.11.0.tar.gz |
|---|---|
| Size | 207.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0e9fd242baa51b9350a969222319bcdf2c6ede1cf2e8a99e3f81d608af7b6fc
|
|
BLAKE2b-256 checksum How to use checksums |
1d101a21c58de1fee8c63bf983db9531704e9b0611c63fd7a849a9ffdf9cc8c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency logRelease files / hotdata-0.11.0-py3-none-any.whl
| Download URL | hotdata-0.11.0-py3-none-any.whl |
|---|---|
| Size | 292.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4ece2f43bac9a4f43ad32c305aa93042aa4a4f68a5bbdec4f2c6ae0b29f591d6
|
|
BLAKE2b-256 checksum How to use checksums |
aca4cc71105c5971d29b40cfff76ab592fed95e1d433903631f9d2fccede50a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency log