diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index ceb7462..14fdfd1 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -8,6 +8,8 @@ docs/ApiErrorDetail.md docs/ApiErrorResponse.md docs/AsyncQueryResponse.md docs/AttachDatabaseCatalogRequest.md +docs/BatchCreateUploadRequest.md +docs/BatchCreateUploadResponse.md docs/BooleanProfileDetail.md docs/CategoricalProfileDetail.md docs/CategoryValueInfo.md @@ -37,6 +39,7 @@ docs/CreateIndexRequest.md docs/CreateSavedQueryRequest.md docs/CreateSecretRequest.md docs/CreateSecretResponse.md +docs/CreateUploadRequest.md docs/CreateWorkspaceRequest.md docs/CreateWorkspaceResponse.md docs/DatabaseAttachmentInfo.md @@ -52,6 +55,9 @@ docs/EmbeddingProviderResponse.md docs/EmbeddingProvidersApi.md docs/Error.md docs/ExecuteSavedQueryRequest.md +docs/FinalizeUploadPart.md +docs/FinalizeUploadRequest.md +docs/FinalizeUploadResponse.md docs/GetConnectionResponse.md docs/GetDatabaseContextResponse.md docs/GetResultResponse.md @@ -120,6 +126,7 @@ docs/UpdateSecretRequest.md docs/UpdateSecretResponse.md docs/UploadInfo.md docs/UploadResponse.md +docs/UploadSessionResponse.md docs/UploadsApi.md docs/UpsertDatabaseContextRequest.md docs/UpsertDatabaseContextResponse.md @@ -159,6 +166,8 @@ hotdata/models/api_error_detail.py hotdata/models/api_error_response.py hotdata/models/async_query_response.py hotdata/models/attach_database_catalog_request.py +hotdata/models/batch_create_upload_request.py +hotdata/models/batch_create_upload_response.py hotdata/models/boolean_profile_detail.py hotdata/models/categorical_profile_detail.py hotdata/models/category_value_info.py @@ -186,6 +195,7 @@ hotdata/models/create_index_request.py hotdata/models/create_saved_query_request.py hotdata/models/create_secret_request.py hotdata/models/create_secret_response.py +hotdata/models/create_upload_request.py hotdata/models/create_workspace_request.py hotdata/models/create_workspace_response.py hotdata/models/database_attachment_info.py @@ -198,6 +208,9 @@ hotdata/models/discovery_status.py hotdata/models/embedding_provider_response.py hotdata/models/error.py hotdata/models/execute_saved_query_request.py +hotdata/models/finalize_upload_part.py +hotdata/models/finalize_upload_request.py +hotdata/models/finalize_upload_response.py hotdata/models/get_connection_response.py hotdata/models/get_database_context_response.py hotdata/models/get_result_response.py @@ -257,6 +270,7 @@ hotdata/models/update_secret_request.py hotdata/models/update_secret_response.py hotdata/models/upload_info.py hotdata/models/upload_response.py +hotdata/models/upload_session_response.py hotdata/models/upsert_database_context_request.py hotdata/models/upsert_database_context_response.py hotdata/models/workspace_detail.py @@ -273,6 +287,8 @@ test/test_api_error_detail.py test/test_api_error_response.py test/test_async_query_response.py test/test_attach_database_catalog_request.py +test/test_batch_create_upload_request.py +test/test_batch_create_upload_response.py test/test_boolean_profile_detail.py test/test_categorical_profile_detail.py test/test_category_value_info.py @@ -302,6 +318,7 @@ test/test_create_index_request.py test/test_create_saved_query_request.py test/test_create_secret_request.py test/test_create_secret_response.py +test/test_create_upload_request.py test/test_create_workspace_request.py test/test_create_workspace_response.py test/test_database_attachment_info.py @@ -317,6 +334,9 @@ test/test_embedding_provider_response.py test/test_embedding_providers_api.py test/test_error.py test/test_execute_saved_query_request.py +test/test_finalize_upload_part.py +test/test_finalize_upload_request.py +test/test_finalize_upload_response.py test/test_get_connection_response.py test/test_get_database_context_response.py test/test_get_result_response.py @@ -385,6 +405,7 @@ test/test_update_secret_request.py test/test_update_secret_response.py test/test_upload_info.py test/test_upload_response.py +test/test_upload_session_response.py test/test_uploads_api.py test/test_upsert_database_context_request.py test/test_upsert_database_context_response.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0098132..fd55d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- feat(uploads): add file upload endpoints - docs: remove stale datasets references, refresh MCP + CLI reference - feat(tables): add csv and json file format support for table loads - Regenerate the client from the updated Hotdata OpenAPI spec diff --git a/docs/BatchCreateUploadRequest.md b/docs/BatchCreateUploadRequest.md new file mode 100644 index 0000000..df12e9a --- /dev/null +++ b/docs/BatchCreateUploadRequest.md @@ -0,0 +1,30 @@ +# BatchCreateUploadRequest + +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. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uploads** | [**List[CreateUploadRequest]**](CreateUploadRequest.md) | | + +## Example + +```python +from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of BatchCreateUploadRequest from a JSON string +batch_create_upload_request_instance = BatchCreateUploadRequest.from_json(json) +# print the JSON string representation of the object +print(BatchCreateUploadRequest.to_json()) + +# convert the object into a dict +batch_create_upload_request_dict = batch_create_upload_request_instance.to_dict() +# create an instance of BatchCreateUploadRequest from a dict +batch_create_upload_request_from_dict = BatchCreateUploadRequest.from_dict(batch_create_upload_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/BatchCreateUploadResponse.md b/docs/BatchCreateUploadResponse.md new file mode 100644 index 0000000..64d3886 --- /dev/null +++ b/docs/BatchCreateUploadResponse.md @@ -0,0 +1,30 @@ +# BatchCreateUploadResponse + +Response body for `POST /v1/uploads/batch`: one created session per requested file, in request order. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uploads** | [**List[UploadSessionResponse]**](UploadSessionResponse.md) | | + +## Example + +```python +from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of BatchCreateUploadResponse from a JSON string +batch_create_upload_response_instance = BatchCreateUploadResponse.from_json(json) +# print the JSON string representation of the object +print(BatchCreateUploadResponse.to_json()) + +# convert the object into a dict +batch_create_upload_response_dict = batch_create_upload_response_instance.to_dict() +# create an instance of BatchCreateUploadResponse from a dict +batch_create_upload_response_from_dict = BatchCreateUploadResponse.from_dict(batch_create_upload_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/CreateUploadRequest.md b/docs/CreateUploadRequest.md new file mode 100644 index 0000000..76955eb --- /dev/null +++ b/docs/CreateUploadRequest.md @@ -0,0 +1,36 @@ +# CreateUploadRequest + +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. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**checksum_algo** | **str** | Integrity checksum algorithm you are volunteering for this file. Currently only `sha256` is accepted. Optional; pair with `checksum_value`. | [optional] +**checksum_value** | **str** | Integrity checksum value, paired with `checksum_algo`. Optional. | [optional] +**content_encoding** | **str** | Content encoding to record for the uploaded file (for example `gzip`). Optional. | [optional] +**content_type** | **str** | Content type to record for the uploaded file (for example the Parquet, CSV, or JSON MIME type). Optional. | [optional] +**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. | +**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] +**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] + +## Example + +```python +from hotdata.models.create_upload_request import CreateUploadRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of CreateUploadRequest from a JSON string +create_upload_request_instance = CreateUploadRequest.from_json(json) +# print the JSON string representation of the object +print(CreateUploadRequest.to_json()) + +# convert the object into a dict +create_upload_request_dict = create_upload_request_instance.to_dict() +# create an instance of CreateUploadRequest from a dict +create_upload_request_from_dict = CreateUploadRequest.from_dict(create_upload_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/FinalizeUploadPart.md b/docs/FinalizeUploadPart.md new file mode 100644 index 0000000..2ad4526 --- /dev/null +++ b/docs/FinalizeUploadPart.md @@ -0,0 +1,31 @@ +# FinalizeUploadPart + +One part of a multi-part upload, supplied at finalize. Reserved for a future multi-part mode; single-`PUT` uploads have no parts. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**e_tag** | **str** | The entity tag (ETag) storage returned for the uploaded part. | +**part_number** | **int** | 1-based part number, as reported by storage for the part. | + +## Example + +```python +from hotdata.models.finalize_upload_part import FinalizeUploadPart + +# TODO update the JSON string below +json = "{}" +# create an instance of FinalizeUploadPart from a JSON string +finalize_upload_part_instance = FinalizeUploadPart.from_json(json) +# print the JSON string representation of the object +print(FinalizeUploadPart.to_json()) + +# convert the object into a dict +finalize_upload_part_dict = finalize_upload_part_instance.to_dict() +# create an instance of FinalizeUploadPart from a dict +finalize_upload_part_from_dict = FinalizeUploadPart.from_dict(finalize_upload_part_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/FinalizeUploadRequest.md b/docs/FinalizeUploadRequest.md new file mode 100644 index 0000000..1d258a4 --- /dev/null +++ b/docs/FinalizeUploadRequest.md @@ -0,0 +1,30 @@ +# FinalizeUploadRequest + +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. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**parts** | [**List[FinalizeUploadPart]**](FinalizeUploadPart.md) | Parts to assemble, for a multi-part upload. Omit for single-`PUT` uploads (the common case). | [optional] + +## Example + +```python +from hotdata.models.finalize_upload_request import FinalizeUploadRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of FinalizeUploadRequest from a JSON string +finalize_upload_request_instance = FinalizeUploadRequest.from_json(json) +# print the JSON string representation of the object +print(FinalizeUploadRequest.to_json()) + +# convert the object into a dict +finalize_upload_request_dict = finalize_upload_request_instance.to_dict() +# create an instance of FinalizeUploadRequest from a dict +finalize_upload_request_from_dict = FinalizeUploadRequest.from_dict(finalize_upload_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/FinalizeUploadResponse.md b/docs/FinalizeUploadResponse.md new file mode 100644 index 0000000..0e5d421 --- /dev/null +++ b/docs/FinalizeUploadResponse.md @@ -0,0 +1,34 @@ +# FinalizeUploadResponse + +Response body for `POST /v1/uploads/{upload_id}/finalize`: the finalized upload, ready to be loaded into a managed table. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**content_type** | **str** | | [optional] +**created_at** | **datetime** | | +**size_bytes** | **int** | The validated size of the uploaded file in bytes. | +**status** | **str** | | +**upload_id** | **str** | | + +## Example + +```python +from hotdata.models.finalize_upload_response import FinalizeUploadResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of FinalizeUploadResponse from a JSON string +finalize_upload_response_instance = FinalizeUploadResponse.from_json(json) +# print the JSON string representation of the object +print(FinalizeUploadResponse.to_json()) + +# convert the object into a dict +finalize_upload_response_dict = finalize_upload_response_instance.to_dict() +# create an instance of FinalizeUploadResponse from a dict +finalize_upload_response_from_dict = FinalizeUploadResponse.from_dict(finalize_upload_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/UploadSessionResponse.md b/docs/UploadSessionResponse.md new file mode 100644 index 0000000..f90cccc --- /dev/null +++ b/docs/UploadSessionResponse.md @@ -0,0 +1,36 @@ +# UploadSessionResponse + +A created upload session: everything needed to upload the bytes directly to storage and later finalize the upload. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**finalize_token** | **str** | One-time token that authorizes finalizing this upload. Returned exactly once at create time — store it; it cannot be retrieved again. | +**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. | +**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. | +**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] +**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] +**upload_id** | **str** | Identifier for this upload. Pass it to the finalize endpoint and to the managed-table load endpoint once finalized. | +**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] + +## Example + +```python +from hotdata.models.upload_session_response import UploadSessionResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of UploadSessionResponse from a JSON string +upload_session_response_instance = UploadSessionResponse.from_json(json) +# print the JSON string representation of the object +print(UploadSessionResponse.to_json()) + +# convert the object into a dict +upload_session_response_dict = upload_session_response_instance.to_dict() +# create an instance of UploadSessionResponse from a dict +upload_session_response_from_dict = UploadSessionResponse.from_dict(upload_session_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/UploadsApi.md b/docs/UploadsApi.md index e0c4e90..5eeed19 100644 --- a/docs/UploadsApi.md +++ b/docs/UploadsApi.md @@ -4,10 +4,287 @@ All URIs are relative to *https://api.hotdata.dev* Method | HTTP request | Description ------------- | ------------- | ------------- +[**create_upload_session_handler**](UploadsApi.md#create_upload_session_handler) | **POST** /v1/uploads | Create upload session +[**create_upload_sessions_batch_handler**](UploadsApi.md#create_upload_sessions_batch_handler) | **POST** /v1/uploads/batch | Create upload sessions in bulk +[**finalize_upload_handler**](UploadsApi.md#finalize_upload_handler) | **POST** /v1/uploads/{upload_id}/finalize | Finalize upload [**list_uploads**](UploadsApi.md#list_uploads) | **GET** /v1/files | List uploads [**upload_file**](UploadsApi.md#upload_file) | **POST** /v1/files | Upload file +# **create_upload_session_handler** +> UploadSessionResponse create_upload_session_handler(create_upload_request) + +Create upload session + +Create an upload session for a file you will send directly to storage. Based on the declared size, the response is one of two shapes. For a small file (`mode: single`) it contains a short-lived `url` to `PUT` the whole file to. For a large file (`mode: multipart`) it contains `part_urls` and `part_size`: split the file into `part_size`-byte chunks (the last is the remainder) and `PUT` chunk *i* (1-based) to `part_urls[i - 1]`, keeping each response's `ETag`. Slice by `part_size`, not by an even division across `part_urls.len()` (which can make a non-final part too small). In both cases the response also includes a one-time `finalize_token`. After uploading, call the finalize endpoint with the token (and, for multipart, the `{part_number, e_tag}` list) to make the upload usable as managed-table contents. The returned upload ID can then be passed to the managed-table load endpoint. + +You may hint a preferred part size with `part_size`; the service clamps it to the allowed range and ignores it for single-`PUT` uploads. + +If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send the file to the `POST /v1/files` endpoint instead. + +### Example + +* Api Key Authentication (WorkspaceId): +* Bearer Authentication (BearerAuth): + +```python +import hotdata +from hotdata.models.create_upload_request import CreateUploadRequest +from hotdata.models.upload_session_response import UploadSessionResponse +from hotdata.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.hotdata.dev +# See configuration.py for a list of all supported configuration parameters. +configuration = hotdata.Configuration( + host = "https://api.hotdata.dev" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure API key authorization: WorkspaceId +configuration.api_key['WorkspaceId'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['WorkspaceId'] = 'Bearer' + +# Configure Bearer authorization: BearerAuth +configuration = hotdata.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with hotdata.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = hotdata.UploadsApi(api_client) + create_upload_request = hotdata.CreateUploadRequest() # CreateUploadRequest | + + try: + # Create upload session + api_response = api_instance.create_upload_session_handler(create_upload_request) + print("The response of UploadsApi->create_upload_session_handler:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UploadsApi->create_upload_session_handler: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **create_upload_request** | [**CreateUploadRequest**](CreateUploadRequest.md)| | + +### Return type + +[**UploadSessionResponse**](UploadSessionResponse.md) + +### Authorization + +[WorkspaceId](../README.md#WorkspaceId), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**201** | Upload session created | - | +**400** | Invalid request (e.g. file too large, unsupported checksum algorithm) | - | +**501** | Storage backend cannot issue upload URLs; use POST /v1/files instead | - | + +[[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) + +# **create_upload_sessions_batch_handler** +> BatchCreateUploadResponse create_upload_sessions_batch_handler(batch_create_upload_request) + +Create upload sessions in bulk + +Create upload sessions for several files in one request. Each file is planned independently and the response returns one session per requested file, in the same order. Each session is finalized separately via the finalize endpoint, so you can upload and finalize files at your own pace. + +If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send each file to the `POST /v1/files` endpoint instead. + +### Example + +* Api Key Authentication (WorkspaceId): +* Bearer Authentication (BearerAuth): + +```python +import hotdata +from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest +from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse +from hotdata.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.hotdata.dev +# See configuration.py for a list of all supported configuration parameters. +configuration = hotdata.Configuration( + host = "https://api.hotdata.dev" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure API key authorization: WorkspaceId +configuration.api_key['WorkspaceId'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['WorkspaceId'] = 'Bearer' + +# Configure Bearer authorization: BearerAuth +configuration = hotdata.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with hotdata.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = hotdata.UploadsApi(api_client) + batch_create_upload_request = hotdata.BatchCreateUploadRequest() # BatchCreateUploadRequest | + + try: + # Create upload sessions in bulk + api_response = api_instance.create_upload_sessions_batch_handler(batch_create_upload_request) + print("The response of UploadsApi->create_upload_sessions_batch_handler:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UploadsApi->create_upload_sessions_batch_handler: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **batch_create_upload_request** | [**BatchCreateUploadRequest**](BatchCreateUploadRequest.md)| | + +### Return type + +[**BatchCreateUploadResponse**](BatchCreateUploadResponse.md) + +### Authorization + +[WorkspaceId](../README.md#WorkspaceId), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**201** | Upload sessions created | - | +**400** | Invalid request (e.g. a file too large, unsupported checksum algorithm) | - | +**501** | Storage backend cannot issue upload URLs; use POST /v1/files instead | - | + +[[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) + +# **finalize_upload_handler** +> FinalizeUploadResponse finalize_upload_handler(upload_id, x_upload_finalize_token, finalize_upload_request=finalize_upload_request) + +Finalize upload + +Confirm that a file has been uploaded to storage and make it usable as managed-table contents. Supply the `finalize_token` returned when the session was created, in the `X-Upload-Finalize-Token` header. The uploaded file's size is validated against the size declared at create time; a mismatch is rejected. Finalize is exactly-once: a second finalize of the same upload is rejected. + +### Example + +* Api Key Authentication (WorkspaceId): +* Bearer Authentication (BearerAuth): + +```python +import hotdata +from hotdata.models.finalize_upload_request import FinalizeUploadRequest +from hotdata.models.finalize_upload_response import FinalizeUploadResponse +from hotdata.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.hotdata.dev +# See configuration.py for a list of all supported configuration parameters. +configuration = hotdata.Configuration( + host = "https://api.hotdata.dev" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure API key authorization: WorkspaceId +configuration.api_key['WorkspaceId'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['WorkspaceId'] = 'Bearer' + +# Configure Bearer authorization: BearerAuth +configuration = hotdata.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with hotdata.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = hotdata.UploadsApi(api_client) + upload_id = 'upload_id_example' # str | Upload session ID returned at create time + x_upload_finalize_token = 'x_upload_finalize_token_example' # str | One-time finalize token returned when the session was created + finalize_upload_request = hotdata.FinalizeUploadRequest() # FinalizeUploadRequest | Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body. (optional) + + try: + # Finalize upload + api_response = api_instance.finalize_upload_handler(upload_id, x_upload_finalize_token, finalize_upload_request=finalize_upload_request) + print("The response of UploadsApi->finalize_upload_handler:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UploadsApi->finalize_upload_handler: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **upload_id** | **str**| Upload session ID returned at create time | + **x_upload_finalize_token** | **str**| One-time finalize token returned when the session was created | + **finalize_upload_request** | [**FinalizeUploadRequest**](FinalizeUploadRequest.md)| Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body. | [optional] + +### Return type + +[**FinalizeUploadResponse**](FinalizeUploadResponse.md) + +### Authorization + +[WorkspaceId](../README.md#WorkspaceId), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Upload finalized | - | +**400** | Invalid finalize token, uploaded size mismatch, missing object, or upload not finalizable | - | +**404** | Upload session not found | - | + +[[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) + # **list_uploads** > ListUploadsResponse list_uploads(status=status) diff --git a/hotdata/__init__.py b/hotdata/__init__.py index d83f959..ab65616 100644 --- a/hotdata/__init__.py +++ b/hotdata/__init__.py @@ -57,6 +57,8 @@ "ApiErrorResponse", "AsyncQueryResponse", "AttachDatabaseCatalogRequest", + "BatchCreateUploadRequest", + "BatchCreateUploadResponse", "BooleanProfileDetail", "CategoricalProfileDetail", "CategoryValueInfo", @@ -84,6 +86,7 @@ "CreateSavedQueryRequest", "CreateSecretRequest", "CreateSecretResponse", + "CreateUploadRequest", "CreateWorkspaceRequest", "CreateWorkspaceResponse", "DatabaseAttachmentInfo", @@ -96,6 +99,9 @@ "EmbeddingProviderResponse", "Error", "ExecuteSavedQueryRequest", + "FinalizeUploadPart", + "FinalizeUploadRequest", + "FinalizeUploadResponse", "GetConnectionResponse", "GetDatabaseContextResponse", "GetResultResponse", @@ -155,6 +161,7 @@ "UpdateSecretResponse", "UploadInfo", "UploadResponse", + "UploadSessionResponse", "UpsertDatabaseContextRequest", "UpsertDatabaseContextResponse", "WorkspaceDetail", @@ -200,6 +207,8 @@ from hotdata.models.api_error_response import ApiErrorResponse as ApiErrorResponse from hotdata.models.async_query_response import AsyncQueryResponse as AsyncQueryResponse from hotdata.models.attach_database_catalog_request import AttachDatabaseCatalogRequest as AttachDatabaseCatalogRequest +from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest as BatchCreateUploadRequest +from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse as BatchCreateUploadResponse from hotdata.models.boolean_profile_detail import BooleanProfileDetail as BooleanProfileDetail from hotdata.models.categorical_profile_detail import CategoricalProfileDetail as CategoricalProfileDetail from hotdata.models.category_value_info import CategoryValueInfo as CategoryValueInfo @@ -227,6 +236,7 @@ from hotdata.models.create_saved_query_request import CreateSavedQueryRequest as CreateSavedQueryRequest from hotdata.models.create_secret_request import CreateSecretRequest as CreateSecretRequest from hotdata.models.create_secret_response import CreateSecretResponse as CreateSecretResponse +from hotdata.models.create_upload_request import CreateUploadRequest as CreateUploadRequest from hotdata.models.create_workspace_request import CreateWorkspaceRequest as CreateWorkspaceRequest from hotdata.models.create_workspace_response import CreateWorkspaceResponse as CreateWorkspaceResponse from hotdata.models.database_attachment_info import DatabaseAttachmentInfo as DatabaseAttachmentInfo @@ -239,6 +249,9 @@ from hotdata.models.embedding_provider_response import EmbeddingProviderResponse as EmbeddingProviderResponse from hotdata.models.error import Error as Error from hotdata.models.execute_saved_query_request import ExecuteSavedQueryRequest as ExecuteSavedQueryRequest +from hotdata.models.finalize_upload_part import FinalizeUploadPart as FinalizeUploadPart +from hotdata.models.finalize_upload_request import FinalizeUploadRequest as FinalizeUploadRequest +from hotdata.models.finalize_upload_response import FinalizeUploadResponse as FinalizeUploadResponse from hotdata.models.get_connection_response import GetConnectionResponse as GetConnectionResponse from hotdata.models.get_database_context_response import GetDatabaseContextResponse as GetDatabaseContextResponse from hotdata.models.get_result_response import GetResultResponse as GetResultResponse @@ -298,6 +311,7 @@ from hotdata.models.update_secret_response import UpdateSecretResponse as UpdateSecretResponse from hotdata.models.upload_info import UploadInfo as UploadInfo from hotdata.models.upload_response import UploadResponse as UploadResponse +from hotdata.models.upload_session_response import UploadSessionResponse as UploadSessionResponse from hotdata.models.upsert_database_context_request import UpsertDatabaseContextRequest as UpsertDatabaseContextRequest from hotdata.models.upsert_database_context_response import UpsertDatabaseContextResponse as UpsertDatabaseContextResponse from hotdata.models.workspace_detail import WorkspaceDetail as WorkspaceDetail diff --git a/hotdata/api/uploads_api.py b/hotdata/api/uploads_api.py index 59ce4ea..c05fffd 100644 --- a/hotdata/api/uploads_api.py +++ b/hotdata/api/uploads_api.py @@ -19,8 +19,14 @@ from pydantic import Field, StrictBytes, StrictStr from typing import Optional, Tuple, Union from typing_extensions import Annotated +from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest +from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse +from hotdata.models.create_upload_request import CreateUploadRequest +from hotdata.models.finalize_upload_request import FinalizeUploadRequest +from hotdata.models.finalize_upload_response import FinalizeUploadResponse from hotdata.models.list_uploads_response import ListUploadsResponse from hotdata.models.upload_response import UploadResponse +from hotdata.models.upload_session_response import UploadSessionResponse from hotdata.api_client import ApiClient, RequestSerialized from hotdata.api_response import ApiResponse @@ -40,6 +46,879 @@ def __init__(self, api_client=None) -> None: self.api_client = api_client + @validate_call + def create_upload_session_handler( + self, + create_upload_request: CreateUploadRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> UploadSessionResponse: + """Create upload session + + Create an upload session for a file you will send directly to storage. Based on the declared size, the response is one of two shapes. For a small file (`mode: single`) it contains a short-lived `url` to `PUT` the whole file to. For a large file (`mode: multipart`) it contains `part_urls` and `part_size`: split the file into `part_size`-byte chunks (the last is the remainder) and `PUT` chunk *i* (1-based) to `part_urls[i - 1]`, keeping each response's `ETag`. Slice by `part_size`, not by an even division across `part_urls.len()` (which can make a non-final part too small). In both cases the response also includes a one-time `finalize_token`. After uploading, call the finalize endpoint with the token (and, for multipart, the `{part_number, e_tag}` list) to make the upload usable as managed-table contents. The returned upload ID can then be passed to the managed-table load endpoint. You may hint a preferred part size with `part_size`; the service clamps it to the allowed range and ignores it for single-`PUT` uploads. If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send the file to the `POST /v1/files` endpoint instead. + + :param create_upload_request: (required) + :type create_upload_request: CreateUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_upload_session_handler_serialize( + create_upload_request=create_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "UploadSessionResponse", + '400': "ApiErrorResponse", + '501': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_upload_session_handler_with_http_info( + self, + create_upload_request: CreateUploadRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[UploadSessionResponse]: + """Create upload session + + Create an upload session for a file you will send directly to storage. Based on the declared size, the response is one of two shapes. For a small file (`mode: single`) it contains a short-lived `url` to `PUT` the whole file to. For a large file (`mode: multipart`) it contains `part_urls` and `part_size`: split the file into `part_size`-byte chunks (the last is the remainder) and `PUT` chunk *i* (1-based) to `part_urls[i - 1]`, keeping each response's `ETag`. Slice by `part_size`, not by an even division across `part_urls.len()` (which can make a non-final part too small). In both cases the response also includes a one-time `finalize_token`. After uploading, call the finalize endpoint with the token (and, for multipart, the `{part_number, e_tag}` list) to make the upload usable as managed-table contents. The returned upload ID can then be passed to the managed-table load endpoint. You may hint a preferred part size with `part_size`; the service clamps it to the allowed range and ignores it for single-`PUT` uploads. If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send the file to the `POST /v1/files` endpoint instead. + + :param create_upload_request: (required) + :type create_upload_request: CreateUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_upload_session_handler_serialize( + create_upload_request=create_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "UploadSessionResponse", + '400': "ApiErrorResponse", + '501': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_upload_session_handler_without_preload_content( + self, + create_upload_request: CreateUploadRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create upload session + + Create an upload session for a file you will send directly to storage. Based on the declared size, the response is one of two shapes. For a small file (`mode: single`) it contains a short-lived `url` to `PUT` the whole file to. For a large file (`mode: multipart`) it contains `part_urls` and `part_size`: split the file into `part_size`-byte chunks (the last is the remainder) and `PUT` chunk *i* (1-based) to `part_urls[i - 1]`, keeping each response's `ETag`. Slice by `part_size`, not by an even division across `part_urls.len()` (which can make a non-final part too small). In both cases the response also includes a one-time `finalize_token`. After uploading, call the finalize endpoint with the token (and, for multipart, the `{part_number, e_tag}` list) to make the upload usable as managed-table contents. The returned upload ID can then be passed to the managed-table load endpoint. You may hint a preferred part size with `part_size`; the service clamps it to the allowed range and ignores it for single-`PUT` uploads. If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send the file to the `POST /v1/files` endpoint instead. + + :param create_upload_request: (required) + :type create_upload_request: CreateUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_upload_session_handler_serialize( + create_upload_request=create_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "UploadSessionResponse", + '400': "ApiErrorResponse", + '501': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_upload_session_handler_serialize( + self, + create_upload_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_upload_request is not None: + _body_params = create_upload_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'WorkspaceId', + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/uploads', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def create_upload_sessions_batch_handler( + self, + batch_create_upload_request: BatchCreateUploadRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BatchCreateUploadResponse: + """Create upload sessions in bulk + + Create upload sessions for several files in one request. Each file is planned independently and the response returns one session per requested file, in the same order. Each session is finalized separately via the finalize endpoint, so you can upload and finalize files at your own pace. If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send each file to the `POST /v1/files` endpoint instead. + + :param batch_create_upload_request: (required) + :type batch_create_upload_request: BatchCreateUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_upload_sessions_batch_handler_serialize( + batch_create_upload_request=batch_create_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "BatchCreateUploadResponse", + '400': "ApiErrorResponse", + '501': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_upload_sessions_batch_handler_with_http_info( + self, + batch_create_upload_request: BatchCreateUploadRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BatchCreateUploadResponse]: + """Create upload sessions in bulk + + Create upload sessions for several files in one request. Each file is planned independently and the response returns one session per requested file, in the same order. Each session is finalized separately via the finalize endpoint, so you can upload and finalize files at your own pace. If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send each file to the `POST /v1/files` endpoint instead. + + :param batch_create_upload_request: (required) + :type batch_create_upload_request: BatchCreateUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_upload_sessions_batch_handler_serialize( + batch_create_upload_request=batch_create_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "BatchCreateUploadResponse", + '400': "ApiErrorResponse", + '501': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_upload_sessions_batch_handler_without_preload_content( + self, + batch_create_upload_request: BatchCreateUploadRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create upload sessions in bulk + + Create upload sessions for several files in one request. Each file is planned independently and the response returns one session per requested file, in the same order. Each session is finalized separately via the finalize endpoint, so you can upload and finalize files at your own pace. If the response status is `501` with error code `PRESIGN_UNSUPPORTED`, the configured storage backend cannot issue upload URLs; send each file to the `POST /v1/files` endpoint instead. + + :param batch_create_upload_request: (required) + :type batch_create_upload_request: BatchCreateUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_upload_sessions_batch_handler_serialize( + batch_create_upload_request=batch_create_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "BatchCreateUploadResponse", + '400': "ApiErrorResponse", + '501': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_upload_sessions_batch_handler_serialize( + self, + batch_create_upload_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if batch_create_upload_request is not None: + _body_params = batch_create_upload_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'WorkspaceId', + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/uploads/batch', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def finalize_upload_handler( + self, + upload_id: Annotated[StrictStr, Field(description="Upload session ID returned at create time")], + x_upload_finalize_token: Annotated[StrictStr, Field(description="One-time finalize token returned when the session was created")], + finalize_upload_request: Annotated[Optional[FinalizeUploadRequest], Field(description="Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> FinalizeUploadResponse: + """Finalize upload + + Confirm that a file has been uploaded to storage and make it usable as managed-table contents. Supply the `finalize_token` returned when the session was created, in the `X-Upload-Finalize-Token` header. The uploaded file's size is validated against the size declared at create time; a mismatch is rejected. Finalize is exactly-once: a second finalize of the same upload is rejected. + + :param upload_id: Upload session ID returned at create time (required) + :type upload_id: str + :param x_upload_finalize_token: One-time finalize token returned when the session was created (required) + :type x_upload_finalize_token: str + :param finalize_upload_request: Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body. + :type finalize_upload_request: FinalizeUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._finalize_upload_handler_serialize( + upload_id=upload_id, + x_upload_finalize_token=x_upload_finalize_token, + finalize_upload_request=finalize_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "FinalizeUploadResponse", + '400': "ApiErrorResponse", + '404': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def finalize_upload_handler_with_http_info( + self, + upload_id: Annotated[StrictStr, Field(description="Upload session ID returned at create time")], + x_upload_finalize_token: Annotated[StrictStr, Field(description="One-time finalize token returned when the session was created")], + finalize_upload_request: Annotated[Optional[FinalizeUploadRequest], Field(description="Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[FinalizeUploadResponse]: + """Finalize upload + + Confirm that a file has been uploaded to storage and make it usable as managed-table contents. Supply the `finalize_token` returned when the session was created, in the `X-Upload-Finalize-Token` header. The uploaded file's size is validated against the size declared at create time; a mismatch is rejected. Finalize is exactly-once: a second finalize of the same upload is rejected. + + :param upload_id: Upload session ID returned at create time (required) + :type upload_id: str + :param x_upload_finalize_token: One-time finalize token returned when the session was created (required) + :type x_upload_finalize_token: str + :param finalize_upload_request: Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body. + :type finalize_upload_request: FinalizeUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._finalize_upload_handler_serialize( + upload_id=upload_id, + x_upload_finalize_token=x_upload_finalize_token, + finalize_upload_request=finalize_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "FinalizeUploadResponse", + '400': "ApiErrorResponse", + '404': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def finalize_upload_handler_without_preload_content( + self, + upload_id: Annotated[StrictStr, Field(description="Upload session ID returned at create time")], + x_upload_finalize_token: Annotated[StrictStr, Field(description="One-time finalize token returned when the session was created")], + finalize_upload_request: Annotated[Optional[FinalizeUploadRequest], Field(description="Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Finalize upload + + Confirm that a file has been uploaded to storage and make it usable as managed-table contents. Supply the `finalize_token` returned when the session was created, in the `X-Upload-Finalize-Token` header. The uploaded file's size is validated against the size declared at create time; a mismatch is rejected. Finalize is exactly-once: a second finalize of the same upload is rejected. + + :param upload_id: Upload session ID returned at create time (required) + :type upload_id: str + :param x_upload_finalize_token: One-time finalize token returned when the session was created (required) + :type x_upload_finalize_token: str + :param finalize_upload_request: Optional; send `parts` only for a multi-part upload. Single-`PUT` uploads finalize with no body. + :type finalize_upload_request: FinalizeUploadRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._finalize_upload_handler_serialize( + upload_id=upload_id, + x_upload_finalize_token=x_upload_finalize_token, + finalize_upload_request=finalize_upload_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "FinalizeUploadResponse", + '400': "ApiErrorResponse", + '404': "ApiErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _finalize_upload_handler_serialize( + self, + upload_id, + x_upload_finalize_token, + finalize_upload_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if upload_id is not None: + _path_params['upload_id'] = upload_id + # process the query parameters + # process the header parameters + if x_upload_finalize_token is not None: + _header_params['X-Upload-Finalize-Token'] = x_upload_finalize_token + # process the form parameters + # process the body parameter + if finalize_upload_request is not None: + _body_params = finalize_upload_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'WorkspaceId', + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/uploads/{upload_id}/finalize', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def list_uploads( self, diff --git a/hotdata/models/__init__.py b/hotdata/models/__init__.py index 4bcc409..b967cfa 100644 --- a/hotdata/models/__init__.py +++ b/hotdata/models/__init__.py @@ -21,6 +21,8 @@ from hotdata.models.api_error_response import ApiErrorResponse from hotdata.models.async_query_response import AsyncQueryResponse from hotdata.models.attach_database_catalog_request import AttachDatabaseCatalogRequest +from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest +from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse from hotdata.models.boolean_profile_detail import BooleanProfileDetail from hotdata.models.categorical_profile_detail import CategoricalProfileDetail from hotdata.models.category_value_info import CategoryValueInfo @@ -48,6 +50,7 @@ from hotdata.models.create_saved_query_request import CreateSavedQueryRequest from hotdata.models.create_secret_request import CreateSecretRequest from hotdata.models.create_secret_response import CreateSecretResponse +from hotdata.models.create_upload_request import CreateUploadRequest from hotdata.models.create_workspace_request import CreateWorkspaceRequest from hotdata.models.create_workspace_response import CreateWorkspaceResponse from hotdata.models.database_attachment_info import DatabaseAttachmentInfo @@ -60,6 +63,9 @@ from hotdata.models.embedding_provider_response import EmbeddingProviderResponse from hotdata.models.error import Error from hotdata.models.execute_saved_query_request import ExecuteSavedQueryRequest +from hotdata.models.finalize_upload_part import FinalizeUploadPart +from hotdata.models.finalize_upload_request import FinalizeUploadRequest +from hotdata.models.finalize_upload_response import FinalizeUploadResponse from hotdata.models.get_connection_response import GetConnectionResponse from hotdata.models.get_database_context_response import GetDatabaseContextResponse from hotdata.models.get_result_response import GetResultResponse @@ -119,6 +125,7 @@ from hotdata.models.update_secret_response import UpdateSecretResponse from hotdata.models.upload_info import UploadInfo from hotdata.models.upload_response import UploadResponse +from hotdata.models.upload_session_response import UploadSessionResponse from hotdata.models.upsert_database_context_request import UpsertDatabaseContextRequest from hotdata.models.upsert_database_context_response import UpsertDatabaseContextResponse from hotdata.models.workspace_detail import WorkspaceDetail diff --git a/hotdata/models/batch_create_upload_request.py b/hotdata/models/batch_create_upload_request.py new file mode 100644 index 0000000..ed87f79 --- /dev/null +++ b/hotdata/models/batch_create_upload_request.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List +from hotdata.models.create_upload_request import CreateUploadRequest +from typing import Optional, Set +from typing_extensions import Self + +class BatchCreateUploadRequest(BaseModel): + """ + 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. + """ # noqa: E501 + uploads: List[CreateUploadRequest] + __properties: ClassVar[List[str]] = ["uploads"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BatchCreateUploadRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in uploads (list) + _items = [] + if self.uploads: + for _item_uploads in self.uploads: + if _item_uploads: + _items.append(_item_uploads.to_dict()) + _dict['uploads'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BatchCreateUploadRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "uploads": [CreateUploadRequest.from_dict(_item) for _item in obj["uploads"]] if obj.get("uploads") is not None else None + }) + return _obj + + diff --git a/hotdata/models/batch_create_upload_response.py b/hotdata/models/batch_create_upload_response.py new file mode 100644 index 0000000..6b5f0d7 --- /dev/null +++ b/hotdata/models/batch_create_upload_response.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List +from hotdata.models.upload_session_response import UploadSessionResponse +from typing import Optional, Set +from typing_extensions import Self + +class BatchCreateUploadResponse(BaseModel): + """ + Response body for `POST /v1/uploads/batch`: one created session per requested file, in request order. + """ # noqa: E501 + uploads: List[UploadSessionResponse] + __properties: ClassVar[List[str]] = ["uploads"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BatchCreateUploadResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in uploads (list) + _items = [] + if self.uploads: + for _item_uploads in self.uploads: + if _item_uploads: + _items.append(_item_uploads.to_dict()) + _dict['uploads'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BatchCreateUploadResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "uploads": [UploadSessionResponse.from_dict(_item) for _item in obj["uploads"]] if obj.get("uploads") is not None else None + }) + return _obj + + diff --git a/hotdata/models/create_upload_request.py b/hotdata/models/create_upload_request.py new file mode 100644 index 0000000..d05839f --- /dev/null +++ b/hotdata/models/create_upload_request.py @@ -0,0 +1,131 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class CreateUploadRequest(BaseModel): + """ + 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. + """ # noqa: E501 + checksum_algo: Optional[StrictStr] = Field(default=None, description="Integrity checksum algorithm you are volunteering for this file. Currently only `sha256` is accepted. Optional; pair with `checksum_value`.") + checksum_value: Optional[StrictStr] = Field(default=None, description="Integrity checksum value, paired with `checksum_algo`. Optional.") + content_encoding: Optional[StrictStr] = Field(default=None, description="Content encoding to record for the uploaded file (for example `gzip`). Optional.") + content_type: Optional[StrictStr] = Field(default=None, description="Content type to record for the uploaded file (for example the Parquet, CSV, or JSON MIME type). Optional.") + declared_size_bytes: Annotated[int, Field(strict=True, ge=0)] = Field(description="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.") + filename: Optional[StrictStr] = Field(default=None, description="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.") + part_size: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=None, description="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.") + __properties: ClassVar[List[str]] = ["checksum_algo", "checksum_value", "content_encoding", "content_type", "declared_size_bytes", "filename", "part_size"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateUploadRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if checksum_algo (nullable) is None + # and model_fields_set contains the field + if self.checksum_algo is None and "checksum_algo" in self.model_fields_set: + _dict['checksum_algo'] = None + + # set to None if checksum_value (nullable) is None + # and model_fields_set contains the field + if self.checksum_value is None and "checksum_value" in self.model_fields_set: + _dict['checksum_value'] = None + + # set to None if content_encoding (nullable) is None + # and model_fields_set contains the field + if self.content_encoding is None and "content_encoding" in self.model_fields_set: + _dict['content_encoding'] = None + + # set to None if content_type (nullable) is None + # and model_fields_set contains the field + if self.content_type is None and "content_type" in self.model_fields_set: + _dict['content_type'] = None + + # set to None if filename (nullable) is None + # and model_fields_set contains the field + if self.filename is None and "filename" in self.model_fields_set: + _dict['filename'] = None + + # set to None if part_size (nullable) is None + # and model_fields_set contains the field + if self.part_size is None and "part_size" in self.model_fields_set: + _dict['part_size'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateUploadRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "checksum_algo": obj.get("checksum_algo"), + "checksum_value": obj.get("checksum_value"), + "content_encoding": obj.get("content_encoding"), + "content_type": obj.get("content_type"), + "declared_size_bytes": obj.get("declared_size_bytes"), + "filename": obj.get("filename"), + "part_size": obj.get("part_size") + }) + return _obj + + diff --git a/hotdata/models/finalize_upload_part.py b/hotdata/models/finalize_upload_part.py new file mode 100644 index 0000000..18901c6 --- /dev/null +++ b/hotdata/models/finalize_upload_part.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class FinalizeUploadPart(BaseModel): + """ + One part of a multi-part upload, supplied at finalize. Reserved for a future multi-part mode; single-`PUT` uploads have no parts. + """ # noqa: E501 + e_tag: StrictStr = Field(description="The entity tag (ETag) storage returned for the uploaded part.") + part_number: StrictInt = Field(description="1-based part number, as reported by storage for the part.") + __properties: ClassVar[List[str]] = ["e_tag", "part_number"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of FinalizeUploadPart from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of FinalizeUploadPart from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "e_tag": obj.get("e_tag"), + "part_number": obj.get("part_number") + }) + return _obj + + diff --git a/hotdata/models/finalize_upload_request.py b/hotdata/models/finalize_upload_request.py new file mode 100644 index 0000000..d8e6ef4 --- /dev/null +++ b/hotdata/models/finalize_upload_request.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List, Optional +from hotdata.models.finalize_upload_part import FinalizeUploadPart +from typing import Optional, Set +from typing_extensions import Self + +class FinalizeUploadRequest(BaseModel): + """ + 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. + """ # noqa: E501 + parts: Optional[List[FinalizeUploadPart]] = Field(default=None, description="Parts to assemble, for a multi-part upload. Omit for single-`PUT` uploads (the common case).") + __properties: ClassVar[List[str]] = ["parts"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of FinalizeUploadRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in parts (list) + _items = [] + if self.parts: + for _item_parts in self.parts: + if _item_parts: + _items.append(_item_parts.to_dict()) + _dict['parts'] = _items + # set to None if parts (nullable) is None + # and model_fields_set contains the field + if self.parts is None and "parts" in self.model_fields_set: + _dict['parts'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of FinalizeUploadRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "parts": [FinalizeUploadPart.from_dict(_item) for _item in obj["parts"]] if obj.get("parts") is not None else None + }) + return _obj + + diff --git a/hotdata/models/finalize_upload_response.py b/hotdata/models/finalize_upload_response.py new file mode 100644 index 0000000..1a72f0d --- /dev/null +++ b/hotdata/models/finalize_upload_response.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class FinalizeUploadResponse(BaseModel): + """ + Response body for `POST /v1/uploads/{upload_id}/finalize`: the finalized upload, ready to be loaded into a managed table. + """ # noqa: E501 + content_type: Optional[StrictStr] = None + created_at: datetime + size_bytes: StrictInt = Field(description="The validated size of the uploaded file in bytes.") + status: StrictStr + upload_id: StrictStr + __properties: ClassVar[List[str]] = ["content_type", "created_at", "size_bytes", "status", "upload_id"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of FinalizeUploadResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if content_type (nullable) is None + # and model_fields_set contains the field + if self.content_type is None and "content_type" in self.model_fields_set: + _dict['content_type'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of FinalizeUploadResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content_type": obj.get("content_type"), + "created_at": obj.get("created_at"), + "size_bytes": obj.get("size_bytes"), + "status": obj.get("status"), + "upload_id": obj.get("upload_id") + }) + return _obj + + diff --git a/hotdata/models/upload_session_response.py b/hotdata/models/upload_session_response.py new file mode 100644 index 0000000..59bfab3 --- /dev/null +++ b/hotdata/models/upload_session_response.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class UploadSessionResponse(BaseModel): + """ + A created upload session: everything needed to upload the bytes directly to storage and later finalize the upload. + """ # noqa: E501 + finalize_token: StrictStr = Field(description="One-time token that authorizes finalizing this upload. Returned exactly once at create time — store it; it cannot be retrieved again.") + headers: Dict[str, StrictStr] = Field(description="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.") + mode: StrictStr = Field(description="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.") + part_size: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=None, description="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.") + part_urls: Optional[List[StrictStr]] = Field(default=None, description="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.") + upload_id: StrictStr = Field(description="Identifier for this upload. Pass it to the finalize endpoint and to the managed-table load endpoint once finalized.") + url: Optional[StrictStr] = Field(default=None, description="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`).") + __properties: ClassVar[List[str]] = ["finalize_token", "headers", "mode", "part_size", "part_urls", "upload_id", "url"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UploadSessionResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if part_size (nullable) is None + # and model_fields_set contains the field + if self.part_size is None and "part_size" in self.model_fields_set: + _dict['part_size'] = None + + # set to None if part_urls (nullable) is None + # and model_fields_set contains the field + if self.part_urls is None and "part_urls" in self.model_fields_set: + _dict['part_urls'] = None + + # set to None if url (nullable) is None + # and model_fields_set contains the field + if self.url is None and "url" in self.model_fields_set: + _dict['url'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UploadSessionResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "finalize_token": obj.get("finalize_token"), + "headers": obj.get("headers"), + "mode": obj.get("mode"), + "part_size": obj.get("part_size"), + "part_urls": obj.get("part_urls"), + "upload_id": obj.get("upload_id"), + "url": obj.get("url") + }) + return _obj + + diff --git a/test/test_batch_create_upload_request.py b/test/test_batch_create_upload_request.py new file mode 100644 index 0000000..dcd7d51 --- /dev/null +++ b/test/test_batch_create_upload_request.py @@ -0,0 +1,71 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest + +class TestBatchCreateUploadRequest(unittest.TestCase): + """BatchCreateUploadRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BatchCreateUploadRequest: + """Test BatchCreateUploadRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BatchCreateUploadRequest` + """ + model = BatchCreateUploadRequest() + if include_optional: + return BatchCreateUploadRequest( + uploads = [ + hotdata.models.create_upload_request.CreateUploadRequest( + checksum_algo = '', + checksum_value = '', + content_encoding = '', + content_type = '', + declared_size_bytes = 0, + filename = '', + part_size = 0, ) + ] + ) + else: + return BatchCreateUploadRequest( + uploads = [ + hotdata.models.create_upload_request.CreateUploadRequest( + checksum_algo = '', + checksum_value = '', + content_encoding = '', + content_type = '', + declared_size_bytes = 0, + filename = '', + part_size = 0, ) + ], + ) + """ + + def testBatchCreateUploadRequest(self): + """Test BatchCreateUploadRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_batch_create_upload_response.py b/test/test_batch_create_upload_response.py new file mode 100644 index 0000000..c28c41c --- /dev/null +++ b/test/test_batch_create_upload_response.py @@ -0,0 +1,79 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse + +class TestBatchCreateUploadResponse(unittest.TestCase): + """BatchCreateUploadResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BatchCreateUploadResponse: + """Test BatchCreateUploadResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BatchCreateUploadResponse` + """ + model = BatchCreateUploadResponse() + if include_optional: + return BatchCreateUploadResponse( + uploads = [ + hotdata.models.upload_session_response.UploadSessionResponse( + finalize_token = '', + headers = { + 'key' : '' + }, + mode = '', + part_size = 0, + part_urls = [ + '' + ], + upload_id = '', + url = '', ) + ] + ) + else: + return BatchCreateUploadResponse( + uploads = [ + hotdata.models.upload_session_response.UploadSessionResponse( + finalize_token = '', + headers = { + 'key' : '' + }, + mode = '', + part_size = 0, + part_urls = [ + '' + ], + upload_id = '', + url = '', ) + ], + ) + """ + + def testBatchCreateUploadResponse(self): + """Test BatchCreateUploadResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_create_upload_request.py b/test/test_create_upload_request.py new file mode 100644 index 0000000..f134ebd --- /dev/null +++ b/test/test_create_upload_request.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.create_upload_request import CreateUploadRequest + +class TestCreateUploadRequest(unittest.TestCase): + """CreateUploadRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> CreateUploadRequest: + """Test CreateUploadRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `CreateUploadRequest` + """ + model = CreateUploadRequest() + if include_optional: + return CreateUploadRequest( + checksum_algo = '', + checksum_value = '', + content_encoding = '', + content_type = '', + declared_size_bytes = 0, + filename = '', + part_size = 0 + ) + else: + return CreateUploadRequest( + declared_size_bytes = 0, + ) + """ + + def testCreateUploadRequest(self): + """Test CreateUploadRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_finalize_upload_part.py b/test/test_finalize_upload_part.py new file mode 100644 index 0000000..915f05d --- /dev/null +++ b/test/test_finalize_upload_part.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.finalize_upload_part import FinalizeUploadPart + +class TestFinalizeUploadPart(unittest.TestCase): + """FinalizeUploadPart unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> FinalizeUploadPart: + """Test FinalizeUploadPart + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `FinalizeUploadPart` + """ + model = FinalizeUploadPart() + if include_optional: + return FinalizeUploadPart( + e_tag = '', + part_number = 56 + ) + else: + return FinalizeUploadPart( + e_tag = '', + part_number = 56, + ) + """ + + def testFinalizeUploadPart(self): + """Test FinalizeUploadPart""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_finalize_upload_request.py b/test/test_finalize_upload_request.py new file mode 100644 index 0000000..7888b1b --- /dev/null +++ b/test/test_finalize_upload_request.py @@ -0,0 +1,56 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.finalize_upload_request import FinalizeUploadRequest + +class TestFinalizeUploadRequest(unittest.TestCase): + """FinalizeUploadRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> FinalizeUploadRequest: + """Test FinalizeUploadRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `FinalizeUploadRequest` + """ + model = FinalizeUploadRequest() + if include_optional: + return FinalizeUploadRequest( + parts = [ + hotdata.models.finalize_upload_part.FinalizeUploadPart( + e_tag = '', + part_number = 56, ) + ] + ) + else: + return FinalizeUploadRequest( + ) + """ + + def testFinalizeUploadRequest(self): + """Test FinalizeUploadRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_finalize_upload_response.py b/test/test_finalize_upload_response.py new file mode 100644 index 0000000..09ff45c --- /dev/null +++ b/test/test_finalize_upload_response.py @@ -0,0 +1,60 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.finalize_upload_response import FinalizeUploadResponse + +class TestFinalizeUploadResponse(unittest.TestCase): + """FinalizeUploadResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> FinalizeUploadResponse: + """Test FinalizeUploadResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `FinalizeUploadResponse` + """ + model = FinalizeUploadResponse() + if include_optional: + return FinalizeUploadResponse( + content_type = '', + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + size_bytes = 56, + status = '', + upload_id = '' + ) + else: + return FinalizeUploadResponse( + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + size_bytes = 56, + status = '', + upload_id = '', + ) + """ + + def testFinalizeUploadResponse(self): + """Test FinalizeUploadResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_upload_session_response.py b/test/test_upload_session_response.py new file mode 100644 index 0000000..b8d8be3 --- /dev/null +++ b/test/test_upload_session_response.py @@ -0,0 +1,68 @@ +# coding: utf-8 + +""" + Hotdata API + + Powerful data platform API for managed databases, queries, and analytics. + + The version of the OpenAPI document: 1.0.0 + Contact: developers@hotdata.dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from hotdata.models.upload_session_response import UploadSessionResponse + +class TestUploadSessionResponse(unittest.TestCase): + """UploadSessionResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UploadSessionResponse: + """Test UploadSessionResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UploadSessionResponse` + """ + model = UploadSessionResponse() + if include_optional: + return UploadSessionResponse( + finalize_token = '', + headers = { + 'key' : '' + }, + mode = '', + part_size = 0, + part_urls = [ + '' + ], + upload_id = '', + url = '' + ) + else: + return UploadSessionResponse( + finalize_token = '', + headers = { + 'key' : '' + }, + mode = '', + upload_id = '', + ) + """ + + def testUploadSessionResponse(self): + """Test UploadSessionResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_uploads_api.py b/test/test_uploads_api.py index 9b5e28d..cb99a7b 100644 --- a/test/test_uploads_api.py +++ b/test/test_uploads_api.py @@ -27,6 +27,27 @@ def setUp(self) -> None: def tearDown(self) -> None: pass + def test_create_upload_session_handler(self) -> None: + """Test case for create_upload_session_handler + + Create upload session + """ + pass + + def test_create_upload_sessions_batch_handler(self) -> None: + """Test case for create_upload_sessions_batch_handler + + Create upload sessions in bulk + """ + pass + + def test_finalize_upload_handler(self) -> None: + """Test case for finalize_upload_handler + + Finalize upload + """ + pass + def test_list_uploads(self) -> None: """Test case for list_uploads