robosystems-client 0.2.15__py3-none-any.whl → 0.2.17__py3-none-any.whl
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.
Potentially problematic release.
This version of robosystems-client might be problematic. Click here for more details.
- robosystems_client/api/agent/auto_select_agent.py +23 -27
- robosystems_client/api/agent/batch_process_queries.py +13 -13
- robosystems_client/api/agent/execute_specific_agent.py +23 -27
- robosystems_client/api/agent/get_agent_metadata.py +13 -13
- robosystems_client/api/agent/list_agents.py +23 -23
- robosystems_client/api/agent/recommend_agent.py +13 -13
- robosystems_client/api/auth/check_password_strength.py +17 -17
- robosystems_client/api/auth/complete_sso_auth.py +17 -17
- robosystems_client/api/auth/forgot_password.py +17 -23
- robosystems_client/api/auth/generate_sso_token.py +26 -26
- robosystems_client/api/auth/get_captcha_config.py +6 -6
- robosystems_client/api/auth/get_current_auth_user.py +17 -17
- robosystems_client/api/auth/get_password_policy.py +10 -10
- robosystems_client/api/auth/login_user.py +17 -17
- robosystems_client/api/auth/logout_user.py +10 -10
- robosystems_client/api/auth/refresh_auth_session.py +17 -17
- robosystems_client/api/auth/register_user.py +17 -17
- robosystems_client/api/auth/resend_verification_email.py +17 -29
- robosystems_client/api/auth/reset_password.py +17 -17
- robosystems_client/api/auth/sso_token_exchange.py +17 -17
- robosystems_client/api/auth/validate_reset_token.py +17 -17
- robosystems_client/api/auth/verify_email.py +17 -17
- robosystems_client/api/backup/create_backup.py +13 -13
- robosystems_client/api/backup/get_backup_download_url.py +22 -22
- robosystems_client/api/backup/get_backup_stats.py +13 -13
- robosystems_client/api/backup/list_backups.py +31 -31
- robosystems_client/api/backup/restore_backup.py +13 -13
- robosystems_client/api/billing/cancel_org_subscription.py +13 -13
- robosystems_client/api/billing/create_checkout_session.py +13 -13
- robosystems_client/api/billing/create_portal_session.py +13 -13
- robosystems_client/api/billing/get_checkout_status.py +13 -13
- robosystems_client/api/billing/get_org_billing_customer.py +13 -13
- robosystems_client/api/billing/get_org_subscription.py +13 -13
- robosystems_client/api/billing/get_org_upcoming_invoice.py +16 -16
- robosystems_client/api/billing/list_org_invoices.py +22 -22
- robosystems_client/api/billing/list_org_subscriptions.py +13 -13
- robosystems_client/api/connections/create_connection.py +13 -13
- robosystems_client/api/connections/create_link_token.py +13 -13
- robosystems_client/api/connections/delete_connection.py +13 -13
- robosystems_client/api/connections/exchange_link_token.py +13 -13
- robosystems_client/api/connections/get_connection.py +13 -13
- robosystems_client/api/connections/get_connection_options.py +13 -13
- robosystems_client/api/connections/init_o_auth.py +13 -13
- robosystems_client/api/connections/list_connections.py +33 -33
- robosystems_client/api/connections/oauth_callback.py +13 -13
- robosystems_client/api/connections/sync_connection.py +13 -19
- robosystems_client/api/credits_/check_credit_balance.py +38 -45
- robosystems_client/api/credits_/check_storage_limits.py +13 -13
- robosystems_client/api/credits_/get_credit_summary.py +13 -13
- robosystems_client/api/credits_/get_storage_usage.py +28 -28
- robosystems_client/api/credits_/list_credit_transactions.py +71 -71
- robosystems_client/api/files/__init__.py +1 -0
- robosystems_client/api/files/create_file_upload.py +311 -0
- robosystems_client/api/files/delete_file.py +354 -0
- robosystems_client/api/files/get_file.py +329 -0
- robosystems_client/api/files/list_files.py +346 -0
- robosystems_client/api/files/update_file.py +320 -0
- robosystems_client/api/graph_health/get_database_health.py +13 -13
- robosystems_client/api/graph_info/get_database_info.py +13 -13
- robosystems_client/api/graph_limits/get_graph_limits.py +13 -13
- robosystems_client/api/graphs/create_graph.py +13 -13
- robosystems_client/api/graphs/get_available_extensions.py +13 -13
- robosystems_client/api/graphs/get_available_graph_tiers.py +22 -22
- robosystems_client/api/graphs/get_graphs.py +13 -13
- robosystems_client/api/graphs/select_graph.py +13 -13
- robosystems_client/api/materialization/__init__.py +1 -0
- robosystems_client/api/materialization/get_materialization_status.py +272 -0
- robosystems_client/api/materialization/materialize_graph.py +416 -0
- robosystems_client/api/mcp/call_mcp_tool.py +32 -32
- robosystems_client/api/mcp/list_mcp_tools.py +13 -13
- robosystems_client/api/operations/cancel_operation.py +13 -13
- robosystems_client/api/operations/get_operation_status.py +13 -25
- robosystems_client/api/operations/stream_operation_events.py +41 -41
- robosystems_client/api/org/create_org.py +13 -13
- robosystems_client/api/org/get_org.py +13 -13
- robosystems_client/api/org/list_org_graphs.py +13 -13
- robosystems_client/api/org/list_user_orgs.py +6 -6
- robosystems_client/api/org/update_org.py +13 -13
- robosystems_client/api/org_members/invite_org_member.py +13 -13
- robosystems_client/api/org_members/list_org_members.py +13 -13
- robosystems_client/api/org_members/remove_org_member.py +13 -13
- robosystems_client/api/org_members/update_org_member_role.py +13 -13
- robosystems_client/api/org_usage/get_org_limits.py +13 -13
- robosystems_client/api/org_usage/get_org_usage.py +22 -22
- robosystems_client/api/query/execute_cypher_query.py +74 -62
- robosystems_client/api/schema/export_graph_schema.py +35 -35
- robosystems_client/api/schema/get_graph_schema.py +13 -13
- robosystems_client/api/schema/validate_schema.py +13 -13
- robosystems_client/api/service_offerings/get_service_offerings.py +17 -17
- robosystems_client/api/status/get_service_status.py +10 -10
- robosystems_client/api/subgraphs/create_subgraph.py +64 -28
- robosystems_client/api/subgraphs/delete_subgraph.py +13 -13
- robosystems_client/api/subgraphs/get_subgraph_info.py +13 -13
- robosystems_client/api/subgraphs/get_subgraph_quota.py +13 -13
- robosystems_client/api/subgraphs/list_subgraphs.py +13 -13
- robosystems_client/api/subscriptions/create_repository_subscription.py +13 -13
- robosystems_client/api/subscriptions/get_graph_subscription.py +13 -13
- robosystems_client/api/subscriptions/upgrade_subscription.py +13 -13
- robosystems_client/api/tables/list_tables.py +13 -13
- robosystems_client/api/tables/query_tables.py +13 -13
- robosystems_client/api/usage/get_graph_metrics.py +13 -13
- robosystems_client/api/usage/get_graph_usage_analytics.py +66 -66
- robosystems_client/api/user/create_user_api_key.py +13 -13
- robosystems_client/api/user/get_current_user.py +6 -6
- robosystems_client/api/user/list_user_api_keys.py +6 -6
- robosystems_client/api/user/revoke_user_api_key.py +13 -13
- robosystems_client/api/user/update_user.py +13 -13
- robosystems_client/api/user/update_user_api_key.py +13 -13
- robosystems_client/api/user/update_user_password.py +13 -13
- robosystems_client/api/views/__init__.py +1 -0
- robosystems_client/api/views/create_view.py +245 -0
- robosystems_client/api/views/save_view.py +299 -0
- robosystems_client/client.py +13 -13
- robosystems_client/extensions/__init__.py +67 -10
- robosystems_client/extensions/element_mapping_client.py +585 -0
- robosystems_client/extensions/extensions.py +12 -3
- robosystems_client/extensions/file_client.py +380 -0
- robosystems_client/extensions/materialization_client.py +211 -0
- robosystems_client/extensions/subgraph_workspace_client.py +744 -0
- robosystems_client/extensions/table_client.py +161 -0
- robosystems_client/extensions/view_builder_client.py +617 -0
- robosystems_client/models/__init__.py +34 -10
- robosystems_client/models/account_info.py +2 -0
- robosystems_client/models/agent_list_response.py +3 -1
- robosystems_client/models/agent_list_response_agents.py +5 -3
- robosystems_client/models/agent_list_response_agents_additional_property.py +2 -0
- robosystems_client/models/agent_message.py +9 -7
- robosystems_client/models/agent_metadata_response.py +11 -9
- robosystems_client/models/agent_recommendation.py +8 -6
- robosystems_client/models/agent_recommendation_request.py +9 -7
- robosystems_client/models/agent_recommendation_request_context_type_0.py +2 -0
- robosystems_client/models/agent_recommendation_response.py +4 -2
- robosystems_client/models/agent_request.py +41 -40
- robosystems_client/models/agent_request_context_type_0.py +2 -0
- robosystems_client/models/agent_response.py +42 -44
- robosystems_client/models/agent_response_error_details_type_0.py +2 -0
- robosystems_client/models/agent_response_metadata_type_0.py +2 -0
- robosystems_client/models/agent_response_tokens_used_type_0.py +2 -0
- robosystems_client/models/api_key_info.py +18 -16
- robosystems_client/models/api_keys_response.py +4 -2
- robosystems_client/models/auth_response.py +26 -24
- robosystems_client/models/auth_response_org_type_0.py +2 -0
- robosystems_client/models/auth_response_user.py +2 -0
- robosystems_client/models/available_extension.py +5 -3
- robosystems_client/models/available_extensions_response.py +4 -2
- robosystems_client/models/available_graph_tiers_response.py +4 -2
- robosystems_client/models/backup_create_request.py +18 -16
- robosystems_client/models/backup_download_url_response.py +2 -0
- robosystems_client/models/backup_limits.py +2 -0
- robosystems_client/models/backup_list_response.py +4 -2
- robosystems_client/models/backup_response.py +13 -11
- robosystems_client/models/backup_restore_request.py +7 -6
- robosystems_client/models/backup_stats_response.py +9 -7
- robosystems_client/models/backup_stats_response_backup_formats.py +2 -0
- robosystems_client/models/batch_agent_request.py +7 -5
- robosystems_client/models/batch_agent_response.py +4 -2
- robosystems_client/models/billing_customer.py +10 -8
- robosystems_client/models/cancel_operation_response_canceloperation.py +2 -0
- robosystems_client/models/check_credit_balance_response_checkcreditbalance.py +2 -0
- robosystems_client/models/checkout_response.py +22 -20
- robosystems_client/models/checkout_status_response.py +19 -17
- robosystems_client/models/connection_options_response.py +4 -2
- robosystems_client/models/connection_provider_info.py +26 -24
- robosystems_client/models/connection_response.py +14 -12
- robosystems_client/models/connection_response_metadata.py +2 -0
- robosystems_client/models/copy_operation_limits.py +2 -0
- robosystems_client/models/create_api_key_request.py +13 -11
- robosystems_client/models/create_api_key_response.py +3 -1
- robosystems_client/models/create_checkout_request.py +3 -1
- robosystems_client/models/create_checkout_request_resource_config.py +2 -0
- robosystems_client/models/create_connection_request.py +21 -21
- robosystems_client/models/create_graph_request.py +25 -25
- robosystems_client/models/create_org_request.py +7 -5
- robosystems_client/models/create_repository_subscription_request.py +2 -0
- robosystems_client/models/create_subgraph_request.py +30 -19
- robosystems_client/models/create_subgraph_request_metadata_type_0.py +2 -0
- robosystems_client/models/create_view_request.py +141 -0
- robosystems_client/models/credit_limits.py +2 -0
- robosystems_client/models/credit_summary.py +3 -1
- robosystems_client/models/credit_summary_operation_breakdown.py +2 -0
- robosystems_client/models/credit_summary_response.py +8 -6
- robosystems_client/models/custom_schema_definition.py +39 -33
- robosystems_client/models/custom_schema_definition_metadata.py +2 -0
- robosystems_client/models/custom_schema_definition_nodes_item.py +2 -0
- robosystems_client/models/custom_schema_definition_relationships_item.py +2 -0
- robosystems_client/models/cypher_query_request.py +15 -13
- robosystems_client/models/cypher_query_request_parameters_type_0.py +2 -0
- robosystems_client/models/database_health_response.py +21 -19
- robosystems_client/models/database_info_response.py +13 -11
- robosystems_client/models/delete_file_response.py +54 -1
- robosystems_client/models/delete_subgraph_request.py +12 -10
- robosystems_client/models/delete_subgraph_response.py +13 -11
- robosystems_client/models/detailed_transactions_response.py +6 -4
- robosystems_client/models/detailed_transactions_response_date_range.py +2 -0
- robosystems_client/models/detailed_transactions_response_summary.py +5 -3
- robosystems_client/models/email_verification_request.py +2 -0
- robosystems_client/models/enhanced_credit_transaction_response.py +24 -22
- robosystems_client/models/enhanced_credit_transaction_response_metadata.py +2 -0
- robosystems_client/models/enhanced_file_status_layers.py +83 -0
- robosystems_client/models/error_response.py +19 -17
- robosystems_client/models/exchange_token_request.py +9 -7
- robosystems_client/models/exchange_token_request_metadata_type_0.py +2 -0
- robosystems_client/models/execute_cypher_query_response_200.py +25 -21
- robosystems_client/models/execute_cypher_query_response_200_data_item.py +2 -0
- robosystems_client/models/fact_detail.py +109 -0
- robosystems_client/models/file_info.py +18 -16
- robosystems_client/models/file_layer_status.py +123 -0
- robosystems_client/models/file_status_update.py +14 -0
- robosystems_client/models/file_upload_request.py +25 -3
- robosystems_client/models/file_upload_response.py +2 -0
- robosystems_client/models/forgot_password_request.py +2 -0
- robosystems_client/models/forgot_password_response_forgotpassword.py +2 -0
- robosystems_client/models/get_current_auth_user_response_getcurrentauthuser.py +2 -0
- robosystems_client/models/get_file_info_response.py +62 -21
- robosystems_client/models/get_operation_status_response_getoperationstatus.py +2 -0
- robosystems_client/models/get_storage_usage_response_getstorageusage.py +2 -0
- robosystems_client/models/graph_info.py +10 -8
- robosystems_client/models/graph_limits_response.py +14 -12
- robosystems_client/models/graph_metadata.py +14 -12
- robosystems_client/models/graph_metrics_response.py +17 -15
- robosystems_client/models/graph_metrics_response_estimated_size.py +2 -0
- robosystems_client/models/graph_metrics_response_health_status.py +2 -0
- robosystems_client/models/graph_metrics_response_node_counts.py +2 -0
- robosystems_client/models/graph_metrics_response_relationship_counts.py +2 -0
- robosystems_client/models/graph_subscription_response.py +28 -26
- robosystems_client/models/graph_subscription_tier.py +15 -13
- robosystems_client/models/graph_subscriptions.py +5 -3
- robosystems_client/models/graph_tier_backup.py +2 -0
- robosystems_client/models/graph_tier_copy_operations.py +2 -0
- robosystems_client/models/graph_tier_info.py +15 -13
- robosystems_client/models/graph_tier_instance.py +2 -0
- robosystems_client/models/graph_tier_limits.py +10 -8
- robosystems_client/models/graph_usage_response.py +32 -30
- robosystems_client/models/graph_usage_response_recent_events_item.py +2 -0
- robosystems_client/models/health_status.py +9 -7
- robosystems_client/models/health_status_details_type_0.py +2 -0
- robosystems_client/models/http_validation_error.py +12 -8
- robosystems_client/models/initial_entity_data.py +38 -36
- robosystems_client/models/invite_member_request.py +9 -7
- robosystems_client/models/invoice.py +35 -33
- robosystems_client/models/invoice_line_item.py +13 -11
- robosystems_client/models/invoices_response.py +4 -2
- robosystems_client/models/link_token_request.py +21 -23
- robosystems_client/models/link_token_request_options_type_0.py +2 -0
- robosystems_client/models/list_org_graphs_response_200_item.py +2 -0
- robosystems_client/models/list_subgraphs_response.py +15 -13
- robosystems_client/models/list_table_files_response.py +27 -11
- robosystems_client/models/login_request.py +2 -0
- robosystems_client/models/logout_user_response_logoutuser.py +2 -0
- robosystems_client/models/{bulk_ingest_request.py → materialize_request.py} +25 -15
- robosystems_client/models/materialize_response.py +131 -0
- robosystems_client/models/materialize_status_response.py +172 -0
- robosystems_client/models/mcp_tool_call.py +7 -5
- robosystems_client/models/mcp_tool_call_arguments.py +2 -0
- robosystems_client/models/mcp_tools_response.py +4 -2
- robosystems_client/models/mcp_tools_response_tools_item.py +2 -0
- robosystems_client/models/o_auth_callback_request.py +18 -16
- robosystems_client/models/o_auth_init_request.py +14 -12
- robosystems_client/models/o_auth_init_request_additional_params_type_0.py +2 -0
- robosystems_client/models/o_auth_init_response.py +2 -0
- robosystems_client/models/offering_repository_plan.py +9 -7
- robosystems_client/models/offering_repository_plan_rate_limits_type_0.py +8 -8
- robosystems_client/models/operation_costs.py +4 -2
- robosystems_client/models/operation_costs_ai_operations.py +2 -0
- robosystems_client/models/operation_costs_token_pricing.py +5 -3
- robosystems_client/models/org_detail_response.py +13 -11
- robosystems_client/models/org_detail_response_graphs_item.py +2 -0
- robosystems_client/models/org_detail_response_limits_type_0.py +2 -0
- robosystems_client/models/org_detail_response_members_item.py +2 -0
- robosystems_client/models/org_limits_response.py +3 -1
- robosystems_client/models/org_limits_response_current_usage.py +2 -0
- robosystems_client/models/org_list_response.py +4 -2
- robosystems_client/models/org_member_list_response.py +4 -2
- robosystems_client/models/org_member_response.py +2 -0
- robosystems_client/models/org_response.py +2 -0
- robosystems_client/models/org_usage_response.py +7 -5
- robosystems_client/models/org_usage_response_daily_trend_item.py +2 -0
- robosystems_client/models/org_usage_response_graph_details_item.py +2 -0
- robosystems_client/models/org_usage_summary.py +18 -16
- robosystems_client/models/password_check_request.py +8 -6
- robosystems_client/models/password_check_response.py +3 -1
- robosystems_client/models/password_check_response_character_types.py +2 -0
- robosystems_client/models/password_policy_response.py +3 -1
- robosystems_client/models/password_policy_response_policy.py +2 -0
- robosystems_client/models/payment_method.py +23 -21
- robosystems_client/models/performance_insights.py +5 -3
- robosystems_client/models/performance_insights_operation_stats.py +2 -0
- robosystems_client/models/performance_insights_slow_queries_item.py +2 -0
- robosystems_client/models/plaid_connection_config.py +30 -30
- robosystems_client/models/plaid_connection_config_accounts_type_0_item.py +2 -0
- robosystems_client/models/plaid_connection_config_institution_type_0.py +2 -0
- robosystems_client/models/portal_session_response.py +2 -0
- robosystems_client/models/query_limits.py +2 -0
- robosystems_client/models/quick_books_connection_config.py +13 -11
- robosystems_client/models/rate_limits.py +2 -0
- robosystems_client/models/register_request.py +8 -6
- robosystems_client/models/repository_info.py +4 -2
- robosystems_client/models/repository_subscriptions.py +4 -2
- robosystems_client/models/resend_verification_email_response_resendverificationemail.py +2 -0
- robosystems_client/models/reset_password_request.py +2 -0
- robosystems_client/models/reset_password_validate_response.py +8 -6
- robosystems_client/models/save_view_request.py +138 -0
- robosystems_client/models/save_view_response.py +181 -0
- robosystems_client/models/schema_export_response.py +16 -14
- robosystems_client/models/schema_export_response_data_stats_type_0.py +2 -0
- robosystems_client/models/schema_export_response_schema_definition_type_0.py +2 -0
- robosystems_client/models/schema_info_response.py +3 -1
- robosystems_client/models/schema_info_response_schema.py +2 -0
- robosystems_client/models/schema_validation_request.py +18 -17
- robosystems_client/models/schema_validation_request_schema_definition_type_0.py +2 -0
- robosystems_client/models/schema_validation_response.py +28 -33
- robosystems_client/models/schema_validation_response_compatibility_type_0.py +2 -0
- robosystems_client/models/schema_validation_response_stats_type_0.py +2 -0
- robosystems_client/models/sec_connection_config.py +8 -6
- robosystems_client/models/selection_criteria.py +19 -17
- robosystems_client/models/service_offering_summary.py +2 -0
- robosystems_client/models/service_offerings_response.py +6 -4
- robosystems_client/models/sso_complete_request.py +2 -0
- robosystems_client/models/sso_exchange_request.py +8 -6
- robosystems_client/models/sso_exchange_response.py +2 -0
- robosystems_client/models/sso_token_response.py +2 -0
- robosystems_client/models/storage_info.py +4 -2
- robosystems_client/models/storage_info_included_per_tier.py +2 -0
- robosystems_client/models/storage_info_overage_pricing.py +2 -0
- robosystems_client/models/storage_limit_response.py +9 -7
- robosystems_client/models/storage_limits.py +8 -6
- robosystems_client/models/storage_summary.py +2 -0
- robosystems_client/models/structure_detail.py +85 -0
- robosystems_client/models/subgraph_quota_response.py +23 -21
- robosystems_client/models/subgraph_response.py +35 -35
- robosystems_client/models/subgraph_response_metadata_type_0.py +2 -0
- robosystems_client/models/subgraph_summary.py +14 -12
- robosystems_client/models/success_response.py +11 -9
- robosystems_client/models/success_response_data_type_0.py +2 -0
- robosystems_client/models/sync_connection_request.py +11 -9
- robosystems_client/models/sync_connection_request_sync_options_type_0.py +2 -0
- robosystems_client/models/sync_connection_response_syncconnection.py +2 -0
- robosystems_client/models/table_info.py +12 -10
- robosystems_client/models/table_list_response.py +4 -2
- robosystems_client/models/table_query_request.py +9 -7
- robosystems_client/models/table_query_response.py +2 -0
- robosystems_client/models/token_pricing.py +2 -0
- robosystems_client/models/transaction_summary_response.py +13 -11
- robosystems_client/models/upcoming_invoice.py +10 -8
- robosystems_client/models/update_api_key_request.py +13 -11
- robosystems_client/models/{update_file_status_response_updatefilestatus.py → update_file_response_updatefile.py} +7 -5
- robosystems_client/models/update_member_role_request.py +2 -0
- robosystems_client/models/update_org_request.py +14 -12
- robosystems_client/models/update_password_request.py +2 -0
- robosystems_client/models/update_user_request.py +13 -11
- robosystems_client/models/upgrade_subscription_request.py +2 -0
- robosystems_client/models/user_graphs_response.py +10 -8
- robosystems_client/models/user_response.py +22 -18
- robosystems_client/models/validation_error.py +8 -6
- robosystems_client/models/view_axis_config.py +276 -0
- robosystems_client/models/view_axis_config_element_labels_type_0.py +46 -0
- robosystems_client/models/view_axis_config_member_labels_type_0.py +46 -0
- robosystems_client/models/view_config.py +127 -0
- robosystems_client/models/view_source.py +144 -0
- robosystems_client/models/view_source_type.py +9 -0
- robosystems_client/types.py +9 -9
- {robosystems_client-0.2.15.dist-info → robosystems_client-0.2.17.dist-info}/METADATA +1 -1
- robosystems_client-0.2.17.dist-info/RECORD +420 -0
- robosystems_client/api/tables/delete_file.py +0 -317
- robosystems_client/api/tables/get_file_info.py +0 -249
- robosystems_client/api/tables/get_upload_url.py +0 -380
- robosystems_client/api/tables/ingest_tables.py +0 -456
- robosystems_client/api/tables/list_table_files.py +0 -329
- robosystems_client/api/tables/update_file_status.py +0 -395
- robosystems_client/extensions/table_ingest_client.py +0 -462
- robosystems_client/models/bulk_ingest_response.py +0 -137
- robosystems_client/models/table_ingest_result.py +0 -107
- robosystems_client-0.2.15.dist-info/RECORD +0 -396
- {robosystems_client-0.2.15.dist-info → robosystems_client-0.2.17.dist-info}/WHEEL +0 -0
- {robosystems_client-0.2.15.dist-info → robosystems_client-0.2.17.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"""File Client for RoboSystems API
|
|
2
|
+
|
|
3
|
+
Manages file operations as first-class resources with multi-layer status tracking.
|
|
4
|
+
Files are independent entities with their own lifecycle (S3 → DuckDB → Graph).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from io import BytesIO
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, Any, Optional, Callable, Union, BinaryIO
|
|
11
|
+
import logging
|
|
12
|
+
import httpx
|
|
13
|
+
|
|
14
|
+
from ..api.files.create_file_upload import (
|
|
15
|
+
sync_detailed as create_file_upload,
|
|
16
|
+
)
|
|
17
|
+
from ..api.files.update_file import (
|
|
18
|
+
sync_detailed as update_file,
|
|
19
|
+
)
|
|
20
|
+
from ..api.files.list_files import (
|
|
21
|
+
sync_detailed as list_files,
|
|
22
|
+
)
|
|
23
|
+
from ..api.files.get_file import (
|
|
24
|
+
sync_detailed as get_file,
|
|
25
|
+
)
|
|
26
|
+
from ..api.files.delete_file import (
|
|
27
|
+
sync_detailed as delete_file,
|
|
28
|
+
)
|
|
29
|
+
from ..models.file_upload_request import FileUploadRequest
|
|
30
|
+
from ..models.file_status_update import FileStatusUpdate
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class FileUploadOptions:
|
|
37
|
+
"""Options for file upload operations"""
|
|
38
|
+
|
|
39
|
+
on_progress: Optional[Callable[[str], None]] = None
|
|
40
|
+
fix_localstack_url: bool = True
|
|
41
|
+
ingest_to_graph: bool = False
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class FileUploadResult:
|
|
46
|
+
"""Result from file upload operation"""
|
|
47
|
+
|
|
48
|
+
file_id: str
|
|
49
|
+
file_size: int
|
|
50
|
+
row_count: int
|
|
51
|
+
table_name: str
|
|
52
|
+
file_name: str
|
|
53
|
+
success: bool = True
|
|
54
|
+
error: Optional[str] = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class FileInfo:
|
|
59
|
+
"""Information about a file"""
|
|
60
|
+
|
|
61
|
+
file_id: str
|
|
62
|
+
file_name: str
|
|
63
|
+
file_format: str
|
|
64
|
+
size_bytes: int
|
|
65
|
+
row_count: Optional[int]
|
|
66
|
+
upload_status: str
|
|
67
|
+
table_name: str
|
|
68
|
+
created_at: Optional[str]
|
|
69
|
+
uploaded_at: Optional[str]
|
|
70
|
+
layers: Optional[Dict[str, Any]] = None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class FileClient:
|
|
74
|
+
"""Client for managing files as first-class resources"""
|
|
75
|
+
|
|
76
|
+
def __init__(self, config: Dict[str, Any]):
|
|
77
|
+
self.config = config
|
|
78
|
+
self.base_url = config["base_url"]
|
|
79
|
+
self.headers = config.get("headers", {})
|
|
80
|
+
self.token = config.get("token")
|
|
81
|
+
self._http_client = httpx.Client(timeout=120.0)
|
|
82
|
+
|
|
83
|
+
def upload(
|
|
84
|
+
self,
|
|
85
|
+
graph_id: str,
|
|
86
|
+
table_name: str,
|
|
87
|
+
file_or_buffer: Union[Path, str, BytesIO, BinaryIO],
|
|
88
|
+
options: Optional[FileUploadOptions] = None,
|
|
89
|
+
) -> FileUploadResult:
|
|
90
|
+
"""
|
|
91
|
+
Upload a file to a table.
|
|
92
|
+
|
|
93
|
+
This handles the complete 3-step upload process:
|
|
94
|
+
1. Get presigned upload URL
|
|
95
|
+
2. Upload file to S3
|
|
96
|
+
3. Mark file as 'uploaded' (triggers DuckDB staging)
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
graph_id: Graph database identifier
|
|
100
|
+
table_name: Table to associate file with
|
|
101
|
+
file_or_buffer: File path, Path object, BytesIO, or file-like object
|
|
102
|
+
options: Upload options (progress callback, LocalStack URL fix, auto-ingest)
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
FileUploadResult with file metadata and status
|
|
106
|
+
"""
|
|
107
|
+
options = options or FileUploadOptions()
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
# Determine file name and read content
|
|
111
|
+
if isinstance(file_or_buffer, (str, Path)):
|
|
112
|
+
file_path = Path(file_or_buffer)
|
|
113
|
+
file_name = file_path.name
|
|
114
|
+
with open(file_path, "rb") as f:
|
|
115
|
+
file_content = f.read()
|
|
116
|
+
elif isinstance(file_or_buffer, BytesIO):
|
|
117
|
+
file_name = "data.parquet"
|
|
118
|
+
file_content = file_or_buffer.getvalue()
|
|
119
|
+
elif hasattr(file_or_buffer, "read"):
|
|
120
|
+
file_name = getattr(file_or_buffer, "name", "data.parquet")
|
|
121
|
+
file_content = file_or_buffer.read()
|
|
122
|
+
else:
|
|
123
|
+
raise ValueError(f"Unsupported file type: {type(file_or_buffer)}")
|
|
124
|
+
|
|
125
|
+
# Step 1: Get presigned upload URL
|
|
126
|
+
if options.on_progress:
|
|
127
|
+
options.on_progress(
|
|
128
|
+
f"Getting upload URL for {file_name} → table '{table_name}'..."
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
upload_request = FileUploadRequest(
|
|
132
|
+
file_name=file_name,
|
|
133
|
+
content_type="application/x-parquet",
|
|
134
|
+
table_name=table_name,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
kwargs = {
|
|
138
|
+
"graph_id": graph_id,
|
|
139
|
+
"client": self.config.get("client"),
|
|
140
|
+
"body": upload_request,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
response = create_file_upload(**kwargs)
|
|
144
|
+
|
|
145
|
+
if response.status_code != 200 or not response.parsed:
|
|
146
|
+
error_msg = f"Failed to get upload URL: {response.status_code}"
|
|
147
|
+
return FileUploadResult(
|
|
148
|
+
file_id="",
|
|
149
|
+
file_size=0,
|
|
150
|
+
row_count=0,
|
|
151
|
+
table_name=table_name,
|
|
152
|
+
file_name=file_name,
|
|
153
|
+
success=False,
|
|
154
|
+
error=error_msg,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
upload_data = response.parsed
|
|
158
|
+
upload_url = upload_data.upload_url
|
|
159
|
+
file_id = upload_data.file_id
|
|
160
|
+
|
|
161
|
+
# Fix LocalStack URL if needed
|
|
162
|
+
if options.fix_localstack_url and "localstack:4566" in upload_url:
|
|
163
|
+
upload_url = upload_url.replace("localstack:4566", "localhost:4566")
|
|
164
|
+
|
|
165
|
+
# Step 2: Upload file to S3
|
|
166
|
+
if options.on_progress:
|
|
167
|
+
options.on_progress(f"Uploading {file_name} to S3...")
|
|
168
|
+
|
|
169
|
+
s3_response = self._http_client.put(
|
|
170
|
+
upload_url,
|
|
171
|
+
content=file_content,
|
|
172
|
+
headers={"Content-Type": "application/x-parquet"},
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
if s3_response.status_code not in [200, 204]:
|
|
176
|
+
return FileUploadResult(
|
|
177
|
+
file_id=file_id,
|
|
178
|
+
file_size=len(file_content),
|
|
179
|
+
row_count=0,
|
|
180
|
+
table_name=table_name,
|
|
181
|
+
file_name=file_name,
|
|
182
|
+
success=False,
|
|
183
|
+
error=f"S3 upload failed: {s3_response.status_code}",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Step 3: Mark file as uploaded
|
|
187
|
+
if options.on_progress:
|
|
188
|
+
options.on_progress(f"Marking {file_name} as uploaded...")
|
|
189
|
+
|
|
190
|
+
status_update = FileStatusUpdate(
|
|
191
|
+
status="uploaded",
|
|
192
|
+
ingest_to_graph=options.ingest_to_graph,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
update_kwargs = {
|
|
196
|
+
"graph_id": graph_id,
|
|
197
|
+
"file_id": file_id,
|
|
198
|
+
"client": self.config.get("client"),
|
|
199
|
+
"body": status_update,
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
update_response = update_file(**update_kwargs)
|
|
203
|
+
|
|
204
|
+
if update_response.status_code != 200 or not update_response.parsed:
|
|
205
|
+
return FileUploadResult(
|
|
206
|
+
file_id=file_id,
|
|
207
|
+
file_size=len(file_content),
|
|
208
|
+
row_count=0,
|
|
209
|
+
table_name=table_name,
|
|
210
|
+
file_name=file_name,
|
|
211
|
+
success=False,
|
|
212
|
+
error="Failed to complete file upload",
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# Extract metadata from response
|
|
216
|
+
response_data = update_response.parsed
|
|
217
|
+
actual_file_size = getattr(response_data, "file_size_bytes", len(file_content))
|
|
218
|
+
actual_row_count = getattr(response_data, "row_count", 0)
|
|
219
|
+
|
|
220
|
+
if options.on_progress:
|
|
221
|
+
options.on_progress(
|
|
222
|
+
f"✅ Uploaded {file_name} ({actual_file_size:,} bytes, {actual_row_count:,} rows)"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
return FileUploadResult(
|
|
226
|
+
file_id=file_id,
|
|
227
|
+
file_size=actual_file_size,
|
|
228
|
+
row_count=actual_row_count,
|
|
229
|
+
table_name=table_name,
|
|
230
|
+
file_name=file_name,
|
|
231
|
+
success=True,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
except Exception as e:
|
|
235
|
+
logger.error(f"File upload failed: {e}")
|
|
236
|
+
return FileUploadResult(
|
|
237
|
+
file_id="",
|
|
238
|
+
file_size=0,
|
|
239
|
+
row_count=0,
|
|
240
|
+
table_name=table_name,
|
|
241
|
+
file_name=getattr(file_or_buffer, "name", "unknown"),
|
|
242
|
+
success=False,
|
|
243
|
+
error=str(e),
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def list(
|
|
247
|
+
self,
|
|
248
|
+
graph_id: str,
|
|
249
|
+
table_name: Optional[str] = None,
|
|
250
|
+
status: Optional[str] = None,
|
|
251
|
+
) -> list[FileInfo]:
|
|
252
|
+
"""
|
|
253
|
+
List files in a graph with optional filtering.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
graph_id: Graph database identifier
|
|
257
|
+
table_name: Optional table name filter
|
|
258
|
+
status: Optional upload status filter (uploaded, pending, etc.)
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
List of FileInfo objects
|
|
262
|
+
"""
|
|
263
|
+
try:
|
|
264
|
+
kwargs = {
|
|
265
|
+
"graph_id": graph_id,
|
|
266
|
+
"client": self.config.get("client"),
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if table_name:
|
|
270
|
+
kwargs["table_name"] = table_name
|
|
271
|
+
if status:
|
|
272
|
+
kwargs["status"] = status
|
|
273
|
+
|
|
274
|
+
response = list_files(**kwargs)
|
|
275
|
+
|
|
276
|
+
if response.status_code != 200 or not response.parsed:
|
|
277
|
+
logger.error(f"Failed to list files: {response.status_code}")
|
|
278
|
+
return []
|
|
279
|
+
|
|
280
|
+
files_data = response.parsed
|
|
281
|
+
files = getattr(files_data, "files", [])
|
|
282
|
+
|
|
283
|
+
return [
|
|
284
|
+
FileInfo(
|
|
285
|
+
file_id=f.file_id,
|
|
286
|
+
file_name=f.file_name,
|
|
287
|
+
file_format=f.file_format,
|
|
288
|
+
size_bytes=f.size_bytes or 0,
|
|
289
|
+
row_count=f.row_count,
|
|
290
|
+
upload_status=f.upload_status,
|
|
291
|
+
table_name=getattr(f, "table_name", ""),
|
|
292
|
+
created_at=f.created_at,
|
|
293
|
+
uploaded_at=f.uploaded_at,
|
|
294
|
+
)
|
|
295
|
+
for f in files
|
|
296
|
+
]
|
|
297
|
+
|
|
298
|
+
except Exception as e:
|
|
299
|
+
logger.error(f"Failed to list files: {e}")
|
|
300
|
+
return []
|
|
301
|
+
|
|
302
|
+
def get(self, graph_id: str, file_id: str) -> Optional[FileInfo]:
|
|
303
|
+
"""
|
|
304
|
+
Get detailed information about a specific file.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
graph_id: Graph database identifier
|
|
308
|
+
file_id: File ID
|
|
309
|
+
|
|
310
|
+
Returns:
|
|
311
|
+
FileInfo with multi-layer status tracking, or None if not found
|
|
312
|
+
"""
|
|
313
|
+
try:
|
|
314
|
+
kwargs = {
|
|
315
|
+
"graph_id": graph_id,
|
|
316
|
+
"file_id": file_id,
|
|
317
|
+
"client": self.config.get("client"),
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
response = get_file(**kwargs)
|
|
321
|
+
|
|
322
|
+
if response.status_code != 200 or not response.parsed:
|
|
323
|
+
logger.error(f"Failed to get file {file_id}: {response.status_code}")
|
|
324
|
+
return None
|
|
325
|
+
|
|
326
|
+
file_data = response.parsed
|
|
327
|
+
|
|
328
|
+
return FileInfo(
|
|
329
|
+
file_id=file_data.file_id,
|
|
330
|
+
file_name=file_data.file_name,
|
|
331
|
+
file_format=file_data.file_format,
|
|
332
|
+
size_bytes=file_data.size_bytes or 0,
|
|
333
|
+
row_count=file_data.row_count,
|
|
334
|
+
upload_status=file_data.upload_status,
|
|
335
|
+
table_name=file_data.table_name or "",
|
|
336
|
+
created_at=file_data.created_at,
|
|
337
|
+
uploaded_at=file_data.uploaded_at,
|
|
338
|
+
layers=getattr(file_data, "layers", None),
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
except Exception as e:
|
|
342
|
+
logger.error(f"Failed to get file {file_id}: {e}")
|
|
343
|
+
return None
|
|
344
|
+
|
|
345
|
+
def delete(self, graph_id: str, file_id: str, cascade: bool = False) -> bool:
|
|
346
|
+
"""
|
|
347
|
+
Delete a file from all layers.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
graph_id: Graph database identifier
|
|
351
|
+
file_id: File ID to delete
|
|
352
|
+
cascade: If True, delete from all layers including DuckDB and graph
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
True if deletion succeeded, False otherwise
|
|
356
|
+
"""
|
|
357
|
+
try:
|
|
358
|
+
kwargs = {
|
|
359
|
+
"graph_id": graph_id,
|
|
360
|
+
"file_id": file_id,
|
|
361
|
+
"client": self.config.get("client"),
|
|
362
|
+
"cascade": cascade,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
response = delete_file(**kwargs)
|
|
366
|
+
|
|
367
|
+
if response.status_code not in [200, 204]:
|
|
368
|
+
logger.error(f"Failed to delete file {file_id}: {response.status_code}")
|
|
369
|
+
return False
|
|
370
|
+
|
|
371
|
+
return True
|
|
372
|
+
|
|
373
|
+
except Exception as e:
|
|
374
|
+
logger.error(f"Failed to delete file {file_id}: {e}")
|
|
375
|
+
return False
|
|
376
|
+
|
|
377
|
+
def __del__(self):
|
|
378
|
+
"""Cleanup HTTP client on deletion"""
|
|
379
|
+
if hasattr(self, "_http_client"):
|
|
380
|
+
self._http_client.close()
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""Materialization Client for RoboSystems API
|
|
2
|
+
|
|
3
|
+
Manages graph materialization from DuckDB staging tables.
|
|
4
|
+
Treats the graph database as a materialized view of the mutable DuckDB data lake.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Dict, Any, Optional, Callable
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from ..api.materialization.materialize_graph import (
|
|
12
|
+
sync_detailed as materialize_graph,
|
|
13
|
+
)
|
|
14
|
+
from ..api.materialization.get_materialization_status import (
|
|
15
|
+
sync_detailed as get_materialization_status,
|
|
16
|
+
)
|
|
17
|
+
from ..models.materialize_request import MaterializeRequest
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class MaterializationOptions:
|
|
24
|
+
"""Options for graph materialization operations"""
|
|
25
|
+
|
|
26
|
+
ignore_errors: bool = True
|
|
27
|
+
rebuild: bool = False
|
|
28
|
+
force: bool = False
|
|
29
|
+
on_progress: Optional[Callable[[str], None]] = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class MaterializationResult:
|
|
34
|
+
"""Result from materialization operation"""
|
|
35
|
+
|
|
36
|
+
status: str
|
|
37
|
+
was_stale: bool
|
|
38
|
+
stale_reason: Optional[str]
|
|
39
|
+
tables_materialized: list[str]
|
|
40
|
+
total_rows: int
|
|
41
|
+
execution_time_ms: float
|
|
42
|
+
message: str
|
|
43
|
+
success: bool = True
|
|
44
|
+
error: Optional[str] = None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class MaterializationStatus:
|
|
49
|
+
"""Status information about graph materialization"""
|
|
50
|
+
|
|
51
|
+
graph_id: str
|
|
52
|
+
is_stale: bool
|
|
53
|
+
stale_reason: Optional[str]
|
|
54
|
+
stale_since: Optional[str]
|
|
55
|
+
last_materialized_at: Optional[str]
|
|
56
|
+
materialization_count: int
|
|
57
|
+
hours_since_materialization: Optional[float]
|
|
58
|
+
message: str
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class MaterializationClient:
|
|
62
|
+
"""Client for managing graph materialization operations"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, config: Dict[str, Any]):
|
|
65
|
+
self.config = config
|
|
66
|
+
self.base_url = config["base_url"]
|
|
67
|
+
self.headers = config.get("headers", {})
|
|
68
|
+
self.token = config.get("token")
|
|
69
|
+
|
|
70
|
+
def materialize(
|
|
71
|
+
self,
|
|
72
|
+
graph_id: str,
|
|
73
|
+
options: Optional[MaterializationOptions] = None,
|
|
74
|
+
) -> MaterializationResult:
|
|
75
|
+
"""
|
|
76
|
+
Materialize graph from DuckDB staging tables.
|
|
77
|
+
|
|
78
|
+
Rebuilds the complete graph database from the current state of DuckDB
|
|
79
|
+
staging tables. Automatically discovers all tables, materializes them in
|
|
80
|
+
the correct order (nodes before relationships), and clears the staleness flag.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
graph_id: Graph database identifier
|
|
84
|
+
options: Materialization options (ignore_errors, rebuild, force)
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
MaterializationResult with detailed execution information
|
|
88
|
+
|
|
89
|
+
When to use:
|
|
90
|
+
- After batch uploads (files uploaded with ingest_to_graph=false)
|
|
91
|
+
- After cascade file deletions (graph marked stale)
|
|
92
|
+
- Periodic full refresh to ensure consistency
|
|
93
|
+
- Recovery from partial materialization failures
|
|
94
|
+
"""
|
|
95
|
+
options = options or MaterializationOptions()
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
if options.on_progress:
|
|
99
|
+
options.on_progress("Starting graph materialization...")
|
|
100
|
+
|
|
101
|
+
request = MaterializeRequest(
|
|
102
|
+
ignore_errors=options.ignore_errors,
|
|
103
|
+
rebuild=options.rebuild,
|
|
104
|
+
force=options.force,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
kwargs = {
|
|
108
|
+
"graph_id": graph_id,
|
|
109
|
+
"client": self.config.get("client"),
|
|
110
|
+
"body": request,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
response = materialize_graph(**kwargs)
|
|
114
|
+
|
|
115
|
+
if response.status_code != 200 or not response.parsed:
|
|
116
|
+
error_msg = f"Materialization failed: {response.status_code}"
|
|
117
|
+
if hasattr(response, "content"):
|
|
118
|
+
try:
|
|
119
|
+
import json
|
|
120
|
+
|
|
121
|
+
error_data = json.loads(response.content)
|
|
122
|
+
error_msg = error_data.get("detail", error_msg)
|
|
123
|
+
except Exception:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
return MaterializationResult(
|
|
127
|
+
status="failed",
|
|
128
|
+
was_stale=False,
|
|
129
|
+
stale_reason=None,
|
|
130
|
+
tables_materialized=[],
|
|
131
|
+
total_rows=0,
|
|
132
|
+
execution_time_ms=0,
|
|
133
|
+
message=error_msg,
|
|
134
|
+
success=False,
|
|
135
|
+
error=error_msg,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
result_data = response.parsed
|
|
139
|
+
|
|
140
|
+
if options.on_progress:
|
|
141
|
+
options.on_progress(
|
|
142
|
+
f"✅ Materialization complete: {len(result_data.tables_materialized)} tables, "
|
|
143
|
+
f"{result_data.total_rows:,} rows in {result_data.execution_time_ms:.2f}ms"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return MaterializationResult(
|
|
147
|
+
status=result_data.status,
|
|
148
|
+
was_stale=result_data.was_stale,
|
|
149
|
+
stale_reason=result_data.stale_reason,
|
|
150
|
+
tables_materialized=result_data.tables_materialized,
|
|
151
|
+
total_rows=result_data.total_rows,
|
|
152
|
+
execution_time_ms=result_data.execution_time_ms,
|
|
153
|
+
message=result_data.message,
|
|
154
|
+
success=True,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
except Exception as e:
|
|
158
|
+
logger.error(f"Materialization failed: {e}")
|
|
159
|
+
return MaterializationResult(
|
|
160
|
+
status="failed",
|
|
161
|
+
was_stale=False,
|
|
162
|
+
stale_reason=None,
|
|
163
|
+
tables_materialized=[],
|
|
164
|
+
total_rows=0,
|
|
165
|
+
execution_time_ms=0,
|
|
166
|
+
message=str(e),
|
|
167
|
+
success=False,
|
|
168
|
+
error=str(e),
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def status(self, graph_id: str) -> Optional[MaterializationStatus]:
|
|
172
|
+
"""
|
|
173
|
+
Get current materialization status for the graph.
|
|
174
|
+
|
|
175
|
+
Shows whether the graph is stale (DuckDB has changes not yet in graph database),
|
|
176
|
+
when it was last materialized, and how long since last materialization.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
graph_id: Graph database identifier
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
MaterializationStatus with staleness and timing information
|
|
183
|
+
"""
|
|
184
|
+
try:
|
|
185
|
+
kwargs = {
|
|
186
|
+
"graph_id": graph_id,
|
|
187
|
+
"client": self.config.get("client"),
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
response = get_materialization_status(**kwargs)
|
|
191
|
+
|
|
192
|
+
if response.status_code != 200 or not response.parsed:
|
|
193
|
+
logger.error(f"Failed to get materialization status: {response.status_code}")
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
status_data = response.parsed
|
|
197
|
+
|
|
198
|
+
return MaterializationStatus(
|
|
199
|
+
graph_id=status_data.graph_id,
|
|
200
|
+
is_stale=status_data.is_stale,
|
|
201
|
+
stale_reason=status_data.stale_reason,
|
|
202
|
+
stale_since=status_data.stale_since,
|
|
203
|
+
last_materialized_at=status_data.last_materialized_at,
|
|
204
|
+
materialization_count=status_data.materialization_count,
|
|
205
|
+
hours_since_materialization=status_data.hours_since_materialization,
|
|
206
|
+
message=status_data.message,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
logger.error(f"Failed to get materialization status: {e}")
|
|
211
|
+
return None
|