Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]


## [0.3.4] - 2026-06-15

### Changed

- feat(queries): add preview and total row count fields

## [0.3.3] - 2026-06-10

### Changed
Expand Down
1 change: 1 addition & 0 deletions docs/QueryApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ Name | Type | Description | Notes
**202** | Query submitted asynchronously | - |
**400** | Invalid request (no database specified, or header/body database_id conflict) | - |
**404** | Database not found | - |
**429** | Too many concurrent queries; retry after the Retry-After delay | - |
**500** | Internal server error | - |

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
Expand Down
5 changes: 4 additions & 1 deletion docs/QueryResponse.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ Name | Type | Description | Notes
**columns** | **List[str]** | |
**execution_time_ms** | **int** | |
**nullable** | **List[bool]** | Nullable flags for each column (parallel to columns vec). True if the column allows NULL values, false if NOT NULL. |
**preview_row_count** | **int** | Number of rows in *this* response body (`rows.len()`). Always present. For a large result this is a bounded preview, not the grand total — see `total_row_count` and `truncated` (#640). |
**query_run_id** | **str** | Unique identifier for the query run record (qrun...). |
**result_id** | **str** | Unique identifier for retrieving this result via GET /results/{id}. Null if catalog registration failed (see `warning` field for details). When non-null, the result is being persisted asynchronously. | [optional]
**row_count** | **int** | |
**row_count** | **int** | **Deprecated** — use `preview_row_count` (rows in this body) and `total_row_count` (grand total) instead. Retained for backward compatibility and currently always equal to `preview_row_count`; it will be removed in a future release once clients migrate to the count fields below (#640). |
**rows** | **List[List[object]]** | Array of rows, where each row is an array of column values. Values can be strings, numbers, booleans, or null. |
**total_row_count** | **int** | Grand total rows in the full result. Present (and equal to `preview_row_count`) when the whole result fit in this response; `null` while a truncated result is still being persisted. When `null`, read the authoritative total from `GET /v1/query-runs/{id}` (`row_count`) or the `X-Total-Row-Count` header on `GET /v1/results/{id}` (#640). | [optional]
**truncated** | **bool** | True when `rows` is a bounded preview of a larger result. Fetch the full result via `result_id` (#640). Always `false` until bounded streaming is enabled; clients should still branch on it so no code change is needed when truncation goes live. |
**warning** | **str** | Warning message if result persistence could not be initiated. When present, `result_id` will be null and the result cannot be retrieved later. The query results are still returned in this response. | [optional]

## Example
Expand Down
3 changes: 3 additions & 0 deletions hotdata/api/query_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def query(
'202': "AsyncQueryResponse",
'400': "ApiErrorResponse",
'404': "ApiErrorResponse",
'429': "ApiErrorResponse",
'500': "ApiErrorResponse",
}
response_data = self.api_client.call_api(
Expand Down Expand Up @@ -177,6 +178,7 @@ def query_with_http_info(
'202': "AsyncQueryResponse",
'400': "ApiErrorResponse",
'404': "ApiErrorResponse",
'429': "ApiErrorResponse",
'500': "ApiErrorResponse",
}
response_data = self.api_client.call_api(
Expand Down Expand Up @@ -252,6 +254,7 @@ def query_without_preload_content(
'202': "AsyncQueryResponse",
'400': "ApiErrorResponse",
'404': "ApiErrorResponse",
'429': "ApiErrorResponse",
'500': "ApiErrorResponse",
}
response_data = self.api_client.call_api(
Expand Down
2 changes: 1 addition & 1 deletion hotdata/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def __init__(
self.default_headers[header_name] = header_value
self.cookie = cookie
# Set default User-Agent.
self.user_agent = 'OpenAPI-Generator/0.3.3/python'
self.user_agent = 'OpenAPI-Generator/0.3.4/python'
self.client_side_validation = configuration.client_side_validation

def __enter__(self):
Expand Down
17 changes: 14 additions & 3 deletions hotdata/models/query_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import re # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from typing import Optional, Set
Expand All @@ -31,12 +31,15 @@ class QueryResponse(BaseModel):
columns: List[StrictStr]
execution_time_ms: Annotated[int, Field(strict=True, ge=0)]
nullable: List[StrictBool] = Field(description="Nullable flags for each column (parallel to columns vec). True if the column allows NULL values, false if NOT NULL.")
preview_row_count: StrictInt = Field(description="Number of rows in *this* response body (`rows.len()`). Always present. For a large result this is a bounded preview, not the grand total — see `total_row_count` and `truncated` (#640).")
query_run_id: StrictStr = Field(description="Unique identifier for the query run record (qrun...).")
result_id: Optional[StrictStr] = Field(default=None, description="Unique identifier for retrieving this result via GET /results/{id}. Null if catalog registration failed (see `warning` field for details). When non-null, the result is being persisted asynchronously.")
row_count: Annotated[int, Field(strict=True, ge=0)]
row_count: Annotated[int, Field(strict=True, ge=0)] = Field(description="**Deprecated** — use `preview_row_count` (rows in this body) and `total_row_count` (grand total) instead. Retained for backward compatibility and currently always equal to `preview_row_count`; it will be removed in a future release once clients migrate to the count fields below (#640).")
rows: List[List[Any]] = Field(description="Array of rows, where each row is an array of column values. Values can be strings, numbers, booleans, or null.")
total_row_count: Optional[StrictInt] = Field(default=None, description="Grand total rows in the full result. Present (and equal to `preview_row_count`) when the whole result fit in this response; `null` while a truncated result is still being persisted. When `null`, read the authoritative total from `GET /v1/query-runs/{id}` (`row_count`) or the `X-Total-Row-Count` header on `GET /v1/results/{id}` (#640).")
truncated: StrictBool = Field(description="True when `rows` is a bounded preview of a larger result. Fetch the full result via `result_id` (#640). Always `false` until bounded streaming is enabled; clients should still branch on it so no code change is needed when truncation goes live.")
warning: Optional[StrictStr] = Field(default=None, description="Warning message if result persistence could not be initiated. When present, `result_id` will be null and the result cannot be retrieved later. The query results are still returned in this response.")
__properties: ClassVar[List[str]] = ["columns", "execution_time_ms", "nullable", "query_run_id", "result_id", "row_count", "rows", "warning"]
__properties: ClassVar[List[str]] = ["columns", "execution_time_ms", "nullable", "preview_row_count", "query_run_id", "result_id", "row_count", "rows", "total_row_count", "truncated", "warning"]

model_config = ConfigDict(
populate_by_name=True,
Expand Down Expand Up @@ -82,6 +85,11 @@ def to_dict(self) -> Dict[str, Any]:
if self.result_id is None and "result_id" in self.model_fields_set:
_dict['result_id'] = None

# set to None if total_row_count (nullable) is None
# and model_fields_set contains the field
if self.total_row_count is None and "total_row_count" in self.model_fields_set:
_dict['total_row_count'] = None

# set to None if warning (nullable) is None
# and model_fields_set contains the field
if self.warning is None and "warning" in self.model_fields_set:
Expand All @@ -102,10 +110,13 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"columns": obj.get("columns"),
"execution_time_ms": obj.get("execution_time_ms"),
"nullable": obj.get("nullable"),
"preview_row_count": obj.get("preview_row_count"),
"query_run_id": obj.get("query_run_id"),
"result_id": obj.get("result_id"),
"row_count": obj.get("row_count"),
"rows": obj.get("rows"),
"total_row_count": obj.get("total_row_count"),
"truncated": obj.get("truncated"),
"warning": obj.get("warning")
})
return _obj
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "hotdata"
version = "0.3.3"
version = "0.3.4"
description = "Hotdata API"
authors = [
{name = "Hotdata",email = "developers@hotdata.dev"},
Expand Down
5 changes: 5 additions & 0 deletions test/test_query_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def make_instance(self, include_optional) -> QueryResponse:
nullable = [
True
],
preview_row_count = 56,
query_run_id = '',
result_id = '',
row_count = 0,
Expand All @@ -51,6 +52,8 @@ def make_instance(self, include_optional) -> QueryResponse:
null
]
],
total_row_count = 56,
truncated = True,
warning = ''
)
else:
Expand All @@ -62,13 +65,15 @@ def make_instance(self, include_optional) -> QueryResponse:
nullable = [
True
],
preview_row_count = 56,
query_run_id = '',
row_count = 0,
rows = [
[
null
]
],
truncated = True,
)
"""

Expand Down