hotdata 0.4.1__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hotdata-0.6.0/PKG-INFO +200 -0
- hotdata-0.6.0/README.md +182 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/__init__.py +64 -51
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/_auth.py +110 -19
- hotdata-0.6.0/hotdata/_upload_watchdog.py +462 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/__init__.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/connection_types_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/connections_api.py +7 -4
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/database_context_api.py +13 -13
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/databases_api.py +338 -4
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/embedding_providers_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/indexes_api.py +96 -940
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/information_schema_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/jobs_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/query_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/query_runs_api.py +46 -4
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/refresh_api.py +10 -4
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/results_api.py +40 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/saved_queries_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/secrets_api.py +1 -1
- hotdata-0.4.1/hotdata/api/datasets_api.py → hotdata-0.6.0/hotdata/api/uploads_api.py +351 -308
- hotdata-0.6.0/hotdata/api/usage_api.py +303 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api/workspaces_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api_client.py +2 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/arrow.py +20 -3
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/configuration.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/exceptions.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/__init__.py +12 -24
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/add_managed_schema_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/add_managed_table_decl.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/add_managed_table_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/api_error_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/api_error_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/async_query_response.py +3 -3
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/attach_database_catalog_request.py +1 -1
- hotdata-0.6.0/hotdata/models/batch_create_upload_request.py +96 -0
- hotdata-0.6.0/hotdata/models/batch_create_upload_response.py +96 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/boolean_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/categorical_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/category_value_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_detail_one_of.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_detail_one_of1.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_detail_one_of2.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_detail_one_of3.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_detail_one_of4.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/column_profile_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/connection_health_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/connection_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/connection_refresh_result.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/connection_schema_error.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/connection_type_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/connection_type_summary.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_connection_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_connection_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_database_request.py +2 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_database_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_embedding_provider_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_embedding_provider_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_index_request.py +9 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_saved_query_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_secret_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_secret_response.py +1 -1
- hotdata-0.6.0/hotdata/models/create_upload_request.py +136 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_workspace_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/create_workspace_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/database_attachment_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/database_context_entry.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/database_default_schema_decl.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/database_default_table_decl.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/database_detail_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/database_summary.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/discovery_status.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/embedding_provider_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/error.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/execute_saved_query_request.py +1 -1
- hotdata-0.4.1/hotdata/models/dataset_version_summary.py → hotdata-0.6.0/hotdata/models/finalize_upload_part.py +11 -16
- hotdata-0.4.1/hotdata/models/create_dataset_request.py → hotdata-0.6.0/hotdata/models/finalize_upload_request.py +20 -20
- hotdata-0.6.0/hotdata/models/finalize_upload_response.py +102 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/get_connection_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/get_database_context_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/get_result_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/get_secret_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/index_entry_response.py +4 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/index_info_response.py +9 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/index_status.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/information_schema_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/job_result.py +22 -22
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/job_status.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/job_status_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/job_type.py +6 -3
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_connection_types_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_connections_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_database_contexts_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_databases_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_embedding_providers_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_indexes_page_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_indexes_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_jobs_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_query_runs_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_results_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_saved_queries_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_saved_query_versions_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_secrets_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_uploads_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/list_workspaces_response.py +1 -1
- hotdata-0.6.0/hotdata/models/load_managed_table_request.py +107 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/load_managed_table_response.py +3 -3
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/managed_schema_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/managed_table_response.py +1 -1
- hotdata-0.4.1/hotdata/models/refresh_dataset_response.py → hotdata-0.6.0/hotdata/models/mint_upload_parts_request.py +9 -16
- hotdata-0.6.0/hotdata/models/mint_upload_parts_response.py +96 -0
- hotdata-0.6.0/hotdata/models/minted_upload_part_response.py +90 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/numeric_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/query_request.py +2 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/query_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/query_run_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/refresh_request.py +10 -9
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/refresh_response.py +9 -37
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/refresh_warning.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/result_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/results_format_query.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/saved_query_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/saved_query_summary.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/saved_query_version_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/schema_refresh_result.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/secret_metadata_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/submit_job_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/table_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/table_profile_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/table_refresh_error.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/table_refresh_result.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/temporal_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/text_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/update_embedding_provider_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/update_embedding_provider_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/update_saved_query_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/update_secret_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/update_secret_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/upload_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/upload_response.py +1 -1
- hotdata-0.6.0/hotdata/models/upload_session_response.py +116 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/upsert_database_context_request.py +2 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/upsert_database_context_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/workspace_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/models/workspace_list_item.py +1 -1
- hotdata-0.4.1/hotdata/models/dataset_summary.py → hotdata-0.6.0/hotdata/models/workspace_usage_response.py +20 -26
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/query.py +37 -7
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/rest.py +1 -1
- hotdata-0.6.0/hotdata/uploads.py +1690 -0
- hotdata-0.6.0/hotdata.egg-info/PKG-INFO +200 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata.egg-info/SOURCES.txt +34 -49
- {hotdata-0.4.1 → hotdata-0.6.0}/pyproject.toml +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_add_managed_schema_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_add_managed_table_decl.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_add_managed_table_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_api_error_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_api_error_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_async_query_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_attach_database_catalog_request.py +1 -1
- hotdata-0.6.0/test/test_batch_create_upload_request.py +71 -0
- hotdata-0.6.0/test/test_batch_create_upload_response.py +79 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_boolean_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_categorical_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_category_value_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_detail_one_of.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_detail_one_of1.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_detail_one_of2.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_detail_one_of3.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_detail_one_of4.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_column_profile_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_health_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_refresh_result.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_schema_error.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_type_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_type_summary.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connection_types_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_connections_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_connection_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_connection_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_database_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_database_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_embedding_provider_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_embedding_provider_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_index_request.py +2 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_saved_query_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_secret_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_secret_response.py +1 -1
- hotdata-0.6.0/test/test_create_upload_request.py +58 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_workspace_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_create_workspace_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_attachment_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_context_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_context_entry.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_default_schema_decl.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_default_table_decl.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_detail_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_database_summary.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_databases_api.py +8 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_discovery_status.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_embedding_provider_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_embedding_providers_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_error.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_execute_saved_query_request.py +1 -1
- hotdata-0.6.0/test/test_finalize_upload_part.py +55 -0
- hotdata-0.6.0/test/test_finalize_upload_request.py +56 -0
- hotdata-0.4.1/test/test_refresh_dataset_response.py → hotdata-0.6.0/test/test_finalize_upload_response.py +17 -16
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_get_connection_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_get_database_context_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_get_result_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_get_secret_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_index_entry_response.py +2 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_index_info_response.py +2 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_index_status.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_indexes_api.py +1 -22
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_information_schema_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_information_schema_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_job_result.py +11 -10
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_job_status.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_job_status_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_job_type.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_jobs_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_connection_types_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_connections_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_database_contexts_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_databases_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_embedding_providers_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_indexes_page_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_indexes_response.py +3 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_jobs_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_query_runs_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_results_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_saved_queries_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_saved_query_versions_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_secrets_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_uploads_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_list_workspaces_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_load_managed_table_request.py +4 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_load_managed_table_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_managed_schema_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_managed_table_response.py +1 -1
- hotdata-0.6.0/test/test_mint_upload_parts_request.py +57 -0
- hotdata-0.6.0/test/test_mint_upload_parts_response.py +61 -0
- hotdata-0.4.1/test/test_url_dataset_source.py → hotdata-0.6.0/test/test_minted_upload_part_response.py +14 -16
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_numeric_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_query_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_query_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_query_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_query_run_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_query_runs_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_refresh_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_refresh_request.py +2 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_refresh_response.py +2 -12
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_refresh_warning.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_result_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_results_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_results_format_query.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_saved_queries_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_saved_query_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_saved_query_summary.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_saved_query_version_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_schema_refresh_result.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_secret_metadata_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_secrets_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_submit_job_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_table_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_table_profile_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_table_refresh_error.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_table_refresh_result.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_temporal_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_text_profile_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_update_embedding_provider_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_update_embedding_provider_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_update_saved_query_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_update_secret_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_update_secret_response.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_upload_info.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_upload_response.py +1 -1
- hotdata-0.6.0/test/test_upload_session_response.py +68 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_uploads_api.py +29 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_upsert_database_context_request.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_upsert_database_context_response.py +1 -1
- hotdata-0.6.0/test/test_usage_api.py +39 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_workspace_detail.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_workspace_list_item.py +1 -1
- hotdata-0.6.0/test/test_workspace_usage_response.py +60 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_workspaces_api.py +1 -1
- {hotdata-0.4.1 → hotdata-0.6.0}/tests/test_arrow.py +8 -6
- {hotdata-0.4.1 → hotdata-0.6.0}/tests/test_auth.py +301 -2
- {hotdata-0.4.1 → hotdata-0.6.0}/tests/test_query.py +71 -0
- hotdata-0.6.0/tests/test_upload_codex_fixes.py +427 -0
- hotdata-0.6.0/tests/test_upload_multipart_resilient.py +354 -0
- hotdata-0.6.0/tests/test_upload_parity_fixes.py +512 -0
- hotdata-0.6.0/tests/test_upload_resilient.py +233 -0
- hotdata-0.6.0/tests/test_upload_retry_policy.py +201 -0
- hotdata-0.6.0/tests/test_upload_watchdog.py +441 -0
- hotdata-0.6.0/tests/test_uploads.py +1379 -0
- hotdata-0.4.1/PKG-INFO +0 -119
- hotdata-0.4.1/README.md +0 -101
- hotdata-0.4.1/hotdata/api/uploads_api.py +0 -587
- hotdata-0.4.1/hotdata/models/column_type_spec.py +0 -117
- hotdata-0.4.1/hotdata/models/create_dataset_response.py +0 -99
- hotdata-0.4.1/hotdata/models/dataset_source.py +0 -180
- hotdata-0.4.1/hotdata/models/dataset_source_one_of.py +0 -101
- hotdata-0.4.1/hotdata/models/dataset_source_one_of1.py +0 -99
- hotdata-0.4.1/hotdata/models/dataset_source_one_of2.py +0 -101
- hotdata-0.4.1/hotdata/models/dataset_source_one_of3.py +0 -101
- hotdata-0.4.1/hotdata/models/dataset_source_one_of4.py +0 -101
- hotdata-0.4.1/hotdata/models/get_dataset_response.py +0 -120
- hotdata-0.4.1/hotdata/models/inline_data.py +0 -92
- hotdata-0.4.1/hotdata/models/inline_dataset_source.py +0 -92
- hotdata-0.4.1/hotdata/models/list_dataset_versions_response.py +0 -107
- hotdata-0.4.1/hotdata/models/list_datasets_response.py +0 -105
- hotdata-0.4.1/hotdata/models/load_managed_table_request.py +0 -90
- hotdata-0.4.1/hotdata/models/saved_query_dataset_source.py +0 -95
- hotdata-0.4.1/hotdata/models/sql_query_dataset_source.py +0 -102
- hotdata-0.4.1/hotdata/models/update_dataset_request.py +0 -107
- hotdata-0.4.1/hotdata/models/update_dataset_response.py +0 -104
- hotdata-0.4.1/hotdata/models/upload_dataset_source.py +0 -97
- hotdata-0.4.1/hotdata/models/url_dataset_source.py +0 -97
- hotdata-0.4.1/hotdata.egg-info/PKG-INFO +0 -119
- hotdata-0.4.1/test/test_column_type_spec.py +0 -57
- hotdata-0.4.1/test/test_create_dataset_request.py +0 -56
- hotdata-0.4.1/test/test_create_dataset_response.py +0 -63
- hotdata-0.4.1/test/test_dataset_source.py +0 -80
- hotdata-0.4.1/test/test_dataset_source_one_of.py +0 -59
- hotdata-0.4.1/test/test_dataset_source_one_of1.py +0 -56
- hotdata-0.4.1/test/test_dataset_source_one_of2.py +0 -57
- hotdata-0.4.1/test/test_dataset_source_one_of3.py +0 -59
- hotdata-0.4.1/test/test_dataset_source_one_of4.py +0 -65
- hotdata-0.4.1/test/test_dataset_summary.py +0 -66
- hotdata-0.4.1/test/test_dataset_version_summary.py +0 -59
- hotdata-0.4.1/test/test_datasets_api.py +0 -74
- hotdata-0.4.1/test/test_get_dataset_response.py +0 -80
- hotdata-0.4.1/test/test_inline_data.py +0 -58
- hotdata-0.4.1/test/test_inline_dataset_source.py +0 -63
- hotdata-0.4.1/test/test_list_dataset_versions_response.py +0 -75
- hotdata-0.4.1/test/test_list_datasets_response.py +0 -81
- hotdata-0.4.1/test/test_saved_query_dataset_source.py +0 -54
- hotdata-0.4.1/test/test_sql_query_dataset_source.py +0 -55
- hotdata-0.4.1/test/test_update_dataset_request.py +0 -54
- hotdata-0.4.1/test/test_update_dataset_response.py +0 -62
- hotdata-0.4.1/test/test_upload_dataset_source.py +0 -57
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/_retry.py +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/api_response.py +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata/py.typed +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata.egg-info/dependency_links.txt +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata.egg-info/requires.txt +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/hotdata.egg-info/top_level.txt +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/setup.cfg +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/test/test_api_client_close.py +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/tests/test_retry.py +0 -0
- {hotdata-0.4.1 → hotdata-0.6.0}/tests/test_update_changelog.py +0 -0
hotdata-0.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hotdata
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Hotdata API
|
|
5
|
+
Author-email: Hotdata <developers@hotdata.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://www.hotdata.dev
|
|
8
|
+
Project-URL: Repository, https://github.com/hotdata-dev/sdk-python
|
|
9
|
+
Keywords: hotdata,api-client,data-platform
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: urllib3<3.0.0,>=2.1.0
|
|
13
|
+
Requires-Dist: python-dateutil>=2.8.2
|
|
14
|
+
Requires-Dist: pydantic>=2.4.0
|
|
15
|
+
Requires-Dist: typing-extensions>=4.7.1
|
|
16
|
+
Provides-Extra: arrow
|
|
17
|
+
Requires-Dist: pyarrow>=14.0.1; extra == "arrow"
|
|
18
|
+
|
|
19
|
+
# hotdata
|
|
20
|
+
|
|
21
|
+
Official Python client for the [Hotdata](https://www.hotdata.dev) HTTP API: workspaces, connections, datasets, SQL queries, results, secrets, uploads, indexes, jobs, embedding providers, and workspace context.
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
Python 3.9+
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
pip install hotdata
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For an unreleased revision:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
pip install "git+https://github.com/hotdata-dev/sdk-python.git"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
From a local checkout (editable):
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Authentication
|
|
46
|
+
|
|
47
|
+
The API uses an **API key** sent as `Authorization: Bearer <key>`, plus an **`X-Workspace-Id`** header on requests scoped to a workspace.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import hotdata
|
|
51
|
+
|
|
52
|
+
configuration = hotdata.Configuration(
|
|
53
|
+
api_key="YOUR_API_KEY",
|
|
54
|
+
workspace_id="YOUR_WORKSPACE_ID",
|
|
55
|
+
)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`host` defaults to `https://api.hotdata.dev`. Override it if you target another environment.
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
import hotdata
|
|
64
|
+
from hotdata.rest import ApiException
|
|
65
|
+
|
|
66
|
+
configuration = hotdata.Configuration(
|
|
67
|
+
api_key="YOUR_API_KEY",
|
|
68
|
+
workspace_id="YOUR_WORKSPACE_ID",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
with hotdata.ApiClient(configuration) as api_client:
|
|
72
|
+
workspaces = hotdata.WorkspacesApi(api_client)
|
|
73
|
+
try:
|
|
74
|
+
response = workspaces.list_workspaces()
|
|
75
|
+
except ApiException as e:
|
|
76
|
+
print(f"API error: {e.status} {e.reason}\n{e.body}")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Each `Api` class groups endpoints by resource. Construct the client, then call the typed methods you need.
|
|
80
|
+
|
|
81
|
+
## Arrow results
|
|
82
|
+
|
|
83
|
+
Query results can be fetched as an [Apache Arrow](https://arrow.apache.org/) IPC stream instead of JSON, which is faster and far more memory-efficient for large result sets. Install the optional extra:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
pip install 'hotdata[arrow]'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Use `hotdata.arrow.ResultsApi` (a drop-in subclass of `ResultsApi` that adds Arrow methods):
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from hotdata import ApiClient, Configuration
|
|
93
|
+
from hotdata.arrow import ResultsApi
|
|
94
|
+
|
|
95
|
+
with ApiClient(Configuration(api_key="...", workspace_id="...")) as client:
|
|
96
|
+
results = ResultsApi(client)
|
|
97
|
+
|
|
98
|
+
# Results are scoped to a database via the required `X-Database-Id` header,
|
|
99
|
+
# so pass the id of the database the query ran in.
|
|
100
|
+
database_id = "your_database_id"
|
|
101
|
+
|
|
102
|
+
# Buffered: returns a pyarrow.Table.
|
|
103
|
+
table = results.get_result_arrow(result_id, database_id)
|
|
104
|
+
|
|
105
|
+
# Streaming: yields a pyarrow.RecordBatchStreamReader without
|
|
106
|
+
# materializing the full table in memory.
|
|
107
|
+
with results.stream_result_arrow(result_id, database_id) as reader:
|
|
108
|
+
for batch in reader:
|
|
109
|
+
...
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Both methods accept `offset` and `limit` for pagination. They raise `hotdata.arrow.ResultNotReadyError` if the result is still pending or processing — poll `results.get_result(result_id, database_id)` until `status == "ready"` first.
|
|
113
|
+
|
|
114
|
+
## File uploads
|
|
115
|
+
|
|
116
|
+
`hotdata.uploads.UploadsApi` (also the default `hotdata.UploadsApi`) adds
|
|
117
|
+
`upload_file`, which uploads a local file **directly to object storage** and
|
|
118
|
+
finalizes it in one call. It opens an upload session, `PUT`s the bytes straight
|
|
119
|
+
to storage — a single `PUT` for a small file, concurrent part `PUT`s for a large
|
|
120
|
+
one — then finalizes. The bytes never round-trip through the API.
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from hotdata import ApiClient, Configuration, UploadsApi
|
|
124
|
+
|
|
125
|
+
with ApiClient(Configuration(api_key="...", workspace_id="...")) as client:
|
|
126
|
+
uploads = UploadsApi(client)
|
|
127
|
+
|
|
128
|
+
finalized = uploads.upload_file(
|
|
129
|
+
"data.parquet",
|
|
130
|
+
content_type="application/parquet",
|
|
131
|
+
progress=lambda done, total: print(f"{done}/{total} bytes"),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Pass finalized.upload_id to the managed-table load endpoint.
|
|
135
|
+
print(finalized.upload_id)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`upload_file` accepts a path, raw `bytes`, or a seekable binary file object
|
|
139
|
+
(`size` is inferred for all three; a file object is read from its current
|
|
140
|
+
position to the end). The SDK picks single vs. multipart from the size,
|
|
141
|
+
auto-scales the part size, and bounds part concurrency to a peak-memory budget
|
|
142
|
+
(override with `part_size` / `max_concurrency` / `part_retry`). A file larger than
|
|
143
|
+
8 MiB uploads via a **streaming** session — the SDK mints each part's URL just
|
|
144
|
+
before its `PUT`, so a presigned URL can't expire mid-transfer on a slow upload.
|
|
145
|
+
Storage `PUT`s go through a dedicated, header-isolated connection pool (auth and
|
|
146
|
+
workspace headers never reach object storage, which would otherwise reject the
|
|
147
|
+
upload) with a 30s connect timeout so a dead endpoint fails fast. Finalize is sent
|
|
148
|
+
with retries disabled so the exactly-once call is never accidentally replayed.
|
|
149
|
+
|
|
150
|
+
Every failure is a subclass of `hotdata.uploads.UploadError` (also importable as
|
|
151
|
+
`from hotdata import UploadError`), so a single `except UploadError` catches the
|
|
152
|
+
whole flow: `SessionCreateError` (opening the session — check `.status` for a
|
|
153
|
+
`501` `PRESIGN_UNSUPPORTED`), `StorageError` (storage returned a non-2xx; `.exhausted`
|
|
154
|
+
is `True` if it outlived every retry round), `StorageTransportError` (the PUT
|
|
155
|
+
failed before any response), `MissingETagError`, `MintPartError` (minting a part
|
|
156
|
+
URL), `FinalizeError`, `MalformedSessionError`, `SizeLimitError`, and
|
|
157
|
+
`UploadCancelledError`. The phase errors that wrap a control-plane call chain the
|
|
158
|
+
underlying `hotdata.exceptions.ApiException` as `__cause__` (and expose it as
|
|
159
|
+
`.api_exception` / `.status`). A local file read error surfaces as `OSError`.
|
|
160
|
+
|
|
161
|
+
The `progress` callback receives a **cumulative** `(bytes_done, total)` — for a
|
|
162
|
+
tqdm bar (whose `update(n)` wants a delta, and which isn't thread-safe under
|
|
163
|
+
multipart) use the ready-made adapter:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from hotdata import tqdm_progress
|
|
167
|
+
from tqdm import tqdm
|
|
168
|
+
|
|
169
|
+
with tqdm(total=size, unit="B", unit_scale=True) as bar:
|
|
170
|
+
uploads.upload_file("data.parquet", progress=tqdm_progress(bar))
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Pass a `threading.Event` as `cancel_event` to abort an in-flight upload; tune the
|
|
174
|
+
control-plane calls with `request_timeout` (storage-PUT timeouts are automatic and
|
|
175
|
+
size-scaled).
|
|
176
|
+
|
|
177
|
+
For that fallback (or to upload from a non-seekable stream), use `upload_stream`,
|
|
178
|
+
which sends the bytes to the legacy `POST /v1/files` endpoint in one request,
|
|
179
|
+
streaming a file object without buffering it in memory:
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
with open("data.parquet", "rb") as f:
|
|
183
|
+
resp = uploads.upload_stream(f, content_type="application/parquet")
|
|
184
|
+
print(resp.id)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Note `upload_file` shadows the generated raw-body `upload_file(body=...)`; that
|
|
188
|
+
raw operation is still reachable at
|
|
189
|
+
`hotdata.api.uploads_api.UploadsApi.upload_file`.
|
|
190
|
+
|
|
191
|
+
## API reference
|
|
192
|
+
|
|
193
|
+
Generated Markdown for every operation and model is in [`docs/`](https://github.com/hotdata-dev/sdk-python/tree/main/docs):
|
|
194
|
+
|
|
195
|
+
- Resource APIs: `docs/*Api.md` (for example [`QueryApi.md`](https://github.com/hotdata-dev/sdk-python/blob/main/docs/QueryApi.md))
|
|
196
|
+
- Request and response models: `docs/<ModelName>.md`
|
|
197
|
+
|
|
198
|
+
## Support
|
|
199
|
+
|
|
200
|
+
Questions and issues: [github.com/hotdata-dev/sdk-python](https://github.com/hotdata-dev/sdk-python).
|
hotdata-0.6.0/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# hotdata
|
|
2
|
+
|
|
3
|
+
Official Python client for the [Hotdata](https://www.hotdata.dev) HTTP API: workspaces, connections, datasets, SQL queries, results, secrets, uploads, indexes, jobs, embedding providers, and workspace context.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
Python 3.9+
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
pip install hotdata
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For an unreleased revision:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
pip install "git+https://github.com/hotdata-dev/sdk-python.git"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
From a local checkout (editable):
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pip install -e .
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Authentication
|
|
28
|
+
|
|
29
|
+
The API uses an **API key** sent as `Authorization: Bearer <key>`, plus an **`X-Workspace-Id`** header on requests scoped to a workspace.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import hotdata
|
|
33
|
+
|
|
34
|
+
configuration = hotdata.Configuration(
|
|
35
|
+
api_key="YOUR_API_KEY",
|
|
36
|
+
workspace_id="YOUR_WORKSPACE_ID",
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`host` defaults to `https://api.hotdata.dev`. Override it if you target another environment.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import hotdata
|
|
46
|
+
from hotdata.rest import ApiException
|
|
47
|
+
|
|
48
|
+
configuration = hotdata.Configuration(
|
|
49
|
+
api_key="YOUR_API_KEY",
|
|
50
|
+
workspace_id="YOUR_WORKSPACE_ID",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
with hotdata.ApiClient(configuration) as api_client:
|
|
54
|
+
workspaces = hotdata.WorkspacesApi(api_client)
|
|
55
|
+
try:
|
|
56
|
+
response = workspaces.list_workspaces()
|
|
57
|
+
except ApiException as e:
|
|
58
|
+
print(f"API error: {e.status} {e.reason}\n{e.body}")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Each `Api` class groups endpoints by resource. Construct the client, then call the typed methods you need.
|
|
62
|
+
|
|
63
|
+
## Arrow results
|
|
64
|
+
|
|
65
|
+
Query results can be fetched as an [Apache Arrow](https://arrow.apache.org/) IPC stream instead of JSON, which is faster and far more memory-efficient for large result sets. Install the optional extra:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
pip install 'hotdata[arrow]'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Use `hotdata.arrow.ResultsApi` (a drop-in subclass of `ResultsApi` that adds Arrow methods):
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from hotdata import ApiClient, Configuration
|
|
75
|
+
from hotdata.arrow import ResultsApi
|
|
76
|
+
|
|
77
|
+
with ApiClient(Configuration(api_key="...", workspace_id="...")) as client:
|
|
78
|
+
results = ResultsApi(client)
|
|
79
|
+
|
|
80
|
+
# Results are scoped to a database via the required `X-Database-Id` header,
|
|
81
|
+
# so pass the id of the database the query ran in.
|
|
82
|
+
database_id = "your_database_id"
|
|
83
|
+
|
|
84
|
+
# Buffered: returns a pyarrow.Table.
|
|
85
|
+
table = results.get_result_arrow(result_id, database_id)
|
|
86
|
+
|
|
87
|
+
# Streaming: yields a pyarrow.RecordBatchStreamReader without
|
|
88
|
+
# materializing the full table in memory.
|
|
89
|
+
with results.stream_result_arrow(result_id, database_id) as reader:
|
|
90
|
+
for batch in reader:
|
|
91
|
+
...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Both methods accept `offset` and `limit` for pagination. They raise `hotdata.arrow.ResultNotReadyError` if the result is still pending or processing — poll `results.get_result(result_id, database_id)` until `status == "ready"` first.
|
|
95
|
+
|
|
96
|
+
## File uploads
|
|
97
|
+
|
|
98
|
+
`hotdata.uploads.UploadsApi` (also the default `hotdata.UploadsApi`) adds
|
|
99
|
+
`upload_file`, which uploads a local file **directly to object storage** and
|
|
100
|
+
finalizes it in one call. It opens an upload session, `PUT`s the bytes straight
|
|
101
|
+
to storage — a single `PUT` for a small file, concurrent part `PUT`s for a large
|
|
102
|
+
one — then finalizes. The bytes never round-trip through the API.
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from hotdata import ApiClient, Configuration, UploadsApi
|
|
106
|
+
|
|
107
|
+
with ApiClient(Configuration(api_key="...", workspace_id="...")) as client:
|
|
108
|
+
uploads = UploadsApi(client)
|
|
109
|
+
|
|
110
|
+
finalized = uploads.upload_file(
|
|
111
|
+
"data.parquet",
|
|
112
|
+
content_type="application/parquet",
|
|
113
|
+
progress=lambda done, total: print(f"{done}/{total} bytes"),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# Pass finalized.upload_id to the managed-table load endpoint.
|
|
117
|
+
print(finalized.upload_id)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`upload_file` accepts a path, raw `bytes`, or a seekable binary file object
|
|
121
|
+
(`size` is inferred for all three; a file object is read from its current
|
|
122
|
+
position to the end). The SDK picks single vs. multipart from the size,
|
|
123
|
+
auto-scales the part size, and bounds part concurrency to a peak-memory budget
|
|
124
|
+
(override with `part_size` / `max_concurrency` / `part_retry`). A file larger than
|
|
125
|
+
8 MiB uploads via a **streaming** session — the SDK mints each part's URL just
|
|
126
|
+
before its `PUT`, so a presigned URL can't expire mid-transfer on a slow upload.
|
|
127
|
+
Storage `PUT`s go through a dedicated, header-isolated connection pool (auth and
|
|
128
|
+
workspace headers never reach object storage, which would otherwise reject the
|
|
129
|
+
upload) with a 30s connect timeout so a dead endpoint fails fast. Finalize is sent
|
|
130
|
+
with retries disabled so the exactly-once call is never accidentally replayed.
|
|
131
|
+
|
|
132
|
+
Every failure is a subclass of `hotdata.uploads.UploadError` (also importable as
|
|
133
|
+
`from hotdata import UploadError`), so a single `except UploadError` catches the
|
|
134
|
+
whole flow: `SessionCreateError` (opening the session — check `.status` for a
|
|
135
|
+
`501` `PRESIGN_UNSUPPORTED`), `StorageError` (storage returned a non-2xx; `.exhausted`
|
|
136
|
+
is `True` if it outlived every retry round), `StorageTransportError` (the PUT
|
|
137
|
+
failed before any response), `MissingETagError`, `MintPartError` (minting a part
|
|
138
|
+
URL), `FinalizeError`, `MalformedSessionError`, `SizeLimitError`, and
|
|
139
|
+
`UploadCancelledError`. The phase errors that wrap a control-plane call chain the
|
|
140
|
+
underlying `hotdata.exceptions.ApiException` as `__cause__` (and expose it as
|
|
141
|
+
`.api_exception` / `.status`). A local file read error surfaces as `OSError`.
|
|
142
|
+
|
|
143
|
+
The `progress` callback receives a **cumulative** `(bytes_done, total)` — for a
|
|
144
|
+
tqdm bar (whose `update(n)` wants a delta, and which isn't thread-safe under
|
|
145
|
+
multipart) use the ready-made adapter:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from hotdata import tqdm_progress
|
|
149
|
+
from tqdm import tqdm
|
|
150
|
+
|
|
151
|
+
with tqdm(total=size, unit="B", unit_scale=True) as bar:
|
|
152
|
+
uploads.upload_file("data.parquet", progress=tqdm_progress(bar))
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Pass a `threading.Event` as `cancel_event` to abort an in-flight upload; tune the
|
|
156
|
+
control-plane calls with `request_timeout` (storage-PUT timeouts are automatic and
|
|
157
|
+
size-scaled).
|
|
158
|
+
|
|
159
|
+
For that fallback (or to upload from a non-seekable stream), use `upload_stream`,
|
|
160
|
+
which sends the bytes to the legacy `POST /v1/files` endpoint in one request,
|
|
161
|
+
streaming a file object without buffering it in memory:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
with open("data.parquet", "rb") as f:
|
|
165
|
+
resp = uploads.upload_stream(f, content_type="application/parquet")
|
|
166
|
+
print(resp.id)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Note `upload_file` shadows the generated raw-body `upload_file(body=...)`; that
|
|
170
|
+
raw operation is still reachable at
|
|
171
|
+
`hotdata.api.uploads_api.UploadsApi.upload_file`.
|
|
172
|
+
|
|
173
|
+
## API reference
|
|
174
|
+
|
|
175
|
+
Generated Markdown for every operation and model is in [`docs/`](https://github.com/hotdata-dev/sdk-python/tree/main/docs):
|
|
176
|
+
|
|
177
|
+
- Resource APIs: `docs/*Api.md` (for example [`QueryApi.md`](https://github.com/hotdata-dev/sdk-python/blob/main/docs/QueryApi.md))
|
|
178
|
+
- Request and response models: `docs/<ModelName>.md`
|
|
179
|
+
|
|
180
|
+
## Support
|
|
181
|
+
|
|
182
|
+
Questions and issues: [github.com/hotdata-dev/sdk-python](https://github.com/hotdata-dev/sdk-python).
|