Skip to content

Commit ccbd417

Browse files
feat(uploads): add file upload endpoints
1 parent fcf742e commit ccbd417

28 files changed

Lines changed: 2627 additions & 0 deletions

.openapi-generator/FILES

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ docs/ApiErrorDetail.md
88
docs/ApiErrorResponse.md
99
docs/AsyncQueryResponse.md
1010
docs/AttachDatabaseCatalogRequest.md
11+
docs/BatchCreateUploadRequest.md
12+
docs/BatchCreateUploadResponse.md
1113
docs/BooleanProfileDetail.md
1214
docs/CategoricalProfileDetail.md
1315
docs/CategoryValueInfo.md
@@ -37,6 +39,7 @@ docs/CreateIndexRequest.md
3739
docs/CreateSavedQueryRequest.md
3840
docs/CreateSecretRequest.md
3941
docs/CreateSecretResponse.md
42+
docs/CreateUploadRequest.md
4043
docs/CreateWorkspaceRequest.md
4144
docs/CreateWorkspaceResponse.md
4245
docs/DatabaseAttachmentInfo.md
@@ -52,6 +55,9 @@ docs/EmbeddingProviderResponse.md
5255
docs/EmbeddingProvidersApi.md
5356
docs/Error.md
5457
docs/ExecuteSavedQueryRequest.md
58+
docs/FinalizeUploadPart.md
59+
docs/FinalizeUploadRequest.md
60+
docs/FinalizeUploadResponse.md
5561
docs/GetConnectionResponse.md
5662
docs/GetDatabaseContextResponse.md
5763
docs/GetResultResponse.md
@@ -120,6 +126,7 @@ docs/UpdateSecretRequest.md
120126
docs/UpdateSecretResponse.md
121127
docs/UploadInfo.md
122128
docs/UploadResponse.md
129+
docs/UploadSessionResponse.md
123130
docs/UploadsApi.md
124131
docs/UpsertDatabaseContextRequest.md
125132
docs/UpsertDatabaseContextResponse.md
@@ -159,6 +166,8 @@ hotdata/models/api_error_detail.py
159166
hotdata/models/api_error_response.py
160167
hotdata/models/async_query_response.py
161168
hotdata/models/attach_database_catalog_request.py
169+
hotdata/models/batch_create_upload_request.py
170+
hotdata/models/batch_create_upload_response.py
162171
hotdata/models/boolean_profile_detail.py
163172
hotdata/models/categorical_profile_detail.py
164173
hotdata/models/category_value_info.py
@@ -186,6 +195,7 @@ hotdata/models/create_index_request.py
186195
hotdata/models/create_saved_query_request.py
187196
hotdata/models/create_secret_request.py
188197
hotdata/models/create_secret_response.py
198+
hotdata/models/create_upload_request.py
189199
hotdata/models/create_workspace_request.py
190200
hotdata/models/create_workspace_response.py
191201
hotdata/models/database_attachment_info.py
@@ -198,6 +208,9 @@ hotdata/models/discovery_status.py
198208
hotdata/models/embedding_provider_response.py
199209
hotdata/models/error.py
200210
hotdata/models/execute_saved_query_request.py
211+
hotdata/models/finalize_upload_part.py
212+
hotdata/models/finalize_upload_request.py
213+
hotdata/models/finalize_upload_response.py
201214
hotdata/models/get_connection_response.py
202215
hotdata/models/get_database_context_response.py
203216
hotdata/models/get_result_response.py
@@ -257,6 +270,7 @@ hotdata/models/update_secret_request.py
257270
hotdata/models/update_secret_response.py
258271
hotdata/models/upload_info.py
259272
hotdata/models/upload_response.py
273+
hotdata/models/upload_session_response.py
260274
hotdata/models/upsert_database_context_request.py
261275
hotdata/models/upsert_database_context_response.py
262276
hotdata/models/workspace_detail.py
@@ -273,6 +287,8 @@ test/test_api_error_detail.py
273287
test/test_api_error_response.py
274288
test/test_async_query_response.py
275289
test/test_attach_database_catalog_request.py
290+
test/test_batch_create_upload_request.py
291+
test/test_batch_create_upload_response.py
276292
test/test_boolean_profile_detail.py
277293
test/test_categorical_profile_detail.py
278294
test/test_category_value_info.py
@@ -302,6 +318,7 @@ test/test_create_index_request.py
302318
test/test_create_saved_query_request.py
303319
test/test_create_secret_request.py
304320
test/test_create_secret_response.py
321+
test/test_create_upload_request.py
305322
test/test_create_workspace_request.py
306323
test/test_create_workspace_response.py
307324
test/test_database_attachment_info.py
@@ -317,6 +334,9 @@ test/test_embedding_provider_response.py
317334
test/test_embedding_providers_api.py
318335
test/test_error.py
319336
test/test_execute_saved_query_request.py
337+
test/test_finalize_upload_part.py
338+
test/test_finalize_upload_request.py
339+
test/test_finalize_upload_response.py
320340
test/test_get_connection_response.py
321341
test/test_get_database_context_response.py
322342
test/test_get_result_response.py
@@ -385,6 +405,7 @@ test/test_update_secret_request.py
385405
test/test_update_secret_response.py
386406
test/test_upload_info.py
387407
test/test_upload_response.py
408+
test/test_upload_session_response.py
388409
test/test_uploads_api.py
389410
test/test_upsert_database_context_request.py
390411
test/test_upsert_database_context_response.py

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12+
- feat(uploads): add file upload endpoints
1213
- docs: remove stale datasets references, refresh MCP + CLI reference
1314
- feat(tables): add csv and json file format support for table loads
1415
- Regenerate the client from the updated Hotdata OpenAPI spec

docs/BatchCreateUploadRequest.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# BatchCreateUploadRequest
2+
3+
Request body for `POST /v1/uploads/batch`: create several upload sessions in one call. Each entry is planned independently; the response returns one session per request, in the same order.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**uploads** | [**List[CreateUploadRequest]**](CreateUploadRequest.md) | |
10+
11+
## Example
12+
13+
```python
14+
from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest
15+
16+
# TODO update the JSON string below
17+
json = "{}"
18+
# create an instance of BatchCreateUploadRequest from a JSON string
19+
batch_create_upload_request_instance = BatchCreateUploadRequest.from_json(json)
20+
# print the JSON string representation of the object
21+
print(BatchCreateUploadRequest.to_json())
22+
23+
# convert the object into a dict
24+
batch_create_upload_request_dict = batch_create_upload_request_instance.to_dict()
25+
# create an instance of BatchCreateUploadRequest from a dict
26+
batch_create_upload_request_from_dict = BatchCreateUploadRequest.from_dict(batch_create_upload_request_dict)
27+
```
28+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
29+
30+

docs/BatchCreateUploadResponse.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# BatchCreateUploadResponse
2+
3+
Response body for `POST /v1/uploads/batch`: one created session per requested file, in request order.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**uploads** | [**List[UploadSessionResponse]**](UploadSessionResponse.md) | |
10+
11+
## Example
12+
13+
```python
14+
from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse
15+
16+
# TODO update the JSON string below
17+
json = "{}"
18+
# create an instance of BatchCreateUploadResponse from a JSON string
19+
batch_create_upload_response_instance = BatchCreateUploadResponse.from_json(json)
20+
# print the JSON string representation of the object
21+
print(BatchCreateUploadResponse.to_json())
22+
23+
# convert the object into a dict
24+
batch_create_upload_response_dict = batch_create_upload_response_instance.to_dict()
25+
# create an instance of BatchCreateUploadResponse from a dict
26+
batch_create_upload_response_from_dict = BatchCreateUploadResponse.from_dict(batch_create_upload_response_dict)
27+
```
28+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
29+
30+

docs/CreateUploadRequest.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# CreateUploadRequest
2+
3+
Request body for `POST /v1/uploads` and for each entry of `POST /v1/uploads/batch`. Describes a single file you intend to upload directly to storage. The service chooses where the bytes are stored and returns a short-lived URL to `PUT` them to; you do not pick the storage location. The declared size is validated against the bytes you actually upload when you finalize.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**checksum_algo** | **str** | Integrity checksum algorithm you are volunteering for this file. Currently only `sha256` is accepted. Optional; pair with `checksum_value`. | [optional]
10+
**checksum_value** | **str** | Integrity checksum value, paired with `checksum_algo`. Optional. | [optional]
11+
**content_encoding** | **str** | Content encoding to record for the uploaded file (for example `gzip`). Optional. | [optional]
12+
**content_type** | **str** | Content type to record for the uploaded file (for example the Parquet, CSV, or JSON MIME type). Optional. | [optional]
13+
**declared_size_bytes** | **int** | The exact size, in bytes, of the file you will upload. Validated at create time against the maximum allowed size, and again at finalize against the bytes actually stored — a mismatch fails the finalize. |
14+
**filename** | **str** | Original file name, recorded with the upload for your own bookkeeping. Optional and advisory — it does not affect where the bytes are stored or how they are loaded. | [optional]
15+
**part_size** | **int** | Preferred size, in bytes, of each part for a large (multi-part) upload. Optional hint — the service clamps it to the allowed part-size range and to the maximum number of parts, and ignores it for small files uploaded with a single `PUT`. Omit to let the service choose. | [optional]
16+
17+
## Example
18+
19+
```python
20+
from hotdata.models.create_upload_request import CreateUploadRequest
21+
22+
# TODO update the JSON string below
23+
json = "{}"
24+
# create an instance of CreateUploadRequest from a JSON string
25+
create_upload_request_instance = CreateUploadRequest.from_json(json)
26+
# print the JSON string representation of the object
27+
print(CreateUploadRequest.to_json())
28+
29+
# convert the object into a dict
30+
create_upload_request_dict = create_upload_request_instance.to_dict()
31+
# create an instance of CreateUploadRequest from a dict
32+
create_upload_request_from_dict = CreateUploadRequest.from_dict(create_upload_request_dict)
33+
```
34+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
35+
36+

docs/FinalizeUploadPart.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# FinalizeUploadPart
2+
3+
One part of a multi-part upload, supplied at finalize. Reserved for a future multi-part mode; single-`PUT` uploads have no parts.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**e_tag** | **str** | The entity tag (ETag) storage returned for the uploaded part. |
10+
**part_number** | **int** | 1-based part number, as reported by storage for the part. |
11+
12+
## Example
13+
14+
```python
15+
from hotdata.models.finalize_upload_part import FinalizeUploadPart
16+
17+
# TODO update the JSON string below
18+
json = "{}"
19+
# create an instance of FinalizeUploadPart from a JSON string
20+
finalize_upload_part_instance = FinalizeUploadPart.from_json(json)
21+
# print the JSON string representation of the object
22+
print(FinalizeUploadPart.to_json())
23+
24+
# convert the object into a dict
25+
finalize_upload_part_dict = finalize_upload_part_instance.to_dict()
26+
# create an instance of FinalizeUploadPart from a dict
27+
finalize_upload_part_from_dict = FinalizeUploadPart.from_dict(finalize_upload_part_dict)
28+
```
29+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
30+
31+

docs/FinalizeUploadRequest.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# FinalizeUploadRequest
2+
3+
Request body for `POST /v1/uploads/{upload_id}/finalize`. Finalizing confirms the bytes were uploaded and makes the upload usable as managed-table contents. The request body is optional for single-`PUT` uploads; send `parts` only for a future multi-part upload.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**parts** | [**List[FinalizeUploadPart]**](FinalizeUploadPart.md) | Parts to assemble, for a multi-part upload. Omit for single-`PUT` uploads (the common case). | [optional]
10+
11+
## Example
12+
13+
```python
14+
from hotdata.models.finalize_upload_request import FinalizeUploadRequest
15+
16+
# TODO update the JSON string below
17+
json = "{}"
18+
# create an instance of FinalizeUploadRequest from a JSON string
19+
finalize_upload_request_instance = FinalizeUploadRequest.from_json(json)
20+
# print the JSON string representation of the object
21+
print(FinalizeUploadRequest.to_json())
22+
23+
# convert the object into a dict
24+
finalize_upload_request_dict = finalize_upload_request_instance.to_dict()
25+
# create an instance of FinalizeUploadRequest from a dict
26+
finalize_upload_request_from_dict = FinalizeUploadRequest.from_dict(finalize_upload_request_dict)
27+
```
28+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
29+
30+

docs/FinalizeUploadResponse.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# FinalizeUploadResponse
2+
3+
Response body for `POST /v1/uploads/{upload_id}/finalize`: the finalized upload, ready to be loaded into a managed table.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**content_type** | **str** | | [optional]
10+
**created_at** | **datetime** | |
11+
**size_bytes** | **int** | The validated size of the uploaded file in bytes. |
12+
**status** | **str** | |
13+
**upload_id** | **str** | |
14+
15+
## Example
16+
17+
```python
18+
from hotdata.models.finalize_upload_response import FinalizeUploadResponse
19+
20+
# TODO update the JSON string below
21+
json = "{}"
22+
# create an instance of FinalizeUploadResponse from a JSON string
23+
finalize_upload_response_instance = FinalizeUploadResponse.from_json(json)
24+
# print the JSON string representation of the object
25+
print(FinalizeUploadResponse.to_json())
26+
27+
# convert the object into a dict
28+
finalize_upload_response_dict = finalize_upload_response_instance.to_dict()
29+
# create an instance of FinalizeUploadResponse from a dict
30+
finalize_upload_response_from_dict = FinalizeUploadResponse.from_dict(finalize_upload_response_dict)
31+
```
32+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
33+
34+

docs/UploadSessionResponse.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# UploadSessionResponse
2+
3+
A created upload session: everything needed to upload the bytes directly to storage and later finalize the upload.
4+
5+
## Properties
6+
7+
Name | Type | Description | Notes
8+
------------ | ------------- | ------------- | -------------
9+
**finalize_token** | **str** | One-time token that authorizes finalizing this upload. Returned exactly once at create time — store it; it cannot be retrieved again. |
10+
**headers** | **Dict[str, str]** | Headers you must send verbatim with each `PUT`. Currently always empty; present so a future mode can require signed headers without changing the response shape. |
11+
**mode** | **str** | Upload mode: `single` (upload the whole file with one `PUT` to `url`) or `multipart` (upload each part with one `PUT` to the matching entry in `part_urls`). Modeled as a string so additional modes can be added later without breaking clients. |
12+
**part_size** | **int** | For a `multipart` upload, the size in bytes to split the file into: send bytes `[(i-1) * part_size, i * part_size)` to `part_urls[i - 1]`, with the last part carrying the remainder. Slice by this value — do **not** divide the file evenly by `part_urls.len()`, which can make a non-final part smaller than the 5 MiB minimum that storage requires (the upload then fails at finalize). Absent for `single` uploads. | [optional]
13+
**part_urls** | **List[str]** | For a `multipart` upload, the per-part URLs in ascending part order: `PUT` your file's part *i* (1-based) to `part_urls[i - 1]` and keep each response's `ETag`, then pass the `{part_number, e_tag}` list to finalize. Absent for `single` uploads. | [optional]
14+
**upload_id** | **str** | Identifier for this upload. Pass it to the finalize endpoint and to the managed-table load endpoint once finalized. |
15+
**url** | **str** | The URL to `PUT` the raw file bytes to, for a `single` upload. Short-lived — upload promptly and finalize. Absent for `multipart` uploads (use `part_urls`). | [optional]
16+
17+
## Example
18+
19+
```python
20+
from hotdata.models.upload_session_response import UploadSessionResponse
21+
22+
# TODO update the JSON string below
23+
json = "{}"
24+
# create an instance of UploadSessionResponse from a JSON string
25+
upload_session_response_instance = UploadSessionResponse.from_json(json)
26+
# print the JSON string representation of the object
27+
print(UploadSessionResponse.to_json())
28+
29+
# convert the object into a dict
30+
upload_session_response_dict = upload_session_response_instance.to_dict()
31+
# create an instance of UploadSessionResponse from a dict
32+
upload_session_response_from_dict = UploadSessionResponse.from_dict(upload_session_response_dict)
33+
```
34+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
35+
36+

0 commit comments

Comments
 (0)