hotdata 0.8.0__tar.gz → 0.9.1__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.8.0 → hotdata-0.9.1}/PKG-INFO +4 -18
- {hotdata-0.8.0 → hotdata-0.9.1}/README.md +1 -15
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/__init__.py +18 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/_auth.py +138 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/connections_api.py +9 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/databases_api.py +1206 -32
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/information_schema_api.py +3 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/query_api.py +0 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/results_api.py +0 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/uploads_api.py +14 -563
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/usage_api.py +3 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api_client.py +93 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/configuration.py +4 -37
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/__init__.py +9 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/add_managed_table_decl.py +22 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/add_managed_table_request.py +22 -2
- hotdata-0.9.1/hotdata/models/bulk_create_databases_request.py +134 -0
- hotdata-0.9.1/hotdata/models/bulk_create_databases_result.py +95 -0
- hotdata-0.9.1/hotdata/models/column_definition.py +141 -0
- hotdata-0.9.1/hotdata/models/column_type_spec.py +103 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_connection_request.py +2 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_database_response.py +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_embedding_provider_request.py +1 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_index_request.py +15 -5
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_upload_request.py +3 -3
- hotdata-0.9.1/hotdata/models/database_batch_response.py +116 -0
- hotdata-0.9.1/hotdata/models/database_count_response.py +88 -0
- hotdata-0.9.1/hotdata/models/database_default_table_decl.py +110 -0
- hotdata-0.9.1/hotdata/models/delete_database_batch_response.py +90 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/finalize_upload_part.py +3 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/finalize_upload_request.py +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/index_entry_response.py +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/job_result.py +22 -8
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/job_type.py +3 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_databases_response.py +34 -5
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/load_managed_table_request.py +36 -7
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/mint_upload_parts_request.py +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/query_request.py +2 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/query_response.py +3 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/query_run_info.py +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/refresh_request.py +6 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/table_info.py +21 -1
- hotdata-0.8.0/hotdata/models/database_default_table_decl.py → hotdata-0.9.1/hotdata/models/table_partition_key.py +10 -10
- hotdata-0.9.1/hotdata/models/table_sort_key.py +102 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/upload_session_response.py +2 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/uploads.py +12 -135
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata.egg-info/PKG-INFO +4 -18
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata.egg-info/SOURCES.txt +19 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata.egg-info/requires.txt +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/pyproject.toml +3 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_add_managed_schema_request.py +14 -5
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_add_managed_table_decl.py +13 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_add_managed_table_request.py +13 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_attach_database_catalog_request.py +3 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_batch_create_upload_request.py +2 -20
- hotdata-0.9.1/test/test_bulk_create_databases_request.py +78 -0
- hotdata-0.9.1/test/test_bulk_create_databases_result.py +59 -0
- hotdata-0.9.1/test/test_column_definition.py +55 -0
- hotdata-0.9.1/test/test_column_type_spec.py +55 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connections_api.py +1 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_connection_request.py +7 -11
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_database_request.py +13 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_embedding_provider_request.py +6 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_index_request.py +5 -9
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_saved_query_request.py +6 -8
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_secret_request.py +4 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_upload_request.py +6 -6
- hotdata-0.9.1/test/test_database_batch_response.py +62 -0
- hotdata-0.9.1/test/test_database_count_response.py +53 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_default_schema_decl.py +14 -5
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_default_table_decl.py +13 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_databases_api.py +29 -1
- hotdata-0.9.1/test/test_delete_database_batch_response.py +55 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_finalize_upload_part.py +4 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_finalize_upload_request.py +2 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_information_schema_response.py +22 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_job_result.py +9 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_databases_response.py +5 -1
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_load_managed_table_request.py +9 -3
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_mint_upload_parts_request.py +2 -6
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_query_request.py +5 -5
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_table_info.py +22 -0
- hotdata-0.9.1/test/test_table_partition_key.py +55 -0
- hotdata-0.9.1/test/test_table_sort_key.py +55 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_update_secret_request.py +2 -2
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_uploads_api.py +0 -14
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_upsert_database_context_request.py +4 -4
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_auth.py +324 -0
- hotdata-0.9.1/tests/test_config_auth_surface.py +138 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_uploads.py +1 -154
- hotdata-0.8.0/hotdata/models/list_uploads_response.py +0 -96
- hotdata-0.8.0/hotdata/models/upload_info.py +0 -102
- hotdata-0.8.0/hotdata/models/upload_response.py +0 -102
- hotdata-0.8.0/test/test_list_uploads_response.py +0 -67
- hotdata-0.8.0/test/test_upload_info.py +0 -60
- hotdata-0.8.0/test/test_upload_response.py +0 -60
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/_retry.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/_upload_watchdog.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/__init__.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/connection_types_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/database_context_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/embedding_providers_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/indexes_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/jobs_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/query_runs_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/refresh_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/saved_queries_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/secrets_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api/workspaces_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/api_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/arrow.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/exceptions.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/add_managed_schema_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/api_error_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/api_error_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/async_query_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/attach_database_catalog_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/batch_create_upload_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/batch_create_upload_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/boolean_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/categorical_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/category_value_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_detail_one_of.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_detail_one_of1.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_detail_one_of2.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_detail_one_of3.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_detail_one_of4.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/column_profile_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/connection_health_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/connection_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/connection_refresh_result.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/connection_schema_error.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/connection_type_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/connection_type_summary.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_connection_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_database_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_embedding_provider_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_saved_query_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_secret_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_secret_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_workspace_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/create_workspace_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/database_attachment_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/database_context_entry.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/database_default_schema_decl.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/database_detail_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/database_summary.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/discovery_status.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/embedding_provider_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/error.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/execute_saved_query_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/finalize_upload_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/fork_database_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/get_connection_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/get_database_context_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/get_result_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/get_secret_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/index_info_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/index_status.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/information_schema_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/job_status.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/job_status_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_connection_types_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_connections_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_database_contexts_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_embedding_providers_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_indexes_page_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_indexes_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_jobs_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_query_runs_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_results_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_saved_queries_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_saved_query_versions_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_secrets_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/list_workspaces_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/load_managed_table_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/managed_schema_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/managed_table_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/mint_upload_parts_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/minted_upload_part_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/numeric_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/refresh_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/refresh_warning.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/result_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/results_format_query.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/saved_query_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/saved_query_summary.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/saved_query_version_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/schema_refresh_result.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/secret_metadata_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/submit_job_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/table_profile_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/table_refresh_error.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/table_refresh_result.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/temporal_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/text_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/update_embedding_provider_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/update_embedding_provider_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/update_saved_query_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/update_secret_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/update_secret_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/upsert_database_context_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/upsert_database_context_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/workspace_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/workspace_list_item.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/models/workspace_usage_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/py.typed +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/query.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata/rest.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata.egg-info/dependency_links.txt +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/hotdata.egg-info/top_level.txt +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/setup.cfg +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_api_client_close.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_api_error_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_api_error_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_async_query_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_batch_create_upload_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_boolean_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_categorical_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_category_value_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_detail_one_of.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_detail_one_of1.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_detail_one_of2.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_detail_one_of3.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_detail_one_of4.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_column_profile_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_health_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_refresh_result.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_schema_error.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_type_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_type_summary.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_connection_types_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_connection_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_database_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_embedding_provider_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_secret_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_workspace_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_create_workspace_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_attachment_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_context_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_context_entry.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_detail_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_database_summary.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_discovery_status.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_embedding_provider_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_embedding_providers_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_error.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_execute_saved_query_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_finalize_upload_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_fork_database_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_get_connection_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_get_database_context_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_get_result_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_get_secret_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_index_entry_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_index_info_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_index_status.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_indexes_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_information_schema_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_job_status.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_job_status_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_job_type.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_jobs_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_connection_types_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_connections_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_database_contexts_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_embedding_providers_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_indexes_page_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_indexes_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_jobs_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_query_runs_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_results_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_saved_queries_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_saved_query_versions_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_secrets_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_list_workspaces_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_load_managed_table_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_managed_schema_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_managed_table_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_mint_upload_parts_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_minted_upload_part_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_numeric_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_query_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_query_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_query_run_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_query_runs_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_refresh_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_refresh_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_refresh_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_refresh_warning.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_result_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_results_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_results_format_query.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_saved_queries_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_saved_query_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_saved_query_summary.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_saved_query_version_info.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_schema_refresh_result.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_secret_metadata_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_secrets_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_submit_job_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_table_profile_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_table_refresh_error.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_table_refresh_result.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_temporal_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_text_profile_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_update_embedding_provider_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_update_embedding_provider_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_update_saved_query_request.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_update_secret_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_upload_session_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_upsert_database_context_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_usage_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_workspace_detail.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_workspace_list_item.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_workspace_usage_response.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/test/test_workspaces_api.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_arrow.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_query.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_retry.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_update_changelog.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_upload_codex_fixes.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_upload_multipart_resilient.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_upload_parity_fixes.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_upload_resilient.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_upload_retry_policy.py +0 -0
- {hotdata-0.8.0 → hotdata-0.9.1}/tests/test_upload_watchdog.py +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hotdata
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: Hotdata API
|
|
5
5
|
Author-email: Hotdata <developers@hotdata.dev>
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://www.hotdata.dev
|
|
8
8
|
Project-URL: Repository, https://github.com/hotdata-dev/sdk-python
|
|
9
9
|
Keywords: hotdata,api-client,data-platform
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: urllib3<3.0.0,>=2.
|
|
12
|
+
Requires-Dist: urllib3<3.0.0,>=2.7.0
|
|
13
13
|
Requires-Dist: python-dateutil>=2.8.2
|
|
14
14
|
Requires-Dist: pydantic>=2.4.0
|
|
15
15
|
Requires-Dist: typing-extensions>=4.7.1
|
|
@@ -22,7 +22,7 @@ Official Python client for the [Hotdata](https://www.hotdata.dev) HTTP API: work
|
|
|
22
22
|
|
|
23
23
|
## Requirements
|
|
24
24
|
|
|
25
|
-
Python 3.
|
|
25
|
+
Python 3.10+
|
|
26
26
|
|
|
27
27
|
## Install
|
|
28
28
|
|
|
@@ -174,20 +174,6 @@ Pass a `threading.Event` as `cancel_event` to abort an in-flight upload; tune th
|
|
|
174
174
|
control-plane calls with `request_timeout` (storage-PUT timeouts are automatic and
|
|
175
175
|
size-scaled).
|
|
176
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
177
|
## API reference
|
|
192
178
|
|
|
193
179
|
Generated Markdown for every operation and model is in [`docs/`](https://github.com/hotdata-dev/sdk-python/tree/main/docs):
|
|
@@ -4,7 +4,7 @@ Official Python client for the [Hotdata](https://www.hotdata.dev) HTTP API: work
|
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
Python 3.
|
|
7
|
+
Python 3.10+
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -156,20 +156,6 @@ Pass a `threading.Event` as `cancel_event` to abort an in-flight upload; tune th
|
|
|
156
156
|
control-plane calls with `request_timeout` (storage-PUT timeouts are automatic and
|
|
157
157
|
size-scaled).
|
|
158
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
159
|
## API reference
|
|
174
160
|
|
|
175
161
|
Generated Markdown for every operation and model is in [`docs/`](https://github.com/hotdata-dev/sdk-python/tree/main/docs):
|
|
@@ -60,8 +60,11 @@ __all__ = [
|
|
|
60
60
|
"BatchCreateUploadRequest",
|
|
61
61
|
"BatchCreateUploadResponse",
|
|
62
62
|
"BooleanProfileDetail",
|
|
63
|
+
"BulkCreateDatabasesRequest",
|
|
64
|
+
"BulkCreateDatabasesResult",
|
|
63
65
|
"CategoricalProfileDetail",
|
|
64
66
|
"CategoryValueInfo",
|
|
67
|
+
"ColumnDefinition",
|
|
65
68
|
"ColumnInfo",
|
|
66
69
|
"ColumnProfileDetail",
|
|
67
70
|
"ColumnProfileDetailOneOf",
|
|
@@ -70,6 +73,7 @@ __all__ = [
|
|
|
70
73
|
"ColumnProfileDetailOneOf3",
|
|
71
74
|
"ColumnProfileDetailOneOf4",
|
|
72
75
|
"ColumnProfileInfo",
|
|
76
|
+
"ColumnTypeSpec",
|
|
73
77
|
"ConnectionHealthResponse",
|
|
74
78
|
"ConnectionInfo",
|
|
75
79
|
"ConnectionRefreshResult",
|
|
@@ -90,11 +94,14 @@ __all__ = [
|
|
|
90
94
|
"CreateWorkspaceRequest",
|
|
91
95
|
"CreateWorkspaceResponse",
|
|
92
96
|
"DatabaseAttachmentInfo",
|
|
97
|
+
"DatabaseBatchResponse",
|
|
93
98
|
"DatabaseContextEntry",
|
|
99
|
+
"DatabaseCountResponse",
|
|
94
100
|
"DatabaseDefaultSchemaDecl",
|
|
95
101
|
"DatabaseDefaultTableDecl",
|
|
96
102
|
"DatabaseDetailResponse",
|
|
97
103
|
"DatabaseSummary",
|
|
104
|
+
"DeleteDatabaseBatchResponse",
|
|
98
105
|
"DiscoveryStatus",
|
|
99
106
|
"EmbeddingProviderResponse",
|
|
100
107
|
"Error",
|
|
@@ -128,7 +135,6 @@ __all__ = [
|
|
|
128
135
|
"ListSavedQueriesResponse",
|
|
129
136
|
"ListSavedQueryVersionsResponse",
|
|
130
137
|
"ListSecretsResponse",
|
|
131
|
-
"ListUploadsResponse",
|
|
132
138
|
"ListWorkspacesResponse",
|
|
133
139
|
"LoadManagedTableRequest",
|
|
134
140
|
"LoadManagedTableResponse",
|
|
@@ -153,9 +159,11 @@ __all__ = [
|
|
|
153
159
|
"SecretMetadataResponse",
|
|
154
160
|
"SubmitJobResponse",
|
|
155
161
|
"TableInfo",
|
|
162
|
+
"TablePartitionKey",
|
|
156
163
|
"TableProfileResponse",
|
|
157
164
|
"TableRefreshError",
|
|
158
165
|
"TableRefreshResult",
|
|
166
|
+
"TableSortKey",
|
|
159
167
|
"TemporalProfileDetail",
|
|
160
168
|
"TextProfileDetail",
|
|
161
169
|
"UpdateEmbeddingProviderRequest",
|
|
@@ -163,8 +171,6 @@ __all__ = [
|
|
|
163
171
|
"UpdateSavedQueryRequest",
|
|
164
172
|
"UpdateSecretRequest",
|
|
165
173
|
"UpdateSecretResponse",
|
|
166
|
-
"UploadInfo",
|
|
167
|
-
"UploadResponse",
|
|
168
174
|
"UploadSessionResponse",
|
|
169
175
|
"UpsertDatabaseContextRequest",
|
|
170
176
|
"UpsertDatabaseContextResponse",
|
|
@@ -214,8 +220,11 @@ from hotdata.models.attach_database_catalog_request import AttachDatabaseCatalog
|
|
|
214
220
|
from hotdata.models.batch_create_upload_request import BatchCreateUploadRequest as BatchCreateUploadRequest
|
|
215
221
|
from hotdata.models.batch_create_upload_response import BatchCreateUploadResponse as BatchCreateUploadResponse
|
|
216
222
|
from hotdata.models.boolean_profile_detail import BooleanProfileDetail as BooleanProfileDetail
|
|
223
|
+
from hotdata.models.bulk_create_databases_request import BulkCreateDatabasesRequest as BulkCreateDatabasesRequest
|
|
224
|
+
from hotdata.models.bulk_create_databases_result import BulkCreateDatabasesResult as BulkCreateDatabasesResult
|
|
217
225
|
from hotdata.models.categorical_profile_detail import CategoricalProfileDetail as CategoricalProfileDetail
|
|
218
226
|
from hotdata.models.category_value_info import CategoryValueInfo as CategoryValueInfo
|
|
227
|
+
from hotdata.models.column_definition import ColumnDefinition as ColumnDefinition
|
|
219
228
|
from hotdata.models.column_info import ColumnInfo as ColumnInfo
|
|
220
229
|
from hotdata.models.column_profile_detail import ColumnProfileDetail as ColumnProfileDetail
|
|
221
230
|
from hotdata.models.column_profile_detail_one_of import ColumnProfileDetailOneOf as ColumnProfileDetailOneOf
|
|
@@ -224,6 +233,7 @@ from hotdata.models.column_profile_detail_one_of2 import ColumnProfileDetailOneO
|
|
|
224
233
|
from hotdata.models.column_profile_detail_one_of3 import ColumnProfileDetailOneOf3 as ColumnProfileDetailOneOf3
|
|
225
234
|
from hotdata.models.column_profile_detail_one_of4 import ColumnProfileDetailOneOf4 as ColumnProfileDetailOneOf4
|
|
226
235
|
from hotdata.models.column_profile_info import ColumnProfileInfo as ColumnProfileInfo
|
|
236
|
+
from hotdata.models.column_type_spec import ColumnTypeSpec as ColumnTypeSpec
|
|
227
237
|
from hotdata.models.connection_health_response import ConnectionHealthResponse as ConnectionHealthResponse
|
|
228
238
|
from hotdata.models.connection_info import ConnectionInfo as ConnectionInfo
|
|
229
239
|
from hotdata.models.connection_refresh_result import ConnectionRefreshResult as ConnectionRefreshResult
|
|
@@ -244,11 +254,14 @@ from hotdata.models.create_upload_request import CreateUploadRequest as CreateUp
|
|
|
244
254
|
from hotdata.models.create_workspace_request import CreateWorkspaceRequest as CreateWorkspaceRequest
|
|
245
255
|
from hotdata.models.create_workspace_response import CreateWorkspaceResponse as CreateWorkspaceResponse
|
|
246
256
|
from hotdata.models.database_attachment_info import DatabaseAttachmentInfo as DatabaseAttachmentInfo
|
|
257
|
+
from hotdata.models.database_batch_response import DatabaseBatchResponse as DatabaseBatchResponse
|
|
247
258
|
from hotdata.models.database_context_entry import DatabaseContextEntry as DatabaseContextEntry
|
|
259
|
+
from hotdata.models.database_count_response import DatabaseCountResponse as DatabaseCountResponse
|
|
248
260
|
from hotdata.models.database_default_schema_decl import DatabaseDefaultSchemaDecl as DatabaseDefaultSchemaDecl
|
|
249
261
|
from hotdata.models.database_default_table_decl import DatabaseDefaultTableDecl as DatabaseDefaultTableDecl
|
|
250
262
|
from hotdata.models.database_detail_response import DatabaseDetailResponse as DatabaseDetailResponse
|
|
251
263
|
from hotdata.models.database_summary import DatabaseSummary as DatabaseSummary
|
|
264
|
+
from hotdata.models.delete_database_batch_response import DeleteDatabaseBatchResponse as DeleteDatabaseBatchResponse
|
|
252
265
|
from hotdata.models.discovery_status import DiscoveryStatus as DiscoveryStatus
|
|
253
266
|
from hotdata.models.embedding_provider_response import EmbeddingProviderResponse as EmbeddingProviderResponse
|
|
254
267
|
from hotdata.models.error import Error as Error
|
|
@@ -282,7 +295,6 @@ from hotdata.models.list_results_response import ListResultsResponse as ListResu
|
|
|
282
295
|
from hotdata.models.list_saved_queries_response import ListSavedQueriesResponse as ListSavedQueriesResponse
|
|
283
296
|
from hotdata.models.list_saved_query_versions_response import ListSavedQueryVersionsResponse as ListSavedQueryVersionsResponse
|
|
284
297
|
from hotdata.models.list_secrets_response import ListSecretsResponse as ListSecretsResponse
|
|
285
|
-
from hotdata.models.list_uploads_response import ListUploadsResponse as ListUploadsResponse
|
|
286
298
|
from hotdata.models.list_workspaces_response import ListWorkspacesResponse as ListWorkspacesResponse
|
|
287
299
|
from hotdata.models.load_managed_table_request import LoadManagedTableRequest as LoadManagedTableRequest
|
|
288
300
|
from hotdata.models.load_managed_table_response import LoadManagedTableResponse as LoadManagedTableResponse
|
|
@@ -307,9 +319,11 @@ from hotdata.models.schema_refresh_result import SchemaRefreshResult as SchemaRe
|
|
|
307
319
|
from hotdata.models.secret_metadata_response import SecretMetadataResponse as SecretMetadataResponse
|
|
308
320
|
from hotdata.models.submit_job_response import SubmitJobResponse as SubmitJobResponse
|
|
309
321
|
from hotdata.models.table_info import TableInfo as TableInfo
|
|
322
|
+
from hotdata.models.table_partition_key import TablePartitionKey as TablePartitionKey
|
|
310
323
|
from hotdata.models.table_profile_response import TableProfileResponse as TableProfileResponse
|
|
311
324
|
from hotdata.models.table_refresh_error import TableRefreshError as TableRefreshError
|
|
312
325
|
from hotdata.models.table_refresh_result import TableRefreshResult as TableRefreshResult
|
|
326
|
+
from hotdata.models.table_sort_key import TableSortKey as TableSortKey
|
|
313
327
|
from hotdata.models.temporal_profile_detail import TemporalProfileDetail as TemporalProfileDetail
|
|
314
328
|
from hotdata.models.text_profile_detail import TextProfileDetail as TextProfileDetail
|
|
315
329
|
from hotdata.models.update_embedding_provider_request import UpdateEmbeddingProviderRequest as UpdateEmbeddingProviderRequest
|
|
@@ -317,8 +331,6 @@ from hotdata.models.update_embedding_provider_response import UpdateEmbeddingPro
|
|
|
317
331
|
from hotdata.models.update_saved_query_request import UpdateSavedQueryRequest as UpdateSavedQueryRequest
|
|
318
332
|
from hotdata.models.update_secret_request import UpdateSecretRequest as UpdateSecretRequest
|
|
319
333
|
from hotdata.models.update_secret_response import UpdateSecretResponse as UpdateSecretResponse
|
|
320
|
-
from hotdata.models.upload_info import UploadInfo as UploadInfo
|
|
321
|
-
from hotdata.models.upload_response import UploadResponse as UploadResponse
|
|
322
334
|
from hotdata.models.upload_session_response import UploadSessionResponse as UploadSessionResponse
|
|
323
335
|
from hotdata.models.upsert_database_context_request import UpsertDatabaseContextRequest as UpsertDatabaseContextRequest
|
|
324
336
|
from hotdata.models.upsert_database_context_response import UpsertDatabaseContextResponse as UpsertDatabaseContextResponse
|
|
@@ -39,6 +39,7 @@ Key behaviors:
|
|
|
39
39
|
endpoint fails fast instead of hanging every call.
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
+
import base64
|
|
42
43
|
import json
|
|
43
44
|
import os
|
|
44
45
|
import random
|
|
@@ -81,6 +82,32 @@ class TokenExchangeError(Exception):
|
|
|
81
82
|
"""
|
|
82
83
|
|
|
83
84
|
|
|
85
|
+
def _exp_from_jwt(token):
|
|
86
|
+
"""The `exp` claim of a compact JWT, as a UNIX timestamp, or None.
|
|
87
|
+
|
|
88
|
+
The claim is AUTHORITATIVE where `expires_in` is only a promise. A mint
|
|
89
|
+
endpoint that replays a cached token is required by RFC 6749 s4.2.2 to
|
|
90
|
+
report the REMAINING lifetime ("the value 3600 denotes that the access token
|
|
91
|
+
will expire in one hour from the time the response was generated"); one that
|
|
92
|
+
reports the original TTL instead hands back a token with seconds of life
|
|
93
|
+
stamped as good for minutes. Reading the claim costs a base64 decode and
|
|
94
|
+
removes the need to trust that.
|
|
95
|
+
|
|
96
|
+
Deliberately does NOT verify the signature: this is the SDK reading a token
|
|
97
|
+
it was just handed, to decide when to refresh it. Whether the token is
|
|
98
|
+
genuine is the server's call on the next request, and a forged `exp` can
|
|
99
|
+
only make this client refresh sooner. Any malformed token returns None and
|
|
100
|
+
the caller falls back to `expires_in`.
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
payload = token.split(".")[1]
|
|
104
|
+
payload += "=" * (-len(payload) % 4)
|
|
105
|
+
exp = json.loads(base64.urlsafe_b64decode(payload)).get("exp")
|
|
106
|
+
return float(exp) if exp is not None else None
|
|
107
|
+
except Exception: # noqa: BLE001 -- any malformed token falls back
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
|
|
84
111
|
def _is_socks_proxy_url(url):
|
|
85
112
|
# Mirror hotdata/rest.py.is_socks_proxy_url so the exchange pool routes
|
|
86
113
|
# SOCKS proxies the same way the generated REST client does.
|
|
@@ -184,6 +211,13 @@ class _TokenManager:
|
|
|
184
211
|
self._jwt = None
|
|
185
212
|
self._exp = 0.0
|
|
186
213
|
self._refresh = None
|
|
214
|
+
# The token this manager last served before it was invalidated. Lets a
|
|
215
|
+
# request that carried it be told apart from one carrying a credential
|
|
216
|
+
# this manager never issued -- see `ApiClient._remint_bearer`.
|
|
217
|
+
self._prev_jwt = None
|
|
218
|
+
# True when the last mint handed back the token we already held, i.e. the
|
|
219
|
+
# server has nothing newer to give. See `_refresh_margin`.
|
|
220
|
+
self._replayed = False
|
|
187
221
|
|
|
188
222
|
@property
|
|
189
223
|
def _needs_exchange(self):
|
|
@@ -217,12 +251,12 @@ class _TokenManager:
|
|
|
217
251
|
# under the lock, and the _LEEWAY margin keeps a token read here valid on
|
|
218
252
|
# the wire even if it is about to be rotated.
|
|
219
253
|
jwt = self._jwt
|
|
220
|
-
if jwt and time.time() < self._exp -
|
|
254
|
+
if jwt and time.time() < self._exp - self._refresh_margin():
|
|
221
255
|
return jwt
|
|
222
256
|
with self._lock:
|
|
223
257
|
# Re-check under the lock: another thread may have minted a fresh JWT
|
|
224
258
|
# while we waited (double-checked locking).
|
|
225
|
-
if self._jwt and time.time() < self._exp -
|
|
259
|
+
if self._jwt and time.time() < self._exp - self._refresh_margin():
|
|
226
260
|
return self._jwt
|
|
227
261
|
# Prefer the refresh token; on failure, drop it and re-mint below.
|
|
228
262
|
if self._refresh and not self._mint(
|
|
@@ -230,10 +264,63 @@ class _TokenManager:
|
|
|
230
264
|
):
|
|
231
265
|
self._refresh = None # refresh failed -> fall through to re-mint
|
|
232
266
|
# Re-mint from the held API token if we still lack a fresh JWT.
|
|
233
|
-
if not self._jwt or time.time() >= self._exp -
|
|
267
|
+
if not self._jwt or time.time() >= self._exp - self._refresh_margin():
|
|
234
268
|
self._mint({"grant_type": "api_token", "api_token": self._credential})
|
|
235
269
|
return self._jwt
|
|
236
270
|
|
|
271
|
+
def _refresh_margin(self):
|
|
272
|
+
"""How early to refresh: `_LEEWAY`, or nothing once the server replays.
|
|
273
|
+
|
|
274
|
+
The leeway exists to rotate a token before it dies. That only helps if a
|
|
275
|
+
mint can produce something newer -- and a server that replays a cached
|
|
276
|
+
token has just demonstrated it cannot. Refreshing anyway costs two token
|
|
277
|
+
endpoint round trips per request (the refresh grant returns the same
|
|
278
|
+
token, so `_refresh` survives and the api_token grant runs too), taken
|
|
279
|
+
under the lock, for the whole leeway window of every cycle.
|
|
280
|
+
|
|
281
|
+
Reading the honest `exp` is what exposes this: the inflated
|
|
282
|
+
`now + expires_in` never entered the window at all, because it had
|
|
283
|
+
already sailed past the real expiry -- a dead token instead of a slow
|
|
284
|
+
one. Dropping the margin for a replayed token keeps the honest expiry
|
|
285
|
+
without paying for advice the server has said it does not have, and the
|
|
286
|
+
401 retry remains the backstop for when the token really does die.
|
|
287
|
+
|
|
288
|
+
Clock skew is NOT handled here -- this margin only ever suppresses the
|
|
289
|
+
window `(_exp - _LEEWAY, _exp)`, and a skewed client's `_exp` is already
|
|
290
|
+
behind `now`, so nothing is left to suppress. `_mint` handles that case by
|
|
291
|
+
declining a claim that has already elapsed.
|
|
292
|
+
"""
|
|
293
|
+
return 0 if self._replayed else _LEEWAY
|
|
294
|
+
|
|
295
|
+
def invalidate(self, only_if=None):
|
|
296
|
+
"""Drop the cached JWT so the next `bearer_value()` mints a fresh one.
|
|
297
|
+
|
|
298
|
+
For the ONE case the proactive `_exp` check cannot cover: the server
|
|
299
|
+
rejected a token this client still believed in. Clears the refresh token
|
|
300
|
+
too -- a refresh is exactly what would hand back the same replayed JWT
|
|
301
|
+
that was just refused, so the next mint must go to the API token.
|
|
302
|
+
|
|
303
|
+
`only_if` makes it a COMPARE-AND-CLEAR, which is what keeps concurrent
|
|
304
|
+
401s from fighting. Several in-flight requests can carry the same doomed
|
|
305
|
+
token and 401 together; without the guard the second one clears the fresh
|
|
306
|
+
JWT the first just minted, and they take turns invalidating each other's
|
|
307
|
+
work. Passing the token that actually failed means a thread only clears
|
|
308
|
+
the state it observed.
|
|
309
|
+
|
|
310
|
+
Returns True when it cleared, False when another thread had already
|
|
311
|
+
replaced the token -- in which case the caller should use that one rather
|
|
312
|
+
than mint again.
|
|
313
|
+
"""
|
|
314
|
+
with self._lock:
|
|
315
|
+
if only_if is not None and self._jwt != only_if:
|
|
316
|
+
return False
|
|
317
|
+
self._prev_jwt = self._jwt
|
|
318
|
+
self._replayed = False
|
|
319
|
+
self._jwt = None
|
|
320
|
+
self._exp = 0.0
|
|
321
|
+
self._refresh = None
|
|
322
|
+
return True
|
|
323
|
+
|
|
237
324
|
def _mint(self, params):
|
|
238
325
|
# Returns True on success. The refresh path is best-effort: ANY failure
|
|
239
326
|
# -- a non-200, a transport error, or a malformed/missing-token body --
|
|
@@ -259,8 +346,55 @@ class _TokenManager:
|
|
|
259
346
|
if isinstance(exc, TokenExchangeError):
|
|
260
347
|
raise
|
|
261
348
|
raise TokenExchangeError(f"token exchange failed: {exc!r}") from exc
|
|
349
|
+
# A mint that returns the token we already hold is the server saying it
|
|
350
|
+
# has nothing newer; `_refresh_margin` stops asking again until this one
|
|
351
|
+
# has actually expired.
|
|
352
|
+
self._replayed = token == self._jwt
|
|
262
353
|
self._jwt = token
|
|
263
|
-
|
|
354
|
+
# The JWT's own `exp` WINS when it is sooner than what `expires_in`
|
|
355
|
+
# promises. A mint that replays a cached token while still reporting the
|
|
356
|
+
# full TTL would otherwise push `_exp` past the token's real expiry, and
|
|
357
|
+
# each refresh pushes it further -- so the proactive `_exp - _LEEWAY`
|
|
358
|
+
# check never fires and an expired token goes on the wire. Observed in
|
|
359
|
+
# production: four consecutive mints returned the same `jti` with
|
|
360
|
+
# `expires_in=300` each time, while the token's true remaining life fell
|
|
361
|
+
# 300s -> 289s. Any load running longer than one token lifetime then
|
|
362
|
+
# fails at whatever it happens to be doing when the token dies.
|
|
363
|
+
#
|
|
364
|
+
# `min`, not "prefer the claim": a claim FURTHER out than `expires_in`
|
|
365
|
+
# would extend the client's trust past what the server offered, which is
|
|
366
|
+
# the opposite of the guarantee wanted here.
|
|
367
|
+
now = time.time()
|
|
368
|
+
by_expires_in = now + expires_in
|
|
369
|
+
claim = _exp_from_jwt(token)
|
|
370
|
+
if claim is not None and (claim > now or self._replayed):
|
|
371
|
+
self._exp = min(by_expires_in, claim)
|
|
372
|
+
else:
|
|
373
|
+
# No readable claim, or one already elapsed on a token we had NOT seen
|
|
374
|
+
# before. Two causes produce an elapsed claim and they want opposite
|
|
375
|
+
# answers, so `_replayed` -- set just above -- separates them:
|
|
376
|
+
#
|
|
377
|
+
# replayed the server keeps handing back one cached token, and its
|
|
378
|
+
# `exp` has finally passed. The token really is dead.
|
|
379
|
+
# Honour the claim: this manager accepted the same claim as
|
|
380
|
+
# FUTURE on an earlier mint, so the clock is not the
|
|
381
|
+
# explanation, and pretending otherwise would put `_exp` at
|
|
382
|
+
# `now + 300` on a corpse -- the pre-fix behaviour, leaving
|
|
383
|
+
# the 401 retry to pay a round trip that a proactive mint
|
|
384
|
+
# would have avoided.
|
|
385
|
+
#
|
|
386
|
+
# first seen the clocks disagree. The server validates `exp` against
|
|
387
|
+
# its own clock, so the token is fine and only this client
|
|
388
|
+
# disbelieves it. Honouring the claim would pin `_exp` in
|
|
389
|
+
# the past and run both grants on every request forever.
|
|
390
|
+
# `expires_in` is always in the future, which is what makes
|
|
391
|
+
# it the safe fallback.
|
|
392
|
+
#
|
|
393
|
+
# A skewed clock AND a replaying server together fall to the first
|
|
394
|
+
# branch, i.e. back to both grants per request. That union is the case
|
|
395
|
+
# being traded away, knowingly: it is rarer than either alone and the
|
|
396
|
+
# 401 retry still covers it.
|
|
397
|
+
self._exp = by_expires_in
|
|
264
398
|
self._refresh = data.get("refresh_token") or self._refresh
|
|
265
399
|
return True
|
|
266
400
|
|
|
@@ -2601,9 +2601,9 @@ class ConnectionsApi:
|
|
|
2601
2601
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
2602
2602
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
2603
2603
|
) -> LoadManagedTableResponse:
|
|
2604
|
-
"""Load managed table from upload or query result
|
|
2604
|
+
"""Load managed table from inline data, upload, or query result
|
|
2605
2605
|
|
|
2606
|
-
Publish data as the new contents of a managed table from one of
|
|
2606
|
+
Publish data as the new contents of a managed table from one of three sources — provide exactly one. With `data`, CSV text is sent inline in this request, up to 2 MiB; column types are detected from the data unless `columns` declares them, and a larger payload is rejected with 413 and the error code `INLINE_DATA_TOO_LARGE`, at which point the data should be uploaded and loaded by `upload_id` instead. With `upload_id`, a previously-uploaded file is published: CSV, JSON, and Parquet are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. With `result_id`, a persisted query result is copied into the table, so the table keeps its data even after the result expires; a result can be loaded into any number of tables. If the target table (or its schema) has not been declared yet, it is created automatically as part of the load — declaring tables up front is optional. `mode` selects how the data is applied: `replace` overwrites the table's contents, `append` inserts the new rows on top of the existing data. Concurrent loads against the same upload return 409. For an upload or inline data, set `async` to run the load in the background and get back a job ID to poll; add `async_after_ms` to wait briefly for it to finish before falling back to a job ID. A `result_id` load runs synchronously.
|
|
2607
2607
|
|
|
2608
2608
|
:param connection_id: Connection ID (required)
|
|
2609
2609
|
:type connection_id: str
|
|
@@ -2652,6 +2652,7 @@ class ConnectionsApi:
|
|
|
2652
2652
|
'400': "ApiErrorResponse",
|
|
2653
2653
|
'404': "ApiErrorResponse",
|
|
2654
2654
|
'409': "ApiErrorResponse",
|
|
2655
|
+
'413': "ApiErrorResponse",
|
|
2655
2656
|
}
|
|
2656
2657
|
response_data = self.api_client.call_api(
|
|
2657
2658
|
*_param,
|
|
@@ -2684,9 +2685,9 @@ class ConnectionsApi:
|
|
|
2684
2685
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
2685
2686
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
2686
2687
|
) -> ApiResponse[LoadManagedTableResponse]:
|
|
2687
|
-
"""Load managed table from upload or query result
|
|
2688
|
+
"""Load managed table from inline data, upload, or query result
|
|
2688
2689
|
|
|
2689
|
-
Publish data as the new contents of a managed table from one of
|
|
2690
|
+
Publish data as the new contents of a managed table from one of three sources — provide exactly one. With `data`, CSV text is sent inline in this request, up to 2 MiB; column types are detected from the data unless `columns` declares them, and a larger payload is rejected with 413 and the error code `INLINE_DATA_TOO_LARGE`, at which point the data should be uploaded and loaded by `upload_id` instead. With `upload_id`, a previously-uploaded file is published: CSV, JSON, and Parquet are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. With `result_id`, a persisted query result is copied into the table, so the table keeps its data even after the result expires; a result can be loaded into any number of tables. If the target table (or its schema) has not been declared yet, it is created automatically as part of the load — declaring tables up front is optional. `mode` selects how the data is applied: `replace` overwrites the table's contents, `append` inserts the new rows on top of the existing data. Concurrent loads against the same upload return 409. For an upload or inline data, set `async` to run the load in the background and get back a job ID to poll; add `async_after_ms` to wait briefly for it to finish before falling back to a job ID. A `result_id` load runs synchronously.
|
|
2690
2691
|
|
|
2691
2692
|
:param connection_id: Connection ID (required)
|
|
2692
2693
|
:type connection_id: str
|
|
@@ -2735,6 +2736,7 @@ class ConnectionsApi:
|
|
|
2735
2736
|
'400': "ApiErrorResponse",
|
|
2736
2737
|
'404': "ApiErrorResponse",
|
|
2737
2738
|
'409': "ApiErrorResponse",
|
|
2739
|
+
'413': "ApiErrorResponse",
|
|
2738
2740
|
}
|
|
2739
2741
|
response_data = self.api_client.call_api(
|
|
2740
2742
|
*_param,
|
|
@@ -2767,9 +2769,9 @@ class ConnectionsApi:
|
|
|
2767
2769
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
2768
2770
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
2769
2771
|
) -> RESTResponseType:
|
|
2770
|
-
"""Load managed table from upload or query result
|
|
2772
|
+
"""Load managed table from inline data, upload, or query result
|
|
2771
2773
|
|
|
2772
|
-
Publish data as the new contents of a managed table from one of
|
|
2774
|
+
Publish data as the new contents of a managed table from one of three sources — provide exactly one. With `data`, CSV text is sent inline in this request, up to 2 MiB; column types are detected from the data unless `columns` declares them, and a larger payload is rejected with 413 and the error code `INLINE_DATA_TOO_LARGE`, at which point the data should be uploaded and loaded by `upload_id` instead. With `upload_id`, a previously-uploaded file is published: CSV, JSON, and Parquet are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. With `result_id`, a persisted query result is copied into the table, so the table keeps its data even after the result expires; a result can be loaded into any number of tables. If the target table (or its schema) has not been declared yet, it is created automatically as part of the load — declaring tables up front is optional. `mode` selects how the data is applied: `replace` overwrites the table's contents, `append` inserts the new rows on top of the existing data. Concurrent loads against the same upload return 409. For an upload or inline data, set `async` to run the load in the background and get back a job ID to poll; add `async_after_ms` to wait briefly for it to finish before falling back to a job ID. A `result_id` load runs synchronously.
|
|
2773
2775
|
|
|
2774
2776
|
:param connection_id: Connection ID (required)
|
|
2775
2777
|
:type connection_id: str
|
|
@@ -2818,6 +2820,7 @@ class ConnectionsApi:
|
|
|
2818
2820
|
'400': "ApiErrorResponse",
|
|
2819
2821
|
'404': "ApiErrorResponse",
|
|
2820
2822
|
'409': "ApiErrorResponse",
|
|
2823
|
+
'413': "ApiErrorResponse",
|
|
2821
2824
|
}
|
|
2822
2825
|
response_data = self.api_client.call_api(
|
|
2823
2826
|
*_param,
|