robosystems-client 0.1.9__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/__init__.py +14 -0
- robosystems_client/api/__init__.py +1 -0
- robosystems_client/api/agent/__init__.py +1 -0
- robosystems_client/api/agent/query_financial_agent.py +423 -0
- robosystems_client/api/auth/__init__.py +1 -0
- robosystems_client/api/auth/check_password_strength.py +172 -0
- robosystems_client/api/auth/complete_sso_auth.py +177 -0
- robosystems_client/api/auth/generate_sso_token.py +174 -0
- robosystems_client/api/auth/get_captcha_config.py +87 -0
- robosystems_client/api/auth/get_current_auth_user.py +220 -0
- robosystems_client/api/auth/get_password_policy.py +134 -0
- robosystems_client/api/auth/login_user.py +181 -0
- robosystems_client/api/auth/logout_user.py +169 -0
- robosystems_client/api/auth/refresh_session.py +174 -0
- robosystems_client/api/auth/register_user.py +189 -0
- robosystems_client/api/auth/sso_login.py +177 -0
- robosystems_client/api/auth/sso_token_exchange.py +181 -0
- robosystems_client/api/backup/__init__.py +1 -0
- robosystems_client/api/backup/create_backup.py +401 -0
- robosystems_client/api/backup/export_backup.py +225 -0
- robosystems_client/api/backup/get_backup_download_url.py +258 -0
- robosystems_client/api/backup/get_backup_stats.py +182 -0
- robosystems_client/api/backup/kuzu_backup_health.py +202 -0
- robosystems_client/api/backup/list_backups.py +217 -0
- robosystems_client/api/backup/restore_backup.py +401 -0
- robosystems_client/api/billing/__init__.py +1 -0
- robosystems_client/api/billing/get_available_subscription_plans_v1_graph_id_billing_available_plans_get.py +198 -0
- robosystems_client/api/billing/get_credit_billing_info_v1_graph_id_billing_credits_get.py +210 -0
- robosystems_client/api/billing/get_current_graph_bill.py +285 -0
- robosystems_client/api/billing/get_graph_billing_history.py +329 -0
- robosystems_client/api/billing/get_graph_monthly_bill.py +315 -0
- robosystems_client/api/billing/get_graph_pricing_info_v1_graph_id_billing_pricing_get.py +198 -0
- robosystems_client/api/billing/get_graph_subscription_v1_graph_id_billing_subscription_get.py +198 -0
- robosystems_client/api/billing/get_graph_usage_details.py +350 -0
- robosystems_client/api/billing/upgrade_graph_subscription_v1_graph_id_billing_subscription_upgrade_post.py +216 -0
- robosystems_client/api/connections/__init__.py +1 -0
- robosystems_client/api/connections/create_connection.py +327 -0
- robosystems_client/api/connections/create_link_token.py +281 -0
- robosystems_client/api/connections/delete_connection.py +278 -0
- robosystems_client/api/connections/exchange_link_token.py +301 -0
- robosystems_client/api/connections/get_connection.py +262 -0
- robosystems_client/api/connections/get_connection_options.py +285 -0
- robosystems_client/api/connections/init_o_auth.py +230 -0
- robosystems_client/api/connections/list_connections.py +314 -0
- robosystems_client/api/connections/oauth_callback.py +318 -0
- robosystems_client/api/connections/sync_connection.py +362 -0
- robosystems_client/api/create/__init__.py +1 -0
- robosystems_client/api/create/create_graph.py +375 -0
- robosystems_client/api/create/get_available_extensions.py +134 -0
- robosystems_client/api/credits_/__init__.py +1 -0
- robosystems_client/api/credits_/check_credit_balance.py +299 -0
- robosystems_client/api/credits_/check_storage_limits.py +249 -0
- robosystems_client/api/credits_/get_credit_summary.py +245 -0
- robosystems_client/api/credits_/get_storage_usage.py +279 -0
- robosystems_client/api/credits_/list_credit_transactions.py +392 -0
- robosystems_client/api/graph_analytics/__init__.py +1 -0
- robosystems_client/api/graph_analytics/get_graph_metrics.py +285 -0
- robosystems_client/api/graph_analytics/get_graph_usage_stats.py +329 -0
- robosystems_client/api/graph_status/__init__.py +1 -0
- robosystems_client/api/graph_status/get_database_health.py +273 -0
- robosystems_client/api/graph_status/get_database_info.py +277 -0
- robosystems_client/api/mcp/__init__.py +1 -0
- robosystems_client/api/mcp/call_mcp_tool.py +432 -0
- robosystems_client/api/mcp/list_mcp_tools.py +265 -0
- robosystems_client/api/operations/__init__.py +1 -0
- robosystems_client/api/operations/cancel_operation.py +246 -0
- robosystems_client/api/operations/get_operation_status.py +273 -0
- robosystems_client/api/operations/stream_operation_events.py +415 -0
- robosystems_client/api/query/__init__.py +1 -0
- robosystems_client/api/query/execute_cypher_query.py +482 -0
- robosystems_client/api/schema/__init__.py +1 -0
- robosystems_client/api/schema/export_graph_schema.py +239 -0
- robosystems_client/api/schema/get_graph_schema_info.py +277 -0
- robosystems_client/api/schema/list_schema_extensions.py +216 -0
- robosystems_client/api/schema/validate_schema.py +326 -0
- robosystems_client/api/service_offerings/__init__.py +1 -0
- robosystems_client/api/service_offerings/get_service_offerings.py +197 -0
- robosystems_client/api/status/__init__.py +1 -0
- robosystems_client/api/status/get_mcp_health.py +136 -0
- robosystems_client/api/status/get_service_status.py +134 -0
- robosystems_client/api/user/__init__.py +1 -0
- robosystems_client/api/user/create_user_api_key.py +205 -0
- robosystems_client/api/user/get_all_credit_summaries.py +256 -0
- robosystems_client/api/user/get_current_user.py +187 -0
- robosystems_client/api/user/get_user_graphs.py +187 -0
- robosystems_client/api/user/list_user_api_keys.py +187 -0
- robosystems_client/api/user/revoke_user_api_key.py +209 -0
- robosystems_client/api/user/select_user_graph.py +213 -0
- robosystems_client/api/user/update_user.py +205 -0
- robosystems_client/api/user/update_user_api_key.py +218 -0
- robosystems_client/api/user/update_user_password.py +218 -0
- robosystems_client/api/user_analytics/__init__.py +1 -0
- robosystems_client/api/user_analytics/get_detailed_user_analytics.py +222 -0
- robosystems_client/api/user_analytics/get_user_usage_overview.py +187 -0
- robosystems_client/api/user_limits/__init__.py +1 -0
- robosystems_client/api/user_limits/get_user_limits.py +190 -0
- robosystems_client/api/user_limits/get_user_usage.py +187 -0
- robosystems_client/api/user_subscriptions/__init__.py +1 -0
- robosystems_client/api/user_subscriptions/cancel_shared_repository_subscription.py +209 -0
- robosystems_client/api/user_subscriptions/get_repository_credits.py +206 -0
- robosystems_client/api/user_subscriptions/get_shared_repository_credits.py +193 -0
- robosystems_client/api/user_subscriptions/get_user_shared_subscriptions.py +213 -0
- robosystems_client/api/user_subscriptions/subscribe_to_shared_repository.py +214 -0
- robosystems_client/api/user_subscriptions/upgrade_shared_repository_subscription.py +228 -0
- robosystems_client/client.py +278 -0
- robosystems_client/errors.py +16 -0
- robosystems_client/extensions/README.md +611 -0
- robosystems_client/extensions/__init__.py +108 -0
- robosystems_client/extensions/auth_integration.py +210 -0
- robosystems_client/extensions/extensions.py +170 -0
- robosystems_client/extensions/operation_client.py +368 -0
- robosystems_client/extensions/query_client.py +375 -0
- robosystems_client/extensions/sse_client.py +520 -0
- robosystems_client/extensions/tests/__init__.py +1 -0
- robosystems_client/extensions/tests/test_integration.py +490 -0
- robosystems_client/extensions/tests/test_unit.py +560 -0
- robosystems_client/extensions/utils.py +526 -0
- robosystems_client/models/__init__.py +379 -0
- robosystems_client/models/account_info.py +79 -0
- robosystems_client/models/add_on_credit_info.py +119 -0
- robosystems_client/models/agent_message.py +68 -0
- robosystems_client/models/agent_request.py +132 -0
- robosystems_client/models/agent_request_context_type_0.py +44 -0
- robosystems_client/models/agent_response.py +132 -0
- robosystems_client/models/agent_response_metadata_type_0.py +44 -0
- robosystems_client/models/api_key_info.py +134 -0
- robosystems_client/models/api_keys_response.py +74 -0
- robosystems_client/models/auth_response.py +82 -0
- robosystems_client/models/auth_response_user.py +44 -0
- robosystems_client/models/available_extension.py +78 -0
- robosystems_client/models/available_extensions_response.py +73 -0
- robosystems_client/models/backup_create_request.py +117 -0
- robosystems_client/models/backup_export_request.py +72 -0
- robosystems_client/models/backup_list_response.py +90 -0
- robosystems_client/models/backup_response.py +200 -0
- robosystems_client/models/backup_restore_request.py +81 -0
- robosystems_client/models/backup_stats_response.py +156 -0
- robosystems_client/models/backup_stats_response_backup_formats.py +44 -0
- robosystems_client/models/cancel_operation_response_canceloperation.py +44 -0
- robosystems_client/models/cancellation_response.py +76 -0
- robosystems_client/models/check_credit_balance_response_checkcreditbalance.py +44 -0
- robosystems_client/models/connection_options_response.py +82 -0
- robosystems_client/models/connection_provider_info.py +203 -0
- robosystems_client/models/connection_provider_info_auth_type.py +11 -0
- robosystems_client/models/connection_provider_info_provider.py +10 -0
- robosystems_client/models/connection_response.py +149 -0
- robosystems_client/models/connection_response_metadata.py +44 -0
- robosystems_client/models/connection_response_provider.py +10 -0
- robosystems_client/models/create_api_key_request.py +82 -0
- robosystems_client/models/create_api_key_response.py +74 -0
- robosystems_client/models/create_connection_request.py +179 -0
- robosystems_client/models/create_connection_request_provider.py +10 -0
- robosystems_client/models/create_graph_request.py +183 -0
- robosystems_client/models/credit_check_request.py +82 -0
- robosystems_client/models/credit_summary.py +128 -0
- robosystems_client/models/credit_summary_response.py +140 -0
- robosystems_client/models/credits_summary_response.py +122 -0
- robosystems_client/models/credits_summary_response_credits_by_addon_item.py +44 -0
- robosystems_client/models/custom_schema_definition.py +194 -0
- robosystems_client/models/custom_schema_definition_metadata.py +49 -0
- robosystems_client/models/custom_schema_definition_nodes_item.py +44 -0
- robosystems_client/models/custom_schema_definition_relationships_item.py +44 -0
- robosystems_client/models/cypher_query_request.py +128 -0
- robosystems_client/models/cypher_query_request_parameters_type_0.py +44 -0
- robosystems_client/models/database_health_response.py +181 -0
- robosystems_client/models/database_info_response.py +191 -0
- robosystems_client/models/detailed_transactions_response.py +124 -0
- robosystems_client/models/detailed_transactions_response_date_range.py +44 -0
- robosystems_client/models/detailed_transactions_response_summary.py +59 -0
- robosystems_client/models/enhanced_credit_transaction_response.py +192 -0
- robosystems_client/models/enhanced_credit_transaction_response_metadata.py +44 -0
- robosystems_client/models/error_response.py +145 -0
- robosystems_client/models/exchange_token_request.py +116 -0
- robosystems_client/models/exchange_token_request_metadata_type_0.py +44 -0
- robosystems_client/models/get_all_credit_summaries_response_getallcreditsummaries.py +44 -0
- robosystems_client/models/get_backup_download_url_response_getbackupdownloadurl.py +44 -0
- robosystems_client/models/get_current_auth_user_response_getcurrentauthuser.py +44 -0
- robosystems_client/models/get_current_graph_bill_response_getcurrentgraphbill.py +44 -0
- robosystems_client/models/get_graph_billing_history_response_getgraphbillinghistory.py +44 -0
- robosystems_client/models/get_graph_monthly_bill_response_getgraphmonthlybill.py +44 -0
- robosystems_client/models/get_graph_schema_info_response_getgraphschemainfo.py +44 -0
- robosystems_client/models/get_graph_usage_details_response_getgraphusagedetails.py +44 -0
- robosystems_client/models/get_mcp_health_response_getmcphealth.py +44 -0
- robosystems_client/models/get_operation_status_response_getoperationstatus.py +44 -0
- robosystems_client/models/get_storage_usage_response_getstorageusage.py +44 -0
- robosystems_client/models/graph_info.py +92 -0
- robosystems_client/models/graph_metadata.py +105 -0
- robosystems_client/models/graph_metrics_response.py +188 -0
- robosystems_client/models/graph_metrics_response_estimated_size.py +44 -0
- robosystems_client/models/graph_metrics_response_health_status.py +44 -0
- robosystems_client/models/graph_metrics_response_node_counts.py +44 -0
- robosystems_client/models/graph_metrics_response_relationship_counts.py +44 -0
- robosystems_client/models/graph_usage_response.py +116 -0
- robosystems_client/models/graph_usage_response_query_statistics.py +44 -0
- robosystems_client/models/graph_usage_response_recent_activity.py +44 -0
- robosystems_client/models/graph_usage_response_storage_usage.py +44 -0
- robosystems_client/models/health_status.py +110 -0
- robosystems_client/models/health_status_details_type_0.py +44 -0
- robosystems_client/models/http_validation_error.py +75 -0
- robosystems_client/models/initial_entity_data.py +212 -0
- robosystems_client/models/kuzu_backup_health_response_kuzubackuphealth.py +44 -0
- robosystems_client/models/link_token_request.py +174 -0
- robosystems_client/models/link_token_request_options_type_0.py +44 -0
- robosystems_client/models/link_token_request_provider_type_0.py +10 -0
- robosystems_client/models/list_connections_provider_type_0.py +10 -0
- robosystems_client/models/list_schema_extensions_response_listschemaextensions.py +44 -0
- robosystems_client/models/login_request.py +68 -0
- robosystems_client/models/logout_user_response_logoutuser.py +44 -0
- robosystems_client/models/mcp_tool_call.py +84 -0
- robosystems_client/models/mcp_tool_call_arguments.py +44 -0
- robosystems_client/models/mcp_tools_response.py +74 -0
- robosystems_client/models/mcp_tools_response_tools_item.py +44 -0
- robosystems_client/models/o_auth_callback_request.py +130 -0
- robosystems_client/models/o_auth_init_request.py +128 -0
- robosystems_client/models/o_auth_init_request_additional_params_type_0.py +44 -0
- robosystems_client/models/o_auth_init_response.py +78 -0
- robosystems_client/models/password_check_request.py +82 -0
- robosystems_client/models/password_check_response.py +112 -0
- robosystems_client/models/password_check_response_character_types.py +44 -0
- robosystems_client/models/password_policy_response.py +66 -0
- robosystems_client/models/password_policy_response_policy.py +44 -0
- robosystems_client/models/plaid_connection_config.py +209 -0
- robosystems_client/models/plaid_connection_config_accounts_type_0_item.py +44 -0
- robosystems_client/models/plaid_connection_config_institution_type_0.py +44 -0
- robosystems_client/models/quick_books_connection_config.py +92 -0
- robosystems_client/models/register_request.py +98 -0
- robosystems_client/models/repository_credits_response.py +101 -0
- robosystems_client/models/repository_plan.py +10 -0
- robosystems_client/models/repository_type.py +10 -0
- robosystems_client/models/response_mode.py +11 -0
- robosystems_client/models/schema_export_response.py +163 -0
- robosystems_client/models/schema_export_response_data_stats_type_0.py +44 -0
- robosystems_client/models/schema_export_response_schema_definition_type_0.py +44 -0
- robosystems_client/models/schema_validation_request.py +142 -0
- robosystems_client/models/schema_validation_request_schema_definition_type_0.py +44 -0
- robosystems_client/models/schema_validation_response.py +227 -0
- robosystems_client/models/schema_validation_response_compatibility_type_0.py +44 -0
- robosystems_client/models/schema_validation_response_stats_type_0.py +44 -0
- robosystems_client/models/sec_connection_config.py +82 -0
- robosystems_client/models/sso_complete_request.py +60 -0
- robosystems_client/models/sso_exchange_request.py +90 -0
- robosystems_client/models/sso_exchange_response.py +78 -0
- robosystems_client/models/sso_login_request.py +60 -0
- robosystems_client/models/sso_token_response.py +78 -0
- robosystems_client/models/storage_limit_response.py +149 -0
- robosystems_client/models/subscription_info.py +180 -0
- robosystems_client/models/subscription_info_metadata.py +44 -0
- robosystems_client/models/subscription_request.py +89 -0
- robosystems_client/models/subscription_response.py +82 -0
- robosystems_client/models/success_response.py +112 -0
- robosystems_client/models/success_response_data_type_0.py +44 -0
- robosystems_client/models/sync_connection_request.py +106 -0
- robosystems_client/models/sync_connection_request_sync_options_type_0.py +44 -0
- robosystems_client/models/sync_connection_response_syncconnection.py +44 -0
- robosystems_client/models/tier_upgrade_request.py +62 -0
- robosystems_client/models/transaction_summary_response.py +126 -0
- robosystems_client/models/update_api_key_request.py +92 -0
- robosystems_client/models/update_password_request.py +76 -0
- robosystems_client/models/update_user_request.py +92 -0
- robosystems_client/models/upgrade_subscription_request.py +82 -0
- robosystems_client/models/user_analytics_response.py +132 -0
- robosystems_client/models/user_analytics_response_api_usage.py +44 -0
- robosystems_client/models/user_analytics_response_graph_usage.py +44 -0
- robosystems_client/models/user_analytics_response_limits.py +44 -0
- robosystems_client/models/user_analytics_response_recent_activity_item.py +44 -0
- robosystems_client/models/user_analytics_response_user_info.py +44 -0
- robosystems_client/models/user_graph_summary.py +134 -0
- robosystems_client/models/user_graphs_response.py +96 -0
- robosystems_client/models/user_limits_response.py +95 -0
- robosystems_client/models/user_response.py +132 -0
- robosystems_client/models/user_subscriptions_response.py +90 -0
- robosystems_client/models/user_usage_response.py +90 -0
- robosystems_client/models/user_usage_response_graphs.py +44 -0
- robosystems_client/models/user_usage_summary_response.py +130 -0
- robosystems_client/models/user_usage_summary_response_usage_vs_limits.py +44 -0
- robosystems_client/models/validation_error.py +88 -0
- robosystems_client/py.typed +1 -0
- robosystems_client/sdk-config.yaml +5 -0
- robosystems_client/types.py +54 -0
- robosystems_client-0.1.9.dist-info/METADATA +302 -0
- robosystems_client-0.1.9.dist-info/RECORD +282 -0
- robosystems_client-0.1.9.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"""Enhanced Query Client with SSE support
|
|
2
|
+
|
|
3
|
+
Provides intelligent query execution with automatic strategy selection.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Dict, Any, Optional, Callable, AsyncIterator, Iterator, Union
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
from ..api.query.execute_cypher_query import sync_detailed as execute_cypher_query
|
|
11
|
+
from ..models.cypher_query_request import CypherQueryRequest
|
|
12
|
+
from .sse_client import SSEClient, AsyncSSEClient, SSEConfig, EventType
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class QueryRequest:
|
|
17
|
+
"""Request object for queries"""
|
|
18
|
+
|
|
19
|
+
query: str
|
|
20
|
+
parameters: Optional[Dict[str, Any]] = None
|
|
21
|
+
timeout: Optional[int] = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class QueryOptions:
|
|
26
|
+
"""Options for query execution"""
|
|
27
|
+
|
|
28
|
+
mode: Optional[str] = "auto" # 'auto', 'sync', 'async', 'stream'
|
|
29
|
+
chunk_size: Optional[int] = None
|
|
30
|
+
test_mode: Optional[bool] = None
|
|
31
|
+
max_wait: Optional[int] = None
|
|
32
|
+
on_queue_update: Optional[Callable[[int, int], None]] = None
|
|
33
|
+
on_progress: Optional[Callable[[str], None]] = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class QueryResult:
|
|
38
|
+
"""Result from query execution"""
|
|
39
|
+
|
|
40
|
+
data: list
|
|
41
|
+
columns: list
|
|
42
|
+
row_count: int
|
|
43
|
+
execution_time_ms: int
|
|
44
|
+
graph_id: Optional[str] = None
|
|
45
|
+
timestamp: Optional[str] = None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class QueuedQueryResponse:
|
|
50
|
+
"""Response when query is queued"""
|
|
51
|
+
|
|
52
|
+
status: str
|
|
53
|
+
operation_id: str
|
|
54
|
+
queue_position: int
|
|
55
|
+
estimated_wait_seconds: int
|
|
56
|
+
message: str
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class QueuedQueryError(Exception):
|
|
60
|
+
"""Exception thrown when query is queued and maxWait is 0"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, queue_info: QueuedQueryResponse):
|
|
63
|
+
super().__init__("Query was queued")
|
|
64
|
+
self.queue_info = queue_info
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class QueryClient:
|
|
68
|
+
"""Enhanced query client with SSE streaming support"""
|
|
69
|
+
|
|
70
|
+
def __init__(self, config: Dict[str, Any]):
|
|
71
|
+
self.config = config
|
|
72
|
+
self.base_url = config["base_url"]
|
|
73
|
+
self.sse_client: Optional[SSEClient] = None
|
|
74
|
+
|
|
75
|
+
def execute_query(
|
|
76
|
+
self, graph_id: str, request: QueryRequest, options: QueryOptions = None
|
|
77
|
+
) -> Union[QueryResult, Iterator[Any]]:
|
|
78
|
+
"""Execute a query with intelligent strategy selection"""
|
|
79
|
+
if options is None:
|
|
80
|
+
options = QueryOptions()
|
|
81
|
+
|
|
82
|
+
# Build request data
|
|
83
|
+
query_request = CypherQueryRequest(
|
|
84
|
+
query=request.query, parameters=request.parameters or {}
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Execute the query through the generated client
|
|
88
|
+
from ..client import AuthenticatedClient
|
|
89
|
+
|
|
90
|
+
# Get client instance (you'd configure this based on your setup)
|
|
91
|
+
client = AuthenticatedClient(base_url=self.base_url)
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
response = execute_cypher_query(
|
|
95
|
+
graph_id=graph_id, client=client, body=query_request
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# Check response type and handle accordingly
|
|
99
|
+
if hasattr(response, "parsed") and response.parsed:
|
|
100
|
+
response_data = response.parsed
|
|
101
|
+
|
|
102
|
+
# Check if this is an immediate response
|
|
103
|
+
if hasattr(response_data, "data") and hasattr(response_data, "columns"):
|
|
104
|
+
return QueryResult(
|
|
105
|
+
data=response_data.data,
|
|
106
|
+
columns=response_data.columns,
|
|
107
|
+
row_count=getattr(response_data, "row_count", len(response_data.data)),
|
|
108
|
+
execution_time_ms=getattr(response_data, "execution_time_ms", 0),
|
|
109
|
+
graph_id=graph_id,
|
|
110
|
+
timestamp=getattr(response_data, "timestamp", datetime.now().isoformat()),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Check if this is a queued response
|
|
114
|
+
if (
|
|
115
|
+
hasattr(response_data, "status")
|
|
116
|
+
and response_data.status == "queued"
|
|
117
|
+
and hasattr(response_data, "operation_id")
|
|
118
|
+
):
|
|
119
|
+
queued_response = QueuedQueryResponse(
|
|
120
|
+
status=response_data.status,
|
|
121
|
+
operation_id=response_data.operation_id,
|
|
122
|
+
queue_position=getattr(response_data, "queue_position", 0),
|
|
123
|
+
estimated_wait_seconds=getattr(response_data, "estimated_wait_seconds", 0),
|
|
124
|
+
message=getattr(response_data, "message", "Query queued"),
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Notify about queue status
|
|
128
|
+
if options.on_queue_update:
|
|
129
|
+
options.on_queue_update(
|
|
130
|
+
queued_response.queue_position, queued_response.estimated_wait_seconds
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# If user doesn't want to wait, raise with queue info
|
|
134
|
+
if options.max_wait == 0:
|
|
135
|
+
raise QueuedQueryError(queued_response)
|
|
136
|
+
|
|
137
|
+
# Use SSE to monitor the operation
|
|
138
|
+
if options.mode == "stream":
|
|
139
|
+
return self._stream_query_results(queued_response.operation_id, options)
|
|
140
|
+
else:
|
|
141
|
+
return self._wait_for_query_completion(
|
|
142
|
+
queued_response.operation_id, options
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
except Exception as e:
|
|
146
|
+
if isinstance(e, QueuedQueryError):
|
|
147
|
+
raise
|
|
148
|
+
raise Exception(f"Query execution failed: {str(e)}")
|
|
149
|
+
|
|
150
|
+
# Unexpected response format
|
|
151
|
+
raise Exception("Unexpected response format from query endpoint")
|
|
152
|
+
|
|
153
|
+
def _stream_query_results(
|
|
154
|
+
self, operation_id: str, options: QueryOptions
|
|
155
|
+
) -> Iterator[Any]:
|
|
156
|
+
"""Stream query results using SSE"""
|
|
157
|
+
buffer = []
|
|
158
|
+
completed = False
|
|
159
|
+
error = None
|
|
160
|
+
|
|
161
|
+
# Set up SSE connection
|
|
162
|
+
sse_config = SSEConfig(base_url=self.base_url)
|
|
163
|
+
self.sse_client = SSEClient(sse_config)
|
|
164
|
+
|
|
165
|
+
# Set up event handlers
|
|
166
|
+
def on_data_chunk(data):
|
|
167
|
+
nonlocal buffer
|
|
168
|
+
if isinstance(data.get("rows"), list):
|
|
169
|
+
buffer.extend(data["rows"])
|
|
170
|
+
elif isinstance(data.get("data"), list):
|
|
171
|
+
buffer.extend(data["data"])
|
|
172
|
+
|
|
173
|
+
def on_queue_update(data):
|
|
174
|
+
if options.on_queue_update:
|
|
175
|
+
options.on_queue_update(
|
|
176
|
+
data.get("position", 0), data.get("estimated_wait_seconds", 0)
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def on_progress(data):
|
|
180
|
+
if options.on_progress:
|
|
181
|
+
options.on_progress(data.get("message", "Processing..."))
|
|
182
|
+
|
|
183
|
+
def on_completed(data):
|
|
184
|
+
nonlocal completed, buffer
|
|
185
|
+
if data.get("result", {}).get("data"):
|
|
186
|
+
buffer.extend(data["result"]["data"])
|
|
187
|
+
completed = True
|
|
188
|
+
|
|
189
|
+
def on_error(err):
|
|
190
|
+
nonlocal error, completed
|
|
191
|
+
error = Exception(err.get("message", err.get("error", "Unknown error")))
|
|
192
|
+
completed = True
|
|
193
|
+
|
|
194
|
+
# Register event handlers
|
|
195
|
+
self.sse_client.on(EventType.DATA_CHUNK.value, on_data_chunk)
|
|
196
|
+
self.sse_client.on(EventType.QUEUE_UPDATE.value, on_queue_update)
|
|
197
|
+
self.sse_client.on(EventType.OPERATION_PROGRESS.value, on_progress)
|
|
198
|
+
self.sse_client.on(EventType.OPERATION_COMPLETED.value, on_completed)
|
|
199
|
+
self.sse_client.on(EventType.OPERATION_ERROR.value, on_error)
|
|
200
|
+
|
|
201
|
+
# Connect and start streaming
|
|
202
|
+
self.sse_client.connect(operation_id)
|
|
203
|
+
|
|
204
|
+
# Yield buffered results
|
|
205
|
+
while not completed or buffer:
|
|
206
|
+
if error:
|
|
207
|
+
raise error
|
|
208
|
+
|
|
209
|
+
if buffer:
|
|
210
|
+
chunk_size = options.chunk_size or 100
|
|
211
|
+
chunk = buffer[:chunk_size]
|
|
212
|
+
buffer = buffer[chunk_size:]
|
|
213
|
+
for item in chunk:
|
|
214
|
+
yield item
|
|
215
|
+
elif not completed:
|
|
216
|
+
# Wait for more data
|
|
217
|
+
import time
|
|
218
|
+
|
|
219
|
+
time.sleep(0.1)
|
|
220
|
+
|
|
221
|
+
# Clean up
|
|
222
|
+
if self.sse_client:
|
|
223
|
+
self.sse_client.close()
|
|
224
|
+
self.sse_client = None
|
|
225
|
+
|
|
226
|
+
def _wait_for_query_completion(
|
|
227
|
+
self, operation_id: str, options: QueryOptions
|
|
228
|
+
) -> QueryResult:
|
|
229
|
+
"""Wait for query completion and return final result"""
|
|
230
|
+
result = None
|
|
231
|
+
error = None
|
|
232
|
+
completed = False
|
|
233
|
+
|
|
234
|
+
# Set up SSE connection
|
|
235
|
+
sse_config = SSEConfig(base_url=self.base_url)
|
|
236
|
+
sse_client = SSEClient(sse_config)
|
|
237
|
+
|
|
238
|
+
def on_queue_update(data):
|
|
239
|
+
if options.on_queue_update:
|
|
240
|
+
options.on_queue_update(
|
|
241
|
+
data.get("position", 0), data.get("estimated_wait_seconds", 0)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def on_progress(data):
|
|
245
|
+
if options.on_progress:
|
|
246
|
+
options.on_progress(data.get("message", "Processing..."))
|
|
247
|
+
|
|
248
|
+
def on_completed(data):
|
|
249
|
+
nonlocal result, completed
|
|
250
|
+
query_result = data.get("result", data)
|
|
251
|
+
result = QueryResult(
|
|
252
|
+
data=query_result.get("data", []),
|
|
253
|
+
columns=query_result.get("columns", []),
|
|
254
|
+
row_count=query_result.get("row_count", 0),
|
|
255
|
+
execution_time_ms=query_result.get("execution_time_ms", 0),
|
|
256
|
+
graph_id=query_result.get("graph_id"),
|
|
257
|
+
timestamp=query_result.get("timestamp", datetime.now().isoformat()),
|
|
258
|
+
)
|
|
259
|
+
completed = True
|
|
260
|
+
|
|
261
|
+
def on_error(err):
|
|
262
|
+
nonlocal error, completed
|
|
263
|
+
error = Exception(err.get("message", err.get("error", "Unknown error")))
|
|
264
|
+
completed = True
|
|
265
|
+
|
|
266
|
+
def on_cancelled():
|
|
267
|
+
nonlocal error, completed
|
|
268
|
+
error = Exception("Query cancelled")
|
|
269
|
+
completed = True
|
|
270
|
+
|
|
271
|
+
# Register event handlers
|
|
272
|
+
sse_client.on(EventType.QUEUE_UPDATE.value, on_queue_update)
|
|
273
|
+
sse_client.on(EventType.OPERATION_PROGRESS.value, on_progress)
|
|
274
|
+
sse_client.on(EventType.OPERATION_COMPLETED.value, on_completed)
|
|
275
|
+
sse_client.on(EventType.OPERATION_ERROR.value, on_error)
|
|
276
|
+
sse_client.on(EventType.OPERATION_CANCELLED.value, on_cancelled)
|
|
277
|
+
|
|
278
|
+
# Connect and wait
|
|
279
|
+
sse_client.connect(operation_id)
|
|
280
|
+
|
|
281
|
+
# Wait for completion
|
|
282
|
+
import time
|
|
283
|
+
|
|
284
|
+
while not completed:
|
|
285
|
+
if error:
|
|
286
|
+
sse_client.close()
|
|
287
|
+
raise error
|
|
288
|
+
time.sleep(0.1)
|
|
289
|
+
|
|
290
|
+
sse_client.close()
|
|
291
|
+
return result
|
|
292
|
+
|
|
293
|
+
def query(
|
|
294
|
+
self, graph_id: str, cypher: str, parameters: Dict[str, Any] = None
|
|
295
|
+
) -> QueryResult:
|
|
296
|
+
"""Convenience method for simple queries"""
|
|
297
|
+
request = QueryRequest(query=cypher, parameters=parameters)
|
|
298
|
+
result = self.execute_query(graph_id, request, QueryOptions(mode="auto"))
|
|
299
|
+
if isinstance(result, QueryResult):
|
|
300
|
+
return result
|
|
301
|
+
else:
|
|
302
|
+
# If it's an iterator, collect all results
|
|
303
|
+
data = list(result)
|
|
304
|
+
return QueryResult(
|
|
305
|
+
data=data,
|
|
306
|
+
columns=[], # Would need to extract from first chunk
|
|
307
|
+
row_count=len(data),
|
|
308
|
+
execution_time_ms=0,
|
|
309
|
+
graph_id=graph_id,
|
|
310
|
+
timestamp=datetime.now().isoformat(),
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
def stream_query(
|
|
314
|
+
self,
|
|
315
|
+
graph_id: str,
|
|
316
|
+
cypher: str,
|
|
317
|
+
parameters: Dict[str, Any] = None,
|
|
318
|
+
chunk_size: int = 1000,
|
|
319
|
+
) -> Iterator[Any]:
|
|
320
|
+
"""Streaming query for large results"""
|
|
321
|
+
request = QueryRequest(query=cypher, parameters=parameters)
|
|
322
|
+
result = self.execute_query(
|
|
323
|
+
graph_id, request, QueryOptions(mode="stream", chunk_size=chunk_size)
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
if isinstance(result, Iterator):
|
|
327
|
+
yield from result
|
|
328
|
+
else:
|
|
329
|
+
# If not streaming, yield all results at once
|
|
330
|
+
yield from result.data
|
|
331
|
+
|
|
332
|
+
def close(self):
|
|
333
|
+
"""Cancel any active SSE connections"""
|
|
334
|
+
if self.sse_client:
|
|
335
|
+
self.sse_client.close()
|
|
336
|
+
self.sse_client = None
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
class AsyncQueryClient:
|
|
340
|
+
"""Async version of the query client"""
|
|
341
|
+
|
|
342
|
+
def __init__(self, config: Dict[str, Any]):
|
|
343
|
+
self.config = config
|
|
344
|
+
self.base_url = config["base_url"]
|
|
345
|
+
self.sse_client: Optional[AsyncSSEClient] = None
|
|
346
|
+
|
|
347
|
+
async def execute_query(
|
|
348
|
+
self, graph_id: str, request: QueryRequest, options: QueryOptions = None
|
|
349
|
+
) -> Union[QueryResult, AsyncIterator[Any]]:
|
|
350
|
+
"""Execute a query asynchronously"""
|
|
351
|
+
# Similar implementation to sync version but with async/await
|
|
352
|
+
# Would need async version of the generated client
|
|
353
|
+
pass
|
|
354
|
+
|
|
355
|
+
async def query(
|
|
356
|
+
self, graph_id: str, cypher: str, parameters: Dict[str, Any] = None
|
|
357
|
+
) -> QueryResult:
|
|
358
|
+
"""Async convenience method for simple queries"""
|
|
359
|
+
pass
|
|
360
|
+
|
|
361
|
+
async def stream_query(
|
|
362
|
+
self,
|
|
363
|
+
graph_id: str,
|
|
364
|
+
cypher: str,
|
|
365
|
+
parameters: Dict[str, Any] = None,
|
|
366
|
+
chunk_size: int = 1000,
|
|
367
|
+
) -> AsyncIterator[Any]:
|
|
368
|
+
"""Async streaming query for large results"""
|
|
369
|
+
pass
|
|
370
|
+
|
|
371
|
+
async def close(self):
|
|
372
|
+
"""Cancel any active SSE connections"""
|
|
373
|
+
if self.sse_client:
|
|
374
|
+
await self.sse_client.close()
|
|
375
|
+
self.sse_client = None
|