robosystems-client 0.2.15__py3-none-any.whl → 0.2.16__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 +39 -0
- robosystems_client/extensions/element_mapping_client.py +585 -0
- robosystems_client/extensions/subgraph_workspace_client.py +744 -0
- robosystems_client/extensions/table_ingest_client.py +24 -23
- 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.16.dist-info}/METADATA +1 -1
- robosystems_client-0.2.16.dist-info/RECORD +418 -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/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.16.dist-info}/WHEEL +0 -0
- {robosystems_client-0.2.15.dist-info → robosystems_client-0.2.16.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
"""Element Mapping Client Extension
|
|
2
|
+
|
|
3
|
+
Client-side extension for managing element mappings in subgraph workspaces.
|
|
4
|
+
Constructs Cypher queries for execution via the public /query endpoint.
|
|
5
|
+
|
|
6
|
+
This replaces server-side mapping endpoints with client-side logic,
|
|
7
|
+
following the architecture where mappings are written to subgraphs
|
|
8
|
+
and later published to the main graph via parquet export/ingest.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import uuid
|
|
12
|
+
from typing import List, Optional
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from enum import Enum
|
|
15
|
+
import pandas as pd
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AggregationMethod(Enum):
|
|
19
|
+
"""Aggregation methods for element mapping"""
|
|
20
|
+
|
|
21
|
+
SUM = "sum"
|
|
22
|
+
AVERAGE = "average"
|
|
23
|
+
WEIGHTED_AVERAGE = "weighted_average"
|
|
24
|
+
FIRST = "first"
|
|
25
|
+
LAST = "last"
|
|
26
|
+
CALCULATED = "calculated"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class MappingStructure:
|
|
31
|
+
"""Element mapping structure"""
|
|
32
|
+
|
|
33
|
+
identifier: str
|
|
34
|
+
name: str
|
|
35
|
+
description: Optional[str] = None
|
|
36
|
+
taxonomy_uri: Optional[str] = None
|
|
37
|
+
target_taxonomy_uri: Optional[str] = None
|
|
38
|
+
associations: Optional[List["ElementAssociation"]] = None
|
|
39
|
+
|
|
40
|
+
def __post_init__(self):
|
|
41
|
+
if self.associations is None:
|
|
42
|
+
self.associations = []
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class ElementAssociation:
|
|
47
|
+
"""Association between source and target elements"""
|
|
48
|
+
|
|
49
|
+
identifier: str
|
|
50
|
+
source_element: str
|
|
51
|
+
target_element: str
|
|
52
|
+
aggregation_method: AggregationMethod = AggregationMethod.SUM
|
|
53
|
+
weight: float = 1.0
|
|
54
|
+
formula: Optional[str] = None
|
|
55
|
+
order_value: float = 1.0
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ElementMappingClient:
|
|
59
|
+
"""
|
|
60
|
+
Client for managing element mappings in subgraph workspaces.
|
|
61
|
+
|
|
62
|
+
All operations construct Cypher queries that are executed via the
|
|
63
|
+
public /query endpoint against a subgraph workspace.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self, query_client):
|
|
67
|
+
"""
|
|
68
|
+
Initialize with a query client for executing Cypher.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
query_client: RoboSystemsExtensions query client
|
|
72
|
+
"""
|
|
73
|
+
self.query = query_client
|
|
74
|
+
|
|
75
|
+
def _generate_uuid(self, seed: str = None) -> str:
|
|
76
|
+
"""Generate a deterministic or random UUID"""
|
|
77
|
+
if seed:
|
|
78
|
+
# For deterministic UUID based on seed
|
|
79
|
+
import hashlib
|
|
80
|
+
|
|
81
|
+
hash_obj = hashlib.sha256(seed.encode())
|
|
82
|
+
hash_hex = hash_obj.hexdigest()
|
|
83
|
+
return f"{hash_hex[:8]}-{hash_hex[8:12]}-7{hash_hex[13:16]}-{hash_hex[16:20]}-{hash_hex[20:32]}"
|
|
84
|
+
else:
|
|
85
|
+
return str(uuid.uuid4())
|
|
86
|
+
|
|
87
|
+
async def create_mapping_structure(
|
|
88
|
+
self,
|
|
89
|
+
graph_id: str,
|
|
90
|
+
name: str,
|
|
91
|
+
description: str = None,
|
|
92
|
+
taxonomy_uri: str = None,
|
|
93
|
+
target_taxonomy_uri: str = None,
|
|
94
|
+
) -> MappingStructure:
|
|
95
|
+
"""
|
|
96
|
+
Create a new element mapping structure in the subgraph.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
graph_id: Subgraph workspace ID (e.g., kg123_workspace)
|
|
100
|
+
name: Name of the mapping structure
|
|
101
|
+
description: Optional description
|
|
102
|
+
taxonomy_uri: Source taxonomy URI (e.g., "qb:chart-of-accounts")
|
|
103
|
+
target_taxonomy_uri: Target taxonomy URI (e.g., "us-gaap:2024")
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Created MappingStructure
|
|
107
|
+
"""
|
|
108
|
+
structure_id = self._generate_uuid(f"mapping_structure_{name}_{graph_id}")
|
|
109
|
+
|
|
110
|
+
cypher = """
|
|
111
|
+
CREATE (s:Structure {
|
|
112
|
+
identifier: $identifier,
|
|
113
|
+
type: 'ElementMapping',
|
|
114
|
+
name: $name,
|
|
115
|
+
definition: $description,
|
|
116
|
+
uri: $uri,
|
|
117
|
+
network_uri: $network_uri
|
|
118
|
+
})
|
|
119
|
+
RETURN s
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
params = {
|
|
123
|
+
"identifier": structure_id,
|
|
124
|
+
"name": name,
|
|
125
|
+
"description": description or "",
|
|
126
|
+
"uri": taxonomy_uri or "",
|
|
127
|
+
"network_uri": target_taxonomy_uri or "",
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
self.query.query(graph_id, cypher, params)
|
|
131
|
+
|
|
132
|
+
return MappingStructure(
|
|
133
|
+
identifier=structure_id,
|
|
134
|
+
name=name,
|
|
135
|
+
description=description,
|
|
136
|
+
taxonomy_uri=taxonomy_uri,
|
|
137
|
+
target_taxonomy_uri=target_taxonomy_uri,
|
|
138
|
+
associations=[],
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
async def get_mapping_structure(
|
|
142
|
+
self, graph_id: str, structure_id: str
|
|
143
|
+
) -> Optional[MappingStructure]:
|
|
144
|
+
"""
|
|
145
|
+
Get a mapping structure with all its associations.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
graph_id: Subgraph workspace ID
|
|
149
|
+
structure_id: Structure identifier
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
MappingStructure with associations, or None if not found
|
|
153
|
+
"""
|
|
154
|
+
cypher = """
|
|
155
|
+
MATCH (s:Structure)
|
|
156
|
+
WHERE s.identifier = $structure_id AND s.type = 'ElementMapping'
|
|
157
|
+
OPTIONAL MATCH (s)-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association)
|
|
158
|
+
OPTIONAL MATCH (a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(from_el:Element)
|
|
159
|
+
OPTIONAL MATCH (a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(to_el:Element)
|
|
160
|
+
RETURN s,
|
|
161
|
+
collect({
|
|
162
|
+
identifier: a.identifier,
|
|
163
|
+
source_element: from_el.uri,
|
|
164
|
+
target_element: to_el.uri,
|
|
165
|
+
aggregation_method: a.preferred_label,
|
|
166
|
+
weight: a.weight,
|
|
167
|
+
order_value: a.order_value
|
|
168
|
+
}) as associations
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
result = self.query.query(graph_id, cypher, {"structure_id": structure_id})
|
|
172
|
+
|
|
173
|
+
if not result or not result.data:
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
row = result.data[0]
|
|
177
|
+
structure_data = row["s"]
|
|
178
|
+
|
|
179
|
+
associations = []
|
|
180
|
+
for assoc in row["associations"]:
|
|
181
|
+
if assoc["identifier"]:
|
|
182
|
+
associations.append(
|
|
183
|
+
ElementAssociation(
|
|
184
|
+
identifier=assoc["identifier"],
|
|
185
|
+
source_element=assoc["source_element"] or "",
|
|
186
|
+
target_element=assoc["target_element"] or "",
|
|
187
|
+
aggregation_method=AggregationMethod(assoc["aggregation_method"] or "sum"),
|
|
188
|
+
weight=assoc["weight"] or 1.0,
|
|
189
|
+
order_value=assoc["order_value"] or 1.0,
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
return MappingStructure(
|
|
194
|
+
identifier=structure_data["identifier"],
|
|
195
|
+
name=structure_data["name"],
|
|
196
|
+
description=structure_data.get("definition"),
|
|
197
|
+
taxonomy_uri=structure_data.get("uri"),
|
|
198
|
+
target_taxonomy_uri=structure_data.get("network_uri"),
|
|
199
|
+
associations=associations,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
async def list_mapping_structures(self, graph_id: str) -> List[MappingStructure]:
|
|
203
|
+
"""
|
|
204
|
+
List all mapping structures in the subgraph.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
graph_id: Subgraph workspace ID
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
List of MappingStructure objects
|
|
211
|
+
"""
|
|
212
|
+
cypher = """
|
|
213
|
+
MATCH (s:Structure)
|
|
214
|
+
WHERE s.type = 'ElementMapping'
|
|
215
|
+
OPTIONAL MATCH (s)-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association)
|
|
216
|
+
RETURN s,
|
|
217
|
+
count(a) as association_count
|
|
218
|
+
ORDER BY s.name
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
result = self.query.query(graph_id, cypher, {})
|
|
222
|
+
|
|
223
|
+
structures = []
|
|
224
|
+
if result and result.data:
|
|
225
|
+
for row in result.data:
|
|
226
|
+
structure_data = row["s"]
|
|
227
|
+
structures.append(
|
|
228
|
+
MappingStructure(
|
|
229
|
+
identifier=structure_data["identifier"],
|
|
230
|
+
name=structure_data["name"],
|
|
231
|
+
description=structure_data.get("definition"),
|
|
232
|
+
taxonomy_uri=structure_data.get("uri"),
|
|
233
|
+
target_taxonomy_uri=structure_data.get("network_uri"),
|
|
234
|
+
associations=[], # Not loading associations in list view
|
|
235
|
+
)
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
return structures
|
|
239
|
+
|
|
240
|
+
async def create_association(
|
|
241
|
+
self,
|
|
242
|
+
graph_id: str,
|
|
243
|
+
structure_id: str,
|
|
244
|
+
source_element: str,
|
|
245
|
+
target_element: str,
|
|
246
|
+
aggregation_method: AggregationMethod = AggregationMethod.SUM,
|
|
247
|
+
weight: float = 1.0,
|
|
248
|
+
order_value: float = 1.0,
|
|
249
|
+
) -> ElementAssociation:
|
|
250
|
+
"""
|
|
251
|
+
Add an association to a mapping structure.
|
|
252
|
+
|
|
253
|
+
Creates an Association node linking source element to target element.
|
|
254
|
+
If the target element doesn't exist, it will be created.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
graph_id: Subgraph workspace ID
|
|
258
|
+
structure_id: Structure identifier
|
|
259
|
+
source_element: Source element URI (e.g., "qb:BankAccount1")
|
|
260
|
+
target_element: Target element URI (e.g., "us-gaap:Cash")
|
|
261
|
+
aggregation_method: How to aggregate values
|
|
262
|
+
weight: Weight for weighted aggregation
|
|
263
|
+
order_value: Display order
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
Created ElementAssociation
|
|
267
|
+
"""
|
|
268
|
+
association_id = self._generate_uuid(
|
|
269
|
+
f"association_{structure_id}_{source_element}_{target_element}"
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Generate identifier for target element
|
|
273
|
+
target_element_id = self._generate_uuid(f"element_{target_element}")
|
|
274
|
+
target_element_name = (
|
|
275
|
+
target_element.split(":")[-1] if ":" in target_element else target_element
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
cypher = """
|
|
279
|
+
MATCH (s:Structure)
|
|
280
|
+
WHERE s.identifier = $structure_id AND s.type = 'ElementMapping'
|
|
281
|
+
MATCH (from_el:Element {uri: $source_element})
|
|
282
|
+
MERGE (to_el:Element {identifier: $target_element_identifier})
|
|
283
|
+
ON CREATE SET to_el.uri = $target_element, to_el.name = $target_element_name
|
|
284
|
+
CREATE (a:Association {
|
|
285
|
+
identifier: $identifier,
|
|
286
|
+
association_type: 'ElementMapping',
|
|
287
|
+
arcrole: 'aggregation',
|
|
288
|
+
preferred_label: $preferred_label,
|
|
289
|
+
weight: $weight,
|
|
290
|
+
order_value: $order_value
|
|
291
|
+
})
|
|
292
|
+
CREATE (s)-[:STRUCTURE_HAS_ASSOCIATION]->(a)
|
|
293
|
+
CREATE (a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(from_el)
|
|
294
|
+
CREATE (a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(to_el)
|
|
295
|
+
RETURN a
|
|
296
|
+
"""
|
|
297
|
+
|
|
298
|
+
params = {
|
|
299
|
+
"structure_id": structure_id,
|
|
300
|
+
"identifier": association_id,
|
|
301
|
+
"preferred_label": aggregation_method.value,
|
|
302
|
+
"weight": weight,
|
|
303
|
+
"order_value": order_value,
|
|
304
|
+
"source_element": source_element,
|
|
305
|
+
"target_element": target_element,
|
|
306
|
+
"target_element_identifier": target_element_id,
|
|
307
|
+
"target_element_name": target_element_name,
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
self.query.query(graph_id, cypher, params)
|
|
311
|
+
|
|
312
|
+
return ElementAssociation(
|
|
313
|
+
identifier=association_id,
|
|
314
|
+
source_element=source_element,
|
|
315
|
+
target_element=target_element,
|
|
316
|
+
aggregation_method=aggregation_method,
|
|
317
|
+
weight=weight,
|
|
318
|
+
order_value=order_value,
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
async def update_association(
|
|
322
|
+
self,
|
|
323
|
+
graph_id: str,
|
|
324
|
+
structure_id: str,
|
|
325
|
+
association_id: str,
|
|
326
|
+
aggregation_method: AggregationMethod = None,
|
|
327
|
+
weight: float = None,
|
|
328
|
+
order_value: float = None,
|
|
329
|
+
) -> Optional[ElementAssociation]:
|
|
330
|
+
"""
|
|
331
|
+
Update an existing association.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
graph_id: Subgraph workspace ID
|
|
335
|
+
structure_id: Structure identifier
|
|
336
|
+
association_id: Association identifier
|
|
337
|
+
aggregation_method: New aggregation method
|
|
338
|
+
weight: New weight
|
|
339
|
+
order_value: New order value
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
Updated ElementAssociation, or None if not found
|
|
343
|
+
"""
|
|
344
|
+
set_clauses = []
|
|
345
|
+
params = {"structure_id": structure_id, "association_id": association_id}
|
|
346
|
+
|
|
347
|
+
if aggregation_method is not None:
|
|
348
|
+
set_clauses.append("a.preferred_label = $aggregation_method")
|
|
349
|
+
params["aggregation_method"] = aggregation_method.value
|
|
350
|
+
|
|
351
|
+
if weight is not None:
|
|
352
|
+
set_clauses.append("a.weight = $weight")
|
|
353
|
+
params["weight"] = weight
|
|
354
|
+
|
|
355
|
+
if order_value is not None:
|
|
356
|
+
set_clauses.append("a.order_value = $order_value")
|
|
357
|
+
params["order_value"] = order_value
|
|
358
|
+
|
|
359
|
+
if not set_clauses:
|
|
360
|
+
return None
|
|
361
|
+
|
|
362
|
+
update_cypher = f"""
|
|
363
|
+
MATCH (s:Structure)-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association)
|
|
364
|
+
WHERE s.identifier = $structure_id AND a.identifier = $association_id
|
|
365
|
+
SET {", ".join(set_clauses)}
|
|
366
|
+
RETURN a
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
self.query.query(graph_id, update_cypher, params)
|
|
370
|
+
|
|
371
|
+
# Get updated association
|
|
372
|
+
get_cypher = """
|
|
373
|
+
MATCH (s:Structure)-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association)
|
|
374
|
+
WHERE s.identifier = $structure_id AND a.identifier = $association_id
|
|
375
|
+
MATCH (a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(from_el:Element)
|
|
376
|
+
MATCH (a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(to_el:Element)
|
|
377
|
+
RETURN a, from_el.uri as source_element, to_el.uri as target_element
|
|
378
|
+
"""
|
|
379
|
+
|
|
380
|
+
result = self.query.query(graph_id, get_cypher, params)
|
|
381
|
+
|
|
382
|
+
if not result or not result.data:
|
|
383
|
+
return None
|
|
384
|
+
|
|
385
|
+
row = result.data[0]
|
|
386
|
+
assoc_data = row["a"]
|
|
387
|
+
|
|
388
|
+
return ElementAssociation(
|
|
389
|
+
identifier=assoc_data["identifier"],
|
|
390
|
+
source_element=row["source_element"],
|
|
391
|
+
target_element=row["target_element"],
|
|
392
|
+
aggregation_method=AggregationMethod(assoc_data["preferred_label"]),
|
|
393
|
+
weight=assoc_data["weight"],
|
|
394
|
+
order_value=assoc_data["order_value"],
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
async def delete_association(
|
|
398
|
+
self, graph_id: str, structure_id: str, association_id: str
|
|
399
|
+
) -> bool:
|
|
400
|
+
"""
|
|
401
|
+
Delete an association from a mapping structure.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
graph_id: Subgraph workspace ID
|
|
405
|
+
structure_id: Structure identifier
|
|
406
|
+
association_id: Association identifier
|
|
407
|
+
|
|
408
|
+
Returns:
|
|
409
|
+
True if deleted
|
|
410
|
+
"""
|
|
411
|
+
cypher = """
|
|
412
|
+
MATCH (s:Structure)-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association)
|
|
413
|
+
WHERE s.identifier = $structure_id AND a.identifier = $association_id
|
|
414
|
+
DETACH DELETE a
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
self.query.query(
|
|
418
|
+
graph_id, cypher, {"structure_id": structure_id, "association_id": association_id}
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
return True
|
|
422
|
+
|
|
423
|
+
async def delete_mapping_structure(self, graph_id: str, structure_id: str) -> bool:
|
|
424
|
+
"""
|
|
425
|
+
Delete a mapping structure and all its associations.
|
|
426
|
+
|
|
427
|
+
Args:
|
|
428
|
+
graph_id: Subgraph workspace ID
|
|
429
|
+
structure_id: Structure identifier
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
True if deleted
|
|
433
|
+
"""
|
|
434
|
+
cypher = """
|
|
435
|
+
MATCH (s:Structure)
|
|
436
|
+
WHERE s.identifier = $structure_id AND s.type = 'ElementMapping'
|
|
437
|
+
OPTIONAL MATCH (s)-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association)
|
|
438
|
+
DETACH DELETE s, a
|
|
439
|
+
"""
|
|
440
|
+
|
|
441
|
+
self.query.query(graph_id, cypher, {"structure_id": structure_id})
|
|
442
|
+
|
|
443
|
+
return True
|
|
444
|
+
|
|
445
|
+
@staticmethod
|
|
446
|
+
def apply_element_mapping(
|
|
447
|
+
fact_data: pd.DataFrame, mapping_structure: MappingStructure
|
|
448
|
+
) -> pd.DataFrame:
|
|
449
|
+
"""
|
|
450
|
+
Apply element mapping to aggregate source elements into target elements.
|
|
451
|
+
|
|
452
|
+
This is a client-side pandas operation that doesn't require graph access.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
fact_data: DataFrame with columns including element_id, numeric_value, etc.
|
|
456
|
+
mapping_structure: MappingStructure with associations defining aggregation
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
DataFrame with aggregated facts mapped to target elements
|
|
460
|
+
"""
|
|
461
|
+
if fact_data.empty or not mapping_structure.associations:
|
|
462
|
+
return fact_data
|
|
463
|
+
|
|
464
|
+
df = fact_data.copy()
|
|
465
|
+
aggregated_rows = []
|
|
466
|
+
|
|
467
|
+
# Handle both numeric_value (from facts) and net_balance (from trial balance)
|
|
468
|
+
value_col = "numeric_value" if "numeric_value" in df.columns else "net_balance"
|
|
469
|
+
|
|
470
|
+
# Group associations by target element
|
|
471
|
+
target_groups = {}
|
|
472
|
+
for assoc in mapping_structure.associations:
|
|
473
|
+
if assoc.target_element not in target_groups:
|
|
474
|
+
target_groups[assoc.target_element] = []
|
|
475
|
+
target_groups[assoc.target_element].append(assoc)
|
|
476
|
+
|
|
477
|
+
# Build URI to ID mapping if both columns exist
|
|
478
|
+
uri_to_id_map = {}
|
|
479
|
+
if "element_uri" in df.columns and "element_id" in df.columns:
|
|
480
|
+
for _, row in df[["element_uri", "element_id"]].drop_duplicates().iterrows():
|
|
481
|
+
uri_to_id_map[row["element_uri"]] = row["element_id"]
|
|
482
|
+
|
|
483
|
+
# Determine groupby columns
|
|
484
|
+
groupby_columns = []
|
|
485
|
+
if "period_end" in df.columns:
|
|
486
|
+
groupby_columns.append("period_end")
|
|
487
|
+
if "period_start" in df.columns:
|
|
488
|
+
groupby_columns.append("period_start")
|
|
489
|
+
if "entity_id" in df.columns:
|
|
490
|
+
groupby_columns.append("entity_id")
|
|
491
|
+
if "dimension_axis" in df.columns:
|
|
492
|
+
groupby_columns.append("dimension_axis")
|
|
493
|
+
if "dimension_member" in df.columns:
|
|
494
|
+
groupby_columns.append("dimension_member")
|
|
495
|
+
|
|
496
|
+
# Aggregate for each target element
|
|
497
|
+
for target_element, associations in target_groups.items():
|
|
498
|
+
# Map source URIs to IDs
|
|
499
|
+
source_element_uris = [assoc.source_element for assoc in associations]
|
|
500
|
+
source_element_ids = [uri_to_id_map.get(uri, uri) for uri in source_element_uris]
|
|
501
|
+
|
|
502
|
+
# Filter source facts
|
|
503
|
+
source_facts = df[df["element_id"].isin(source_element_ids)].copy()
|
|
504
|
+
|
|
505
|
+
if source_facts.empty:
|
|
506
|
+
continue
|
|
507
|
+
|
|
508
|
+
aggregation_method = associations[0].aggregation_method
|
|
509
|
+
|
|
510
|
+
if groupby_columns:
|
|
511
|
+
# Group and aggregate
|
|
512
|
+
for group_keys, group_df in source_facts.groupby(groupby_columns):
|
|
513
|
+
aggregated_value = ElementMappingClient._aggregate_values(
|
|
514
|
+
group_df, associations, aggregation_method, value_col
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
# Create aggregated row
|
|
518
|
+
aggregated_row = group_df.iloc[0].copy()
|
|
519
|
+
aggregated_row["element_id"] = target_element
|
|
520
|
+
aggregated_row["element_name"] = target_element.split(":")[-1]
|
|
521
|
+
aggregated_row[value_col] = aggregated_value
|
|
522
|
+
|
|
523
|
+
if "element_label" in aggregated_row:
|
|
524
|
+
aggregated_row["element_label"] = target_element.split(":")[-1]
|
|
525
|
+
|
|
526
|
+
aggregated_rows.append(aggregated_row)
|
|
527
|
+
else:
|
|
528
|
+
# No grouping, aggregate all
|
|
529
|
+
aggregated_value = ElementMappingClient._aggregate_values(
|
|
530
|
+
source_facts, associations, aggregation_method, value_col
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
aggregated_row = source_facts.iloc[0].copy()
|
|
534
|
+
aggregated_row["element_id"] = target_element
|
|
535
|
+
aggregated_row["element_name"] = target_element.split(":")[-1]
|
|
536
|
+
aggregated_row[value_col] = aggregated_value
|
|
537
|
+
|
|
538
|
+
if "element_label" in aggregated_row:
|
|
539
|
+
aggregated_row["element_label"] = target_element.split(":")[-1]
|
|
540
|
+
|
|
541
|
+
aggregated_rows.append(aggregated_row)
|
|
542
|
+
|
|
543
|
+
if not aggregated_rows:
|
|
544
|
+
return df
|
|
545
|
+
|
|
546
|
+
return pd.DataFrame(aggregated_rows)
|
|
547
|
+
|
|
548
|
+
@staticmethod
|
|
549
|
+
def _aggregate_values(
|
|
550
|
+
facts: pd.DataFrame,
|
|
551
|
+
associations: List[ElementAssociation],
|
|
552
|
+
method: AggregationMethod,
|
|
553
|
+
value_col: str,
|
|
554
|
+
) -> float:
|
|
555
|
+
"""Helper function to aggregate values based on method."""
|
|
556
|
+
if method == AggregationMethod.SUM:
|
|
557
|
+
return facts[value_col].sum()
|
|
558
|
+
|
|
559
|
+
elif method == AggregationMethod.AVERAGE:
|
|
560
|
+
return facts[value_col].mean()
|
|
561
|
+
|
|
562
|
+
elif method == AggregationMethod.WEIGHTED_AVERAGE:
|
|
563
|
+
weights_map = {assoc.source_element: assoc.weight for assoc in associations}
|
|
564
|
+
facts_with_weights = facts.copy()
|
|
565
|
+
facts_with_weights["weight"] = facts_with_weights["element_id"].map(weights_map)
|
|
566
|
+
facts_with_weights["weighted_value"] = (
|
|
567
|
+
facts_with_weights[value_col] * facts_with_weights["weight"]
|
|
568
|
+
)
|
|
569
|
+
total_weight = facts_with_weights["weight"].sum()
|
|
570
|
+
if total_weight == 0:
|
|
571
|
+
return 0.0
|
|
572
|
+
return facts_with_weights["weighted_value"].sum() / total_weight
|
|
573
|
+
|
|
574
|
+
elif method == AggregationMethod.FIRST:
|
|
575
|
+
return facts[value_col].iloc[0]
|
|
576
|
+
|
|
577
|
+
elif method == AggregationMethod.LAST:
|
|
578
|
+
return facts[value_col].iloc[-1]
|
|
579
|
+
|
|
580
|
+
elif method == AggregationMethod.CALCULATED:
|
|
581
|
+
# For calculated, use sum as default (could be customized)
|
|
582
|
+
return facts[value_col].sum()
|
|
583
|
+
|
|
584
|
+
# Default to sum
|
|
585
|
+
return facts[value_col].sum()
|