unrealon 1.0.9__py3-none-any.whl → 1.1.0__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.
- unrealon/__init__.py +23 -21
- unrealon-1.1.0.dist-info/METADATA +164 -0
- unrealon-1.1.0.dist-info/RECORD +82 -0
- {unrealon-1.0.9.dist-info → unrealon-1.1.0.dist-info}/WHEEL +1 -1
- unrealon-1.1.0.dist-info/entry_points.txt +9 -0
- {unrealon-1.0.9.dist-info → unrealon-1.1.0.dist-info/licenses}/LICENSE +1 -1
- unrealon_bridge/__init__.py +114 -0
- unrealon_bridge/cli.py +316 -0
- unrealon_bridge/client/__init__.py +93 -0
- unrealon_bridge/client/base.py +78 -0
- unrealon_bridge/client/commands.py +89 -0
- unrealon_bridge/client/connection.py +90 -0
- unrealon_bridge/client/events.py +65 -0
- unrealon_bridge/client/health.py +38 -0
- unrealon_bridge/client/html_parser.py +146 -0
- unrealon_bridge/client/logging.py +139 -0
- unrealon_bridge/client/proxy.py +70 -0
- unrealon_bridge/client/scheduler.py +450 -0
- unrealon_bridge/client/session.py +70 -0
- unrealon_bridge/configs/__init__.py +14 -0
- unrealon_bridge/configs/bridge_config.py +212 -0
- unrealon_bridge/configs/bridge_config.yaml +39 -0
- unrealon_bridge/models/__init__.py +138 -0
- unrealon_bridge/models/base.py +28 -0
- unrealon_bridge/models/command.py +41 -0
- unrealon_bridge/models/events.py +40 -0
- unrealon_bridge/models/html_parser.py +79 -0
- unrealon_bridge/models/logging.py +55 -0
- unrealon_bridge/models/parser.py +63 -0
- unrealon_bridge/models/proxy.py +41 -0
- unrealon_bridge/models/requests.py +95 -0
- unrealon_bridge/models/responses.py +88 -0
- unrealon_bridge/models/scheduler.py +592 -0
- unrealon_bridge/models/session.py +28 -0
- unrealon_bridge/server/__init__.py +91 -0
- unrealon_bridge/server/base.py +171 -0
- unrealon_bridge/server/handlers/__init__.py +23 -0
- unrealon_bridge/server/handlers/command.py +110 -0
- unrealon_bridge/server/handlers/html_parser.py +139 -0
- unrealon_bridge/server/handlers/logging.py +95 -0
- unrealon_bridge/server/handlers/parser.py +95 -0
- unrealon_bridge/server/handlers/proxy.py +75 -0
- unrealon_bridge/server/handlers/scheduler.py +545 -0
- unrealon_bridge/server/handlers/session.py +66 -0
- unrealon_browser/__init__.py +61 -18
- unrealon_browser/{src/cli → cli}/browser_cli.py +6 -13
- unrealon_browser/{src/cli → cli}/cookies_cli.py +5 -1
- unrealon_browser/{src/core → core}/browser_manager.py +2 -2
- unrealon_browser/{src/managers → managers}/captcha.py +1 -1
- unrealon_browser/{src/managers → managers}/cookies.py +1 -1
- unrealon_browser/managers/logger_bridge.py +231 -0
- unrealon_browser/{src/managers → managers}/profile.py +1 -1
- unrealon_driver/__init__.py +73 -19
- unrealon_driver/browser/__init__.py +8 -0
- unrealon_driver/browser/config.py +74 -0
- unrealon_driver/browser/manager.py +416 -0
- unrealon_driver/exceptions.py +28 -0
- unrealon_driver/parser/__init__.py +55 -0
- unrealon_driver/parser/cli_manager.py +141 -0
- unrealon_driver/parser/daemon_manager.py +227 -0
- unrealon_driver/parser/managers/__init__.py +46 -0
- unrealon_driver/parser/managers/browser.py +51 -0
- unrealon_driver/parser/managers/config.py +281 -0
- unrealon_driver/parser/managers/error.py +412 -0
- unrealon_driver/parser/managers/html.py +732 -0
- unrealon_driver/parser/managers/logging.py +609 -0
- unrealon_driver/parser/managers/result.py +321 -0
- unrealon_driver/parser/parser_manager.py +628 -0
- unrealon/sdk_config.py +0 -88
- unrealon-1.0.9.dist-info/METADATA +0 -810
- unrealon-1.0.9.dist-info/RECORD +0 -246
- unrealon_browser/pyproject.toml +0 -182
- unrealon_browser/src/__init__.py +0 -62
- unrealon_browser/src/managers/logger_bridge.py +0 -395
- unrealon_driver/README.md +0 -204
- unrealon_driver/pyproject.toml +0 -187
- unrealon_driver/src/__init__.py +0 -90
- unrealon_driver/src/cli/__init__.py +0 -10
- unrealon_driver/src/cli/main.py +0 -66
- unrealon_driver/src/cli/simple.py +0 -510
- unrealon_driver/src/config/__init__.py +0 -11
- unrealon_driver/src/config/auto_config.py +0 -478
- unrealon_driver/src/core/__init__.py +0 -18
- unrealon_driver/src/core/exceptions.py +0 -289
- unrealon_driver/src/core/parser.py +0 -638
- unrealon_driver/src/dto/__init__.py +0 -66
- unrealon_driver/src/dto/cli.py +0 -119
- unrealon_driver/src/dto/config.py +0 -18
- unrealon_driver/src/dto/events.py +0 -237
- unrealon_driver/src/dto/execution.py +0 -313
- unrealon_driver/src/dto/services.py +0 -311
- unrealon_driver/src/execution/__init__.py +0 -23
- unrealon_driver/src/execution/daemon_mode.py +0 -317
- unrealon_driver/src/execution/interactive_mode.py +0 -88
- unrealon_driver/src/execution/modes.py +0 -45
- unrealon_driver/src/execution/scheduled_mode.py +0 -209
- unrealon_driver/src/execution/test_mode.py +0 -250
- unrealon_driver/src/logging/__init__.py +0 -24
- unrealon_driver/src/logging/driver_logger.py +0 -512
- unrealon_driver/src/services/__init__.py +0 -24
- unrealon_driver/src/services/browser_service.py +0 -726
- unrealon_driver/src/services/llm/__init__.py +0 -15
- unrealon_driver/src/services/llm/browser_llm_service.py +0 -363
- unrealon_driver/src/services/llm/llm.py +0 -195
- unrealon_driver/src/services/logger_service.py +0 -232
- unrealon_driver/src/services/metrics_service.py +0 -185
- unrealon_driver/src/services/scheduler_service.py +0 -489
- unrealon_driver/src/services/websocket_service.py +0 -362
- unrealon_driver/src/utils/__init__.py +0 -16
- unrealon_driver/src/utils/service_factory.py +0 -317
- unrealon_driver/src/utils/time_formatter.py +0 -338
- unrealon_llm/README.md +0 -44
- unrealon_llm/__init__.py +0 -26
- unrealon_llm/pyproject.toml +0 -154
- unrealon_llm/src/__init__.py +0 -228
- unrealon_llm/src/cli/__init__.py +0 -0
- unrealon_llm/src/core/__init__.py +0 -11
- unrealon_llm/src/core/smart_client.py +0 -438
- unrealon_llm/src/dto/__init__.py +0 -155
- unrealon_llm/src/dto/models/__init__.py +0 -0
- unrealon_llm/src/dto/models/config.py +0 -343
- unrealon_llm/src/dto/models/core.py +0 -328
- unrealon_llm/src/dto/models/enums.py +0 -123
- unrealon_llm/src/dto/models/html_analysis.py +0 -345
- unrealon_llm/src/dto/models/statistics.py +0 -473
- unrealon_llm/src/dto/models/translation.py +0 -383
- unrealon_llm/src/dto/models/type_conversion.py +0 -462
- unrealon_llm/src/dto/schemas/__init__.py +0 -0
- unrealon_llm/src/exceptions.py +0 -392
- unrealon_llm/src/llm_config/__init__.py +0 -20
- unrealon_llm/src/llm_config/logging_config.py +0 -178
- unrealon_llm/src/llm_logging/__init__.py +0 -42
- unrealon_llm/src/llm_logging/llm_events.py +0 -107
- unrealon_llm/src/llm_logging/llm_logger.py +0 -466
- unrealon_llm/src/managers/__init__.py +0 -15
- unrealon_llm/src/managers/cache_manager.py +0 -67
- unrealon_llm/src/managers/cost_manager.py +0 -107
- unrealon_llm/src/managers/request_manager.py +0 -298
- unrealon_llm/src/modules/__init__.py +0 -0
- unrealon_llm/src/modules/html_processor/__init__.py +0 -25
- unrealon_llm/src/modules/html_processor/base_processor.py +0 -415
- unrealon_llm/src/modules/html_processor/details_processor.py +0 -85
- unrealon_llm/src/modules/html_processor/listing_processor.py +0 -91
- unrealon_llm/src/modules/html_processor/models/__init__.py +0 -20
- unrealon_llm/src/modules/html_processor/models/processing_models.py +0 -40
- unrealon_llm/src/modules/html_processor/models/universal_model.py +0 -56
- unrealon_llm/src/modules/html_processor/processor.py +0 -102
- unrealon_llm/src/modules/llm/__init__.py +0 -0
- unrealon_llm/src/modules/translator/__init__.py +0 -0
- unrealon_llm/src/provider.py +0 -116
- unrealon_llm/src/utils/__init__.py +0 -95
- unrealon_llm/src/utils/common.py +0 -64
- unrealon_llm/src/utils/data_extractor.py +0 -188
- unrealon_llm/src/utils/html_cleaner.py +0 -767
- unrealon_llm/src/utils/language_detector.py +0 -308
- unrealon_llm/src/utils/models_cache.py +0 -592
- unrealon_llm/src/utils/smart_counter.py +0 -229
- unrealon_llm/src/utils/token_counter.py +0 -189
- unrealon_sdk/README.md +0 -25
- unrealon_sdk/__init__.py +0 -30
- unrealon_sdk/pyproject.toml +0 -231
- unrealon_sdk/src/__init__.py +0 -150
- unrealon_sdk/src/cli/__init__.py +0 -12
- unrealon_sdk/src/cli/commands/__init__.py +0 -22
- unrealon_sdk/src/cli/commands/benchmark.py +0 -42
- unrealon_sdk/src/cli/commands/diagnostics.py +0 -573
- unrealon_sdk/src/cli/commands/health.py +0 -46
- unrealon_sdk/src/cli/commands/integration.py +0 -498
- unrealon_sdk/src/cli/commands/reports.py +0 -43
- unrealon_sdk/src/cli/commands/security.py +0 -36
- unrealon_sdk/src/cli/commands/server.py +0 -483
- unrealon_sdk/src/cli/commands/servers.py +0 -56
- unrealon_sdk/src/cli/commands/tests.py +0 -55
- unrealon_sdk/src/cli/main.py +0 -126
- unrealon_sdk/src/cli/utils/reporter.py +0 -519
- unrealon_sdk/src/clients/openapi.yaml +0 -3347
- unrealon_sdk/src/clients/python_http/__init__.py +0 -3
- unrealon_sdk/src/clients/python_http/api_config.py +0 -228
- unrealon_sdk/src/clients/python_http/models/BaseModel.py +0 -12
- unrealon_sdk/src/clients/python_http/models/BroadcastDeliveryStats.py +0 -33
- unrealon_sdk/src/clients/python_http/models/BroadcastMessage.py +0 -17
- unrealon_sdk/src/clients/python_http/models/BroadcastMessageRequest.py +0 -35
- unrealon_sdk/src/clients/python_http/models/BroadcastPriority.py +0 -10
- unrealon_sdk/src/clients/python_http/models/BroadcastResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/BroadcastResultResponse.py +0 -33
- unrealon_sdk/src/clients/python_http/models/BroadcastTarget.py +0 -11
- unrealon_sdk/src/clients/python_http/models/ConnectionStats.py +0 -27
- unrealon_sdk/src/clients/python_http/models/ConnectionsResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/DeveloperMessageResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ErrorResponse.py +0 -25
- unrealon_sdk/src/clients/python_http/models/HTTPValidationError.py +0 -16
- unrealon_sdk/src/clients/python_http/models/HealthResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/HealthStatus.py +0 -33
- unrealon_sdk/src/clients/python_http/models/LogLevel.py +0 -10
- unrealon_sdk/src/clients/python_http/models/LoggingRequest.py +0 -27
- unrealon_sdk/src/clients/python_http/models/LoggingResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/MaintenanceMode.py +0 -9
- unrealon_sdk/src/clients/python_http/models/MaintenanceModeRequest.py +0 -33
- unrealon_sdk/src/clients/python_http/models/MaintenanceStatusResponse.py +0 -39
- unrealon_sdk/src/clients/python_http/models/ParserCommandRequest.py +0 -25
- unrealon_sdk/src/clients/python_http/models/ParserMessageResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/ParserRegistrationRequest.py +0 -28
- unrealon_sdk/src/clients/python_http/models/ParserRegistrationResponse.py +0 -25
- unrealon_sdk/src/clients/python_http/models/ParserType.py +0 -10
- unrealon_sdk/src/clients/python_http/models/ProxyBlockRequest.py +0 -19
- unrealon_sdk/src/clients/python_http/models/ProxyEndpointResponse.py +0 -20
- unrealon_sdk/src/clients/python_http/models/ProxyListResponse.py +0 -19
- unrealon_sdk/src/clients/python_http/models/ProxyProvider.py +0 -10
- unrealon_sdk/src/clients/python_http/models/ProxyPurchaseRequest.py +0 -25
- unrealon_sdk/src/clients/python_http/models/ProxyResponse.py +0 -47
- unrealon_sdk/src/clients/python_http/models/ProxyRotationRequest.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ProxyStatus.py +0 -10
- unrealon_sdk/src/clients/python_http/models/ProxyUsageRequest.py +0 -19
- unrealon_sdk/src/clients/python_http/models/ProxyUsageStatsResponse.py +0 -26
- unrealon_sdk/src/clients/python_http/models/ServiceRegistrationDto.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ServiceStatsResponse.py +0 -31
- unrealon_sdk/src/clients/python_http/models/SessionStartRequest.py +0 -23
- unrealon_sdk/src/clients/python_http/models/SuccessResponse.py +0 -25
- unrealon_sdk/src/clients/python_http/models/SystemNotificationResponse.py +0 -23
- unrealon_sdk/src/clients/python_http/models/ValidationError.py +0 -18
- unrealon_sdk/src/clients/python_http/models/ValidationErrorResponse.py +0 -21
- unrealon_sdk/src/clients/python_http/models/WebSocketMetrics.py +0 -21
- unrealon_sdk/src/clients/python_http/models/__init__.py +0 -44
- unrealon_sdk/src/clients/python_http/services/None_service.py +0 -35
- unrealon_sdk/src/clients/python_http/services/ParserManagement_service.py +0 -190
- unrealon_sdk/src/clients/python_http/services/ProxyManagement_service.py +0 -289
- unrealon_sdk/src/clients/python_http/services/SocketLogging_service.py +0 -187
- unrealon_sdk/src/clients/python_http/services/SystemHealth_service.py +0 -119
- unrealon_sdk/src/clients/python_http/services/WebSocketAPI_service.py +0 -198
- unrealon_sdk/src/clients/python_http/services/__init__.py +0 -0
- unrealon_sdk/src/clients/python_http/services/admin_service.py +0 -125
- unrealon_sdk/src/clients/python_http/services/async_None_service.py +0 -35
- unrealon_sdk/src/clients/python_http/services/async_ParserManagement_service.py +0 -190
- unrealon_sdk/src/clients/python_http/services/async_ProxyManagement_service.py +0 -289
- unrealon_sdk/src/clients/python_http/services/async_SocketLogging_service.py +0 -189
- unrealon_sdk/src/clients/python_http/services/async_SystemHealth_service.py +0 -123
- unrealon_sdk/src/clients/python_http/services/async_WebSocketAPI_service.py +0 -200
- unrealon_sdk/src/clients/python_http/services/async_admin_service.py +0 -125
- unrealon_sdk/src/clients/python_websocket/__init__.py +0 -28
- unrealon_sdk/src/clients/python_websocket/client.py +0 -490
- unrealon_sdk/src/clients/python_websocket/events.py +0 -732
- unrealon_sdk/src/clients/python_websocket/example.py +0 -136
- unrealon_sdk/src/clients/python_websocket/types.py +0 -871
- unrealon_sdk/src/core/__init__.py +0 -64
- unrealon_sdk/src/core/client.py +0 -556
- unrealon_sdk/src/core/config.py +0 -465
- unrealon_sdk/src/core/exceptions.py +0 -239
- unrealon_sdk/src/core/metadata.py +0 -191
- unrealon_sdk/src/core/models.py +0 -142
- unrealon_sdk/src/core/types.py +0 -68
- unrealon_sdk/src/dto/__init__.py +0 -268
- unrealon_sdk/src/dto/authentication.py +0 -108
- unrealon_sdk/src/dto/cache.py +0 -208
- unrealon_sdk/src/dto/common.py +0 -19
- unrealon_sdk/src/dto/concurrency.py +0 -393
- unrealon_sdk/src/dto/events.py +0 -108
- unrealon_sdk/src/dto/health.py +0 -339
- unrealon_sdk/src/dto/load_balancing.py +0 -336
- unrealon_sdk/src/dto/logging.py +0 -230
- unrealon_sdk/src/dto/performance.py +0 -165
- unrealon_sdk/src/dto/rate_limiting.py +0 -295
- unrealon_sdk/src/dto/resource_pooling.py +0 -128
- unrealon_sdk/src/dto/structured_logging.py +0 -112
- unrealon_sdk/src/dto/task_scheduling.py +0 -121
- unrealon_sdk/src/dto/websocket.py +0 -55
- unrealon_sdk/src/enterprise/__init__.py +0 -59
- unrealon_sdk/src/enterprise/authentication.py +0 -401
- unrealon_sdk/src/enterprise/cache_manager.py +0 -578
- unrealon_sdk/src/enterprise/error_recovery.py +0 -494
- unrealon_sdk/src/enterprise/event_system.py +0 -549
- unrealon_sdk/src/enterprise/health_monitor.py +0 -747
- unrealon_sdk/src/enterprise/load_balancer.py +0 -964
- unrealon_sdk/src/enterprise/logging/__init__.py +0 -68
- unrealon_sdk/src/enterprise/logging/cleanup.py +0 -156
- unrealon_sdk/src/enterprise/logging/development.py +0 -744
- unrealon_sdk/src/enterprise/logging/service.py +0 -410
- unrealon_sdk/src/enterprise/multithreading_manager.py +0 -853
- unrealon_sdk/src/enterprise/performance_monitor.py +0 -539
- unrealon_sdk/src/enterprise/proxy_manager.py +0 -696
- unrealon_sdk/src/enterprise/rate_limiter.py +0 -652
- unrealon_sdk/src/enterprise/resource_pool.py +0 -763
- unrealon_sdk/src/enterprise/task_scheduler.py +0 -709
- unrealon_sdk/src/internal/__init__.py +0 -10
- unrealon_sdk/src/internal/command_router.py +0 -497
- unrealon_sdk/src/internal/connection_manager.py +0 -397
- unrealon_sdk/src/internal/http_client.py +0 -446
- unrealon_sdk/src/internal/websocket_client.py +0 -420
- unrealon_sdk/src/provider.py +0 -471
- unrealon_sdk/src/utils.py +0 -234
- /unrealon_browser/{src/cli → cli}/__init__.py +0 -0
- /unrealon_browser/{src/cli → cli}/interactive_mode.py +0 -0
- /unrealon_browser/{src/cli → cli}/main.py +0 -0
- /unrealon_browser/{src/core → core}/__init__.py +0 -0
- /unrealon_browser/{src/dto → dto}/__init__.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/config.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/core.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/dataclasses.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/detection.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/enums.py +0 -0
- /unrealon_browser/{src/dto → dto}/models/statistics.py +0 -0
- /unrealon_browser/{src/managers → managers}/__init__.py +0 -0
- /unrealon_browser/{src/managers → managers}/stealth.py +0 -0
|
@@ -1,397 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Connection management for UnrealOn SDK v1.0
|
|
3
|
-
|
|
4
|
-
Handles WebSocket and HTTP connections to the UnrealOn Adapter with:
|
|
5
|
-
- Automatic reconnection
|
|
6
|
-
- Health monitoring
|
|
7
|
-
- Session management
|
|
8
|
-
- Error recovery
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import asyncio
|
|
12
|
-
import logging
|
|
13
|
-
from typing import Optional, Callable, Union, Awaitable, Any
|
|
14
|
-
from datetime import datetime
|
|
15
|
-
|
|
16
|
-
from unrealon_sdk.src.core.config import AdapterConfig
|
|
17
|
-
from unrealon_sdk.src.core.models import ConnectionHealthStatus
|
|
18
|
-
|
|
19
|
-
# Also import from DTO for new features
|
|
20
|
-
from unrealon_sdk.src.dto.health import ConnectionHealthStatus as DTOConnectionHealthStatus
|
|
21
|
-
from unrealon_sdk.src.core.exceptions import ConnectionError, AuthenticationError
|
|
22
|
-
from unrealon_sdk.src.core.metadata import LoggingContextMetadata, SDKMetadata
|
|
23
|
-
|
|
24
|
-
# Use auto-generated models only - no custom models!
|
|
25
|
-
from unrealon_sdk.src.clients.python_websocket.types import ParserCommandEvent
|
|
26
|
-
from unrealon_sdk.src.clients.python_http.models import (
|
|
27
|
-
ParserRegistrationRequest,
|
|
28
|
-
ParserRegistrationResponse,
|
|
29
|
-
LogLevel,
|
|
30
|
-
LoggingRequest,
|
|
31
|
-
HealthResponse,
|
|
32
|
-
SuccessResponse,
|
|
33
|
-
ErrorResponse,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
# Import the wrapper clients we need to create
|
|
37
|
-
from .websocket_client import WebSocketClientWrapper
|
|
38
|
-
from .http_client import HTTPClientWrapper
|
|
39
|
-
|
|
40
|
-
# Development logging
|
|
41
|
-
from unrealon_sdk.src.enterprise.logging.development import (
|
|
42
|
-
get_development_logger,
|
|
43
|
-
SDKEventType,
|
|
44
|
-
SDKContext,
|
|
45
|
-
track_development_operation,
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class ConnectionManager:
|
|
50
|
-
"""
|
|
51
|
-
Manages connections to the UnrealOn Adapter.
|
|
52
|
-
|
|
53
|
-
Provides:
|
|
54
|
-
- WebSocket connection for real-time commands
|
|
55
|
-
- HTTP connection for registration and status
|
|
56
|
-
- Automatic reconnection with exponential backoff
|
|
57
|
-
- Health monitoring and error recovery
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
|
-
def __init__(self, config: AdapterConfig, parser_id: str, logger: logging.Logger):
|
|
61
|
-
"""
|
|
62
|
-
Initialize connection manager.
|
|
63
|
-
|
|
64
|
-
Args:
|
|
65
|
-
config: Adapter configuration
|
|
66
|
-
parser_id: Unique parser identifier
|
|
67
|
-
logger: Logger instance
|
|
68
|
-
"""
|
|
69
|
-
self.config = config
|
|
70
|
-
self.parser_id = parser_id
|
|
71
|
-
self.logger = logger
|
|
72
|
-
|
|
73
|
-
# Connection clients
|
|
74
|
-
self._http_client: Optional[HTTPClientWrapper] = None
|
|
75
|
-
self._websocket_client: Optional[WebSocketClientWrapper] = None
|
|
76
|
-
|
|
77
|
-
# State tracking
|
|
78
|
-
self._connected = False
|
|
79
|
-
self._connecting = False
|
|
80
|
-
self._reconnect_count = 0
|
|
81
|
-
self._session_id: Optional[str] = None
|
|
82
|
-
|
|
83
|
-
# Command handling
|
|
84
|
-
self._command_handler: Optional[
|
|
85
|
-
Callable[[ParserCommandEvent], Union[None, Awaitable[None]]]
|
|
86
|
-
] = None
|
|
87
|
-
|
|
88
|
-
self.logger.debug(f"ConnectionManager initialized for parser {parser_id}")
|
|
89
|
-
|
|
90
|
-
async def _call_handler(self, handler: Optional[Callable[..., Any]], *args: Any) -> None:
|
|
91
|
-
"""
|
|
92
|
-
Safely call handler, supporting both sync and async handlers.
|
|
93
|
-
|
|
94
|
-
Args:
|
|
95
|
-
handler: Handler function (sync or async)
|
|
96
|
-
*args: Arguments to pass to handler
|
|
97
|
-
"""
|
|
98
|
-
if handler is None:
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
try:
|
|
102
|
-
result = handler(*args)
|
|
103
|
-
if asyncio.iscoroutine(result):
|
|
104
|
-
await result
|
|
105
|
-
except Exception as e:
|
|
106
|
-
self.logger.error(f"Error in handler: {e}")
|
|
107
|
-
|
|
108
|
-
async def connect(self) -> None:
|
|
109
|
-
"""
|
|
110
|
-
Establish connections to the adapter.
|
|
111
|
-
|
|
112
|
-
Raises:
|
|
113
|
-
ConnectionError: If connection fails
|
|
114
|
-
"""
|
|
115
|
-
if self._connected:
|
|
116
|
-
self.logger.warning("Already connected to adapter")
|
|
117
|
-
return
|
|
118
|
-
|
|
119
|
-
if self._connecting:
|
|
120
|
-
self.logger.warning("Connection already in progress")
|
|
121
|
-
return
|
|
122
|
-
|
|
123
|
-
self._connecting = True
|
|
124
|
-
|
|
125
|
-
try:
|
|
126
|
-
self.logger.info("Establishing connection to UnrealOn Adapter...")
|
|
127
|
-
|
|
128
|
-
# Initialize HTTP client for registration
|
|
129
|
-
self._http_client = HTTPClientWrapper(config=self.config, logger=self.logger)
|
|
130
|
-
await self._http_client.connect()
|
|
131
|
-
|
|
132
|
-
# Initialize WebSocket client for real-time communication
|
|
133
|
-
self._websocket_client = WebSocketClientWrapper(
|
|
134
|
-
config=self.config, parser_id=self.parser_id, logger=self.logger
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
# Set up event handlers
|
|
138
|
-
self._websocket_client.set_command_handler(self._handle_websocket_command)
|
|
139
|
-
self._websocket_client.set_connection_handler(self._handle_connection_event)
|
|
140
|
-
|
|
141
|
-
# Connect WebSocket
|
|
142
|
-
await self._websocket_client.connect()
|
|
143
|
-
|
|
144
|
-
self._connected = True
|
|
145
|
-
self._connecting = False
|
|
146
|
-
self._reconnect_count = 0
|
|
147
|
-
|
|
148
|
-
self.logger.info("Successfully connected to UnrealOn Adapter")
|
|
149
|
-
|
|
150
|
-
except Exception as e:
|
|
151
|
-
self._connecting = False
|
|
152
|
-
self._connected = False
|
|
153
|
-
self.logger.error(f"Failed to connect to adapter: {e}")
|
|
154
|
-
raise ConnectionError(f"Connection failed: {e}")
|
|
155
|
-
|
|
156
|
-
async def disconnect(self) -> None:
|
|
157
|
-
"""Disconnect from the adapter."""
|
|
158
|
-
if not self._connected:
|
|
159
|
-
self.logger.warning("Not connected to adapter")
|
|
160
|
-
return
|
|
161
|
-
|
|
162
|
-
try:
|
|
163
|
-
self.logger.info("Disconnecting from UnrealOn Adapter...")
|
|
164
|
-
|
|
165
|
-
if self._websocket_client:
|
|
166
|
-
await self._websocket_client.disconnect()
|
|
167
|
-
|
|
168
|
-
if self._http_client:
|
|
169
|
-
await self._http_client.disconnect()
|
|
170
|
-
|
|
171
|
-
self._connected = False
|
|
172
|
-
self._session_id = None
|
|
173
|
-
|
|
174
|
-
self.logger.info("Disconnected from UnrealOn Adapter")
|
|
175
|
-
|
|
176
|
-
except Exception as e:
|
|
177
|
-
self.logger.error(f"Error during disconnect: {e}")
|
|
178
|
-
raise
|
|
179
|
-
|
|
180
|
-
async def reconnect(self) -> None:
|
|
181
|
-
"""
|
|
182
|
-
Attempt to reconnect to the adapter.
|
|
183
|
-
|
|
184
|
-
Uses exponential backoff for retry attempts.
|
|
185
|
-
"""
|
|
186
|
-
if self._connecting:
|
|
187
|
-
self.logger.warning("Reconnection already in progress")
|
|
188
|
-
return
|
|
189
|
-
|
|
190
|
-
self._reconnect_count += 1
|
|
191
|
-
|
|
192
|
-
# Calculate backoff delay
|
|
193
|
-
backoff_delay = min(2**self._reconnect_count, 60) # Max 60 seconds
|
|
194
|
-
|
|
195
|
-
self.logger.info(f"Attempting reconnection #{self._reconnect_count} in {backoff_delay}s...")
|
|
196
|
-
await asyncio.sleep(backoff_delay)
|
|
197
|
-
|
|
198
|
-
try:
|
|
199
|
-
# Cleanup existing connections
|
|
200
|
-
if self._connected:
|
|
201
|
-
await self.disconnect()
|
|
202
|
-
|
|
203
|
-
# Attempt new connection
|
|
204
|
-
await self.connect()
|
|
205
|
-
|
|
206
|
-
self.logger.info(f"Reconnection #{self._reconnect_count} successful")
|
|
207
|
-
|
|
208
|
-
except Exception as e:
|
|
209
|
-
self.logger.error(f"Reconnection #{self._reconnect_count} failed: {e}")
|
|
210
|
-
raise
|
|
211
|
-
|
|
212
|
-
async def register_parser(
|
|
213
|
-
self, request: ParserRegistrationRequest
|
|
214
|
-
) -> ParserRegistrationResponse:
|
|
215
|
-
"""
|
|
216
|
-
Register the parser with the adapter.
|
|
217
|
-
|
|
218
|
-
Args:
|
|
219
|
-
request: Registration request data
|
|
220
|
-
|
|
221
|
-
Returns:
|
|
222
|
-
Registration response
|
|
223
|
-
|
|
224
|
-
Raises:
|
|
225
|
-
ConnectionError: If not connected
|
|
226
|
-
AuthenticationError: If authentication fails
|
|
227
|
-
"""
|
|
228
|
-
if not self._http_client:
|
|
229
|
-
raise ConnectionError("HTTP client not initialized")
|
|
230
|
-
|
|
231
|
-
try:
|
|
232
|
-
self.logger.info(f"Registering parser {request.parser_id} with adapter...")
|
|
233
|
-
|
|
234
|
-
response = await self._http_client.register_parser(request)
|
|
235
|
-
|
|
236
|
-
if response.success:
|
|
237
|
-
self._session_id = response.parser_id
|
|
238
|
-
self.logger.info(f"Parser {request.parser_id} registered successfully")
|
|
239
|
-
else:
|
|
240
|
-
self.logger.error(f"Parser registration failed: {response.error}")
|
|
241
|
-
if response.error and "AUTH" in response.error.upper():
|
|
242
|
-
raise AuthenticationError(response.error or "Authentication failed")
|
|
243
|
-
|
|
244
|
-
return response
|
|
245
|
-
|
|
246
|
-
except Exception as e:
|
|
247
|
-
self.logger.error(f"Parser registration failed: {e}")
|
|
248
|
-
raise
|
|
249
|
-
|
|
250
|
-
async def send_response(self, response: Union[SuccessResponse, ErrorResponse]) -> None:
|
|
251
|
-
"""
|
|
252
|
-
Send command response back to adapter.
|
|
253
|
-
|
|
254
|
-
Args:
|
|
255
|
-
response: Command response to send
|
|
256
|
-
|
|
257
|
-
Raises:
|
|
258
|
-
ConnectionError: If not connected
|
|
259
|
-
"""
|
|
260
|
-
if not self._websocket_client:
|
|
261
|
-
raise ConnectionError("WebSocket client not initialized")
|
|
262
|
-
|
|
263
|
-
try:
|
|
264
|
-
await self._websocket_client.send_response(response)
|
|
265
|
-
self.logger.debug(f"Sent response: {response.success}")
|
|
266
|
-
|
|
267
|
-
except Exception as e:
|
|
268
|
-
self.logger.error(f"Failed to send response: {e}")
|
|
269
|
-
raise
|
|
270
|
-
|
|
271
|
-
async def send_log(
|
|
272
|
-
self, level: LogLevel, message: str, context: Optional[LoggingContextMetadata]
|
|
273
|
-
) -> None:
|
|
274
|
-
"""
|
|
275
|
-
Send log entry to adapter.
|
|
276
|
-
|
|
277
|
-
Args:
|
|
278
|
-
level: Log level
|
|
279
|
-
message: Log message
|
|
280
|
-
context: Additional context
|
|
281
|
-
"""
|
|
282
|
-
if not self.config.enable_logging or not self._websocket_client:
|
|
283
|
-
return
|
|
284
|
-
|
|
285
|
-
try:
|
|
286
|
-
# Use proper Pydantic model for logging
|
|
287
|
-
log_request = LoggingRequest(
|
|
288
|
-
level=level,
|
|
289
|
-
message=message,
|
|
290
|
-
source=f"parser.{self.parser_id}",
|
|
291
|
-
context=context.model_dump() if context else None,
|
|
292
|
-
session_id=self._session_id,
|
|
293
|
-
tags=[self.parser_id], # Add parser_id as tag
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
await self._websocket_client.send_log(log_request)
|
|
297
|
-
|
|
298
|
-
except Exception as e:
|
|
299
|
-
self.logger.error(f"Failed to send log entry: {e}")
|
|
300
|
-
|
|
301
|
-
def set_command_handler(
|
|
302
|
-
self, handler: Callable[[ParserCommandEvent], Union[None, Awaitable[None]]]
|
|
303
|
-
) -> None:
|
|
304
|
-
"""
|
|
305
|
-
Set the command handler function.
|
|
306
|
-
|
|
307
|
-
Args:
|
|
308
|
-
handler: Function to handle incoming commands
|
|
309
|
-
"""
|
|
310
|
-
self._command_handler = handler
|
|
311
|
-
self.logger.debug("Command handler registered")
|
|
312
|
-
|
|
313
|
-
def is_connected(self) -> bool:
|
|
314
|
-
"""Check if connected to adapter."""
|
|
315
|
-
return (
|
|
316
|
-
self._connected
|
|
317
|
-
and self._websocket_client is not None
|
|
318
|
-
and self._websocket_client.is_connected()
|
|
319
|
-
)
|
|
320
|
-
|
|
321
|
-
def get_session_id(self) -> Optional[str]:
|
|
322
|
-
"""Get current session ID."""
|
|
323
|
-
return self._session_id
|
|
324
|
-
|
|
325
|
-
def get_reconnect_count(self) -> int:
|
|
326
|
-
"""Get number of reconnection attempts."""
|
|
327
|
-
return self._reconnect_count
|
|
328
|
-
|
|
329
|
-
async def _handle_websocket_command(self, command: ParserCommandEvent) -> None:
|
|
330
|
-
"""
|
|
331
|
-
Handle incoming command from WebSocket.
|
|
332
|
-
|
|
333
|
-
Args:
|
|
334
|
-
command: Command event received
|
|
335
|
-
"""
|
|
336
|
-
self.logger.debug(f"Received WebSocket command: {command.command_id}")
|
|
337
|
-
|
|
338
|
-
await self._call_handler(self._command_handler, command)
|
|
339
|
-
|
|
340
|
-
if self._command_handler is None:
|
|
341
|
-
self.logger.warning(f"No command handler registered for command {command.command_id}")
|
|
342
|
-
|
|
343
|
-
async def _handle_connection_event(
|
|
344
|
-
self, event: str, data: Optional[SDKMetadata] = None
|
|
345
|
-
) -> None:
|
|
346
|
-
"""
|
|
347
|
-
Handle WebSocket connection events.
|
|
348
|
-
|
|
349
|
-
Args:
|
|
350
|
-
event: Event type (connected, disconnected, error)
|
|
351
|
-
data: Event data
|
|
352
|
-
"""
|
|
353
|
-
self.logger.debug(f"WebSocket connection event: {event}")
|
|
354
|
-
|
|
355
|
-
if event == "connected":
|
|
356
|
-
self.logger.info("WebSocket connection established")
|
|
357
|
-
self._connected = True # Set connected on actual connection
|
|
358
|
-
elif event == "disconnected":
|
|
359
|
-
self.logger.warning("WebSocket connection lost")
|
|
360
|
-
# Check if this is a real disconnection or normal cleanup
|
|
361
|
-
if self._websocket_client and not self._websocket_client.is_connected():
|
|
362
|
-
self._connected = False
|
|
363
|
-
self.logger.info("Confirmed disconnection - will attempt reconnect")
|
|
364
|
-
else:
|
|
365
|
-
self.logger.debug("Disconnect event received but connection may still be active")
|
|
366
|
-
elif event == "error":
|
|
367
|
-
error_msg = getattr(data, "error", "Unknown error") if data else "Unknown error"
|
|
368
|
-
self.logger.error(f"WebSocket connection error: {error_msg}")
|
|
369
|
-
self._connected = False
|
|
370
|
-
|
|
371
|
-
async def health_check(self) -> ConnectionHealthStatus:
|
|
372
|
-
"""
|
|
373
|
-
Perform health check of all connections using Pydantic model.
|
|
374
|
-
|
|
375
|
-
Returns:
|
|
376
|
-
ConnectionHealthStatus model - no raw JSON!
|
|
377
|
-
"""
|
|
378
|
-
components = {}
|
|
379
|
-
|
|
380
|
-
# Check HTTP client - returns Pydantic model
|
|
381
|
-
if self._http_client:
|
|
382
|
-
http_health = await self._http_client.health_check()
|
|
383
|
-
components["http"] = http_health.model_dump()
|
|
384
|
-
|
|
385
|
-
# Check WebSocket client - returns Pydantic model
|
|
386
|
-
if self._websocket_client:
|
|
387
|
-
ws_health = await self._websocket_client.health_check()
|
|
388
|
-
components["websocket"] = ws_health.model_dump()
|
|
389
|
-
|
|
390
|
-
# Return Pydantic model - no raw JSON!
|
|
391
|
-
return ConnectionHealthStatus(
|
|
392
|
-
is_healthy=self.is_connected(),
|
|
393
|
-
connection_quality=1.0 if self.is_connected() else 0.0,
|
|
394
|
-
latency_ms=50.0, # Could be measured dynamically
|
|
395
|
-
uptime_seconds=0.0, # Could track actual uptime
|
|
396
|
-
last_heartbeat=datetime.now().isoformat(),
|
|
397
|
-
)
|