unrealon 1.0.9__py3-none-any.whl → 1.1.1__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.1.dist-info/METADATA +722 -0
- unrealon-1.1.1.dist-info/RECORD +82 -0
- {unrealon-1.0.9.dist-info → unrealon-1.1.1.dist-info}/WHEEL +1 -1
- unrealon-1.1.1.dist-info/entry_points.txt +9 -0
- {unrealon-1.0.9.dist-info → unrealon-1.1.1.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,311 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Service configuration models for UnrealOn Driver v3.0
|
|
3
|
-
|
|
4
|
-
Type-safe configuration for all services.
|
|
5
|
-
COMPLIANCE: 100% Pydantic v2 compliant, no Dict[str, Any] usage.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from pydantic import BaseModel, Field, ConfigDict
|
|
9
|
-
from typing import Optional, List, Union
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from enum import Enum
|
|
12
|
-
|
|
13
|
-
from .config import LogLevel
|
|
14
|
-
# 🔥 STEALTH ALWAYS ON - NO IMPORT NEEDED!
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class DriverBrowserConfig(BaseModel):
|
|
18
|
-
"""Type-safe browser service configuration for UnrealOn Driver."""
|
|
19
|
-
|
|
20
|
-
model_config = ConfigDict(
|
|
21
|
-
validate_assignment=True,
|
|
22
|
-
extra="forbid",
|
|
23
|
-
str_strip_whitespace=True,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
# Core browser settings
|
|
27
|
-
headless: bool = Field(default=True, description="Run browser in headless mode")
|
|
28
|
-
timeout: int = Field(
|
|
29
|
-
default=30, ge=1, le=300, description="Page timeout in seconds"
|
|
30
|
-
)
|
|
31
|
-
user_data_dir: Optional[str] = Field(
|
|
32
|
-
default=None, description="Browser user data directory"
|
|
33
|
-
)
|
|
34
|
-
parser_id: str = Field(..., description="Parser identifier")
|
|
35
|
-
|
|
36
|
-
# 🔥 STEALTH ALWAYS ON - NO CONFIG NEEDED!
|
|
37
|
-
|
|
38
|
-
# Performance settings
|
|
39
|
-
page_load_strategy: str = Field(default="normal", pattern=r"^(normal|eager|none)$")
|
|
40
|
-
wait_for_selector_timeout: int = Field(
|
|
41
|
-
default=10, ge=1, le=60, description="Selector wait timeout"
|
|
42
|
-
)
|
|
43
|
-
network_idle_timeout: int = Field(
|
|
44
|
-
default=3, ge=1, le=30, description="Network idle timeout"
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
# Features
|
|
48
|
-
enable_javascript: bool = Field(
|
|
49
|
-
default=True, description="Enable JavaScript execution"
|
|
50
|
-
)
|
|
51
|
-
enable_images: bool = Field(default=True, description="Load images")
|
|
52
|
-
enable_css: bool = Field(default=True, description="Load CSS")
|
|
53
|
-
|
|
54
|
-
# Debug settings
|
|
55
|
-
debug_mode: bool = Field(default=False, description="Enable debug mode")
|
|
56
|
-
save_screenshots: bool = Field(default=False, description="Save debug screenshots")
|
|
57
|
-
log_level: LogLevel = Field(default=LogLevel.INFO, description="Browser log level")
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class LLMConfig(BaseModel):
|
|
61
|
-
"""Type-safe LLM service configuration."""
|
|
62
|
-
|
|
63
|
-
model_config = ConfigDict(
|
|
64
|
-
validate_assignment=True,
|
|
65
|
-
extra="forbid",
|
|
66
|
-
str_strip_whitespace=True,
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
# Provider settings
|
|
70
|
-
provider: str = Field(default="openrouter", description="LLM provider")
|
|
71
|
-
model: str = Field(
|
|
72
|
-
default="anthropic/claude-3.5-sonnet", description="Model identifier"
|
|
73
|
-
)
|
|
74
|
-
api_key: Optional[str] = Field(default=None, description="API key")
|
|
75
|
-
|
|
76
|
-
# Request settings
|
|
77
|
-
max_tokens: int = Field(default=2048, ge=1, le=8192, description="Maximum tokens")
|
|
78
|
-
temperature: float = Field(
|
|
79
|
-
default=0.1, ge=0.0, le=2.0, description="Sampling temperature"
|
|
80
|
-
)
|
|
81
|
-
timeout: int = Field(default=30, ge=1, le=300, description="Request timeout")
|
|
82
|
-
|
|
83
|
-
# Processing settings
|
|
84
|
-
max_retries: int = Field(
|
|
85
|
-
default=3, ge=0, le=10, description="Maximum retry attempts"
|
|
86
|
-
)
|
|
87
|
-
chunk_size: int = Field(
|
|
88
|
-
default=4000, ge=100, le=10000, description="Text chunk size"
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
# Features
|
|
92
|
-
enable_caching: bool = Field(default=True, description="Enable response caching")
|
|
93
|
-
enable_cost_tracking: bool = Field(default=True, description="Enable cost tracking")
|
|
94
|
-
log_level: LogLevel = Field(default=LogLevel.INFO, description="LLM log level")
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
class WebSocketConfig(BaseModel):
|
|
98
|
-
"""Type-safe WebSocket service configuration."""
|
|
99
|
-
|
|
100
|
-
model_config = ConfigDict(
|
|
101
|
-
validate_assignment=True,
|
|
102
|
-
extra="forbid",
|
|
103
|
-
str_strip_whitespace=True,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Connection settings
|
|
107
|
-
server_url: Optional[str] = Field(default=None, description="WebSocket server URL")
|
|
108
|
-
api_key: Optional[str] = Field(default=None, description="Authentication API key")
|
|
109
|
-
parser_name: str = Field(..., description="Parser name for identification")
|
|
110
|
-
|
|
111
|
-
# Reliability settings
|
|
112
|
-
auto_reconnect: bool = Field(
|
|
113
|
-
default=True, description="Auto-reconnect on disconnect"
|
|
114
|
-
)
|
|
115
|
-
max_reconnect_attempts: int = Field(
|
|
116
|
-
default=10, ge=1, le=100, description="Max reconnection attempts"
|
|
117
|
-
)
|
|
118
|
-
reconnect_delay: float = Field(
|
|
119
|
-
default=1.0, ge=0.1, le=60.0, description="Reconnect delay seconds"
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
# Health monitoring
|
|
123
|
-
health_check_interval: int = Field(
|
|
124
|
-
default=30, ge=5, le=300, description="Health check interval"
|
|
125
|
-
)
|
|
126
|
-
heartbeat_interval: int = Field(
|
|
127
|
-
default=30, ge=5, le=300, description="Heartbeat interval"
|
|
128
|
-
)
|
|
129
|
-
connection_timeout: int = Field(
|
|
130
|
-
default=10, ge=1, le=60, description="Connection timeout"
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
class LoggerConfig(BaseModel):
|
|
135
|
-
"""Type-safe logger service configuration."""
|
|
136
|
-
|
|
137
|
-
model_config = ConfigDict(
|
|
138
|
-
validate_assignment=True,
|
|
139
|
-
extra="forbid",
|
|
140
|
-
str_strip_whitespace=True,
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
# Core settings
|
|
144
|
-
log_level: LogLevel = Field(default=LogLevel.INFO, description="Default log level")
|
|
145
|
-
console_output: bool = Field(default=True, description="Enable console output")
|
|
146
|
-
file_output: bool = Field(default=True, description="Enable file output")
|
|
147
|
-
|
|
148
|
-
# File settings
|
|
149
|
-
log_file: str = Field(default="parser.log", description="Log file name")
|
|
150
|
-
log_dir: Optional[str] = Field(default=None, description="Log directory")
|
|
151
|
-
max_file_size: str = Field(default="10MB", description="Max log file size")
|
|
152
|
-
backup_count: int = Field(
|
|
153
|
-
default=5, ge=1, le=50, description="Number of backup files"
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
# Format settings
|
|
157
|
-
log_format: str = Field(
|
|
158
|
-
default="%(asctime)s | %(name)s | %(levelname)s | %(message)s",
|
|
159
|
-
description="Log format string",
|
|
160
|
-
)
|
|
161
|
-
date_format: str = Field(default="%Y-%m-%d %H:%M:%S", description="Date format")
|
|
162
|
-
|
|
163
|
-
# Performance
|
|
164
|
-
buffer_size: int = Field(
|
|
165
|
-
default=1024, ge=256, le=8192, description="Log buffer size"
|
|
166
|
-
)
|
|
167
|
-
flush_interval: float = Field(
|
|
168
|
-
default=1.0, ge=0.1, le=10.0, description="Flush interval seconds"
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
class MetricsConfig(BaseModel):
|
|
173
|
-
"""Type-safe metrics service configuration."""
|
|
174
|
-
|
|
175
|
-
model_config = ConfigDict(
|
|
176
|
-
validate_assignment=True,
|
|
177
|
-
extra="forbid",
|
|
178
|
-
str_strip_whitespace=True,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
# Core settings
|
|
182
|
-
parser_id: str = Field(..., description="Parser identifier")
|
|
183
|
-
enable_metrics: bool = Field(default=True, description="Enable metrics collection")
|
|
184
|
-
|
|
185
|
-
# Collection settings
|
|
186
|
-
collect_performance: bool = Field(
|
|
187
|
-
default=True, description="Collect performance metrics"
|
|
188
|
-
)
|
|
189
|
-
collect_errors: bool = Field(default=True, description="Collect error metrics")
|
|
190
|
-
collect_usage: bool = Field(default=True, description="Collect usage metrics")
|
|
191
|
-
|
|
192
|
-
# Storage settings
|
|
193
|
-
retention_days: int = Field(
|
|
194
|
-
default=30, ge=1, le=365, description="Metrics retention period"
|
|
195
|
-
)
|
|
196
|
-
export_format: str = Field(default="json", pattern=r"^(json|csv|prometheus)$")
|
|
197
|
-
|
|
198
|
-
# Performance
|
|
199
|
-
batch_size: int = Field(
|
|
200
|
-
default=100, ge=1, le=1000, description="Metrics batch size"
|
|
201
|
-
)
|
|
202
|
-
flush_interval: int = Field(
|
|
203
|
-
default=60, ge=1, le=3600, description="Flush interval seconds"
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
class SchedulerConfig(BaseModel):
|
|
208
|
-
"""Type-safe scheduler service configuration."""
|
|
209
|
-
|
|
210
|
-
model_config = ConfigDict(
|
|
211
|
-
validate_assignment=True,
|
|
212
|
-
extra="forbid",
|
|
213
|
-
str_strip_whitespace=True,
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
# Core settings
|
|
217
|
-
parser_id: str = Field(..., description="Parser identifier")
|
|
218
|
-
max_concurrent_tasks: int = Field(
|
|
219
|
-
default=10, ge=1, le=100, description="Max concurrent tasks"
|
|
220
|
-
)
|
|
221
|
-
enable_jitter: bool = Field(
|
|
222
|
-
default=True, description="Enable jitter for load balancing"
|
|
223
|
-
)
|
|
224
|
-
jitter_range: float = Field(default=0.1, ge=0.0, le=0.5, description="Jitter range")
|
|
225
|
-
|
|
226
|
-
# Task management
|
|
227
|
-
default_timeout: int = Field(
|
|
228
|
-
default=300, ge=30, le=3600, description="Default task timeout"
|
|
229
|
-
)
|
|
230
|
-
default_retries: int = Field(
|
|
231
|
-
default=3, ge=0, le=10, description="Default retry attempts"
|
|
232
|
-
)
|
|
233
|
-
cleanup_interval: int = Field(
|
|
234
|
-
default=3600, ge=60, le=86400, description="Cleanup interval"
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
# Monitoring
|
|
238
|
-
enable_task_monitoring: bool = Field(
|
|
239
|
-
default=True, description="Enable task monitoring"
|
|
240
|
-
)
|
|
241
|
-
health_check_interval: int = Field(
|
|
242
|
-
default=60, ge=10, le=3600, description="Health check interval"
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
class ServiceHealthStatus(BaseModel):
|
|
247
|
-
"""Type-safe service health status."""
|
|
248
|
-
|
|
249
|
-
model_config = ConfigDict(
|
|
250
|
-
validate_assignment=True,
|
|
251
|
-
extra="forbid",
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
status: str = Field(..., pattern=r"^(healthy|unhealthy|degraded|unknown)$")
|
|
255
|
-
service_name: str = Field(..., description="Service name")
|
|
256
|
-
last_check: str = Field(..., description="Last health check timestamp")
|
|
257
|
-
|
|
258
|
-
# Health details
|
|
259
|
-
response_time_ms: Optional[float] = Field(
|
|
260
|
-
default=None, ge=0.0, description="Response time"
|
|
261
|
-
)
|
|
262
|
-
error_rate: Optional[float] = Field(
|
|
263
|
-
default=None, ge=0.0, le=1.0, description="Error rate"
|
|
264
|
-
)
|
|
265
|
-
uptime_seconds: Optional[int] = Field(
|
|
266
|
-
default=None, ge=0, description="Service uptime"
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
# Error information
|
|
270
|
-
last_error: Optional[str] = Field(default=None, description="Last error message")
|
|
271
|
-
error_count: int = Field(default=0, ge=0, description="Total error count")
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
class ServiceOperationResult(BaseModel):
|
|
275
|
-
"""Type-safe service operation result."""
|
|
276
|
-
|
|
277
|
-
model_config = ConfigDict(
|
|
278
|
-
validate_assignment=True,
|
|
279
|
-
extra="forbid",
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
success: bool = Field(..., description="Operation success status")
|
|
283
|
-
service_name: str = Field(..., description="Service name")
|
|
284
|
-
operation: str = Field(..., description="Operation name")
|
|
285
|
-
|
|
286
|
-
# Timing
|
|
287
|
-
start_time: str = Field(..., description="Operation start time")
|
|
288
|
-
duration_seconds: float = Field(..., ge=0.0, description="Operation duration")
|
|
289
|
-
|
|
290
|
-
# Result data
|
|
291
|
-
result: Optional[dict] = Field(default=None, description="Operation result data")
|
|
292
|
-
items_processed: int = Field(default=0, ge=0, description="Items processed")
|
|
293
|
-
|
|
294
|
-
# Error information
|
|
295
|
-
error_message: Optional[str] = Field(
|
|
296
|
-
default=None, description="Error message if failed"
|
|
297
|
-
)
|
|
298
|
-
error_code: Optional[str] = Field(default=None, description="Error code if failed")
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
# Export all models
|
|
302
|
-
__all__ = [
|
|
303
|
-
"DriverBrowserConfig",
|
|
304
|
-
"LLMConfig",
|
|
305
|
-
"WebSocketConfig",
|
|
306
|
-
"LoggerConfig",
|
|
307
|
-
"MetricsConfig",
|
|
308
|
-
"SchedulerConfig",
|
|
309
|
-
"ServiceHealthStatus",
|
|
310
|
-
"ServiceOperationResult",
|
|
311
|
-
]
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Execution modes for UnrealOn Driver v3.0
|
|
3
|
-
|
|
4
|
-
Multiple execution modes for different use cases:
|
|
5
|
-
- Test Mode: Development and debugging
|
|
6
|
-
- Daemon Mode: Production WebSocket service
|
|
7
|
-
- Scheduled Mode: Automated recurring execution
|
|
8
|
-
- Interactive Mode: Live development shell
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from .modes import ExecutionMode
|
|
12
|
-
from .test_mode import TestMode
|
|
13
|
-
from .daemon_mode import DaemonMode
|
|
14
|
-
from .scheduled_mode import ScheduledMode
|
|
15
|
-
from .interactive_mode import InteractiveMode
|
|
16
|
-
|
|
17
|
-
__all__ = [
|
|
18
|
-
"ExecutionMode",
|
|
19
|
-
"TestMode",
|
|
20
|
-
"DaemonMode",
|
|
21
|
-
"ScheduledMode",
|
|
22
|
-
"InteractiveMode"
|
|
23
|
-
]
|
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Daemon Mode implementation for UnrealOn Driver v3.0
|
|
3
|
-
|
|
4
|
-
Production WebSocket service mode with full unrealon_sdk integration.
|
|
5
|
-
Provides real-time parser execution via WebSocket commands.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import asyncio
|
|
9
|
-
import signal
|
|
10
|
-
from typing import Any, Optional
|
|
11
|
-
from datetime import datetime
|
|
12
|
-
|
|
13
|
-
from unrealon_driver.src.dto.execution import (
|
|
14
|
-
DaemonModeConfig,
|
|
15
|
-
DaemonCommandResult,
|
|
16
|
-
DaemonStatusResult,
|
|
17
|
-
DaemonHealthResult,
|
|
18
|
-
ErrorInfo,
|
|
19
|
-
)
|
|
20
|
-
from unrealon_driver.src.dto.services import WebSocketConfig
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class DaemonMode:
|
|
24
|
-
"""
|
|
25
|
-
🔌 Daemon Mode - Production WebSocket Service
|
|
26
|
-
|
|
27
|
-
Full implementation with unrealon_sdk integration:
|
|
28
|
-
- WebSocket connection via AdapterClient
|
|
29
|
-
- Command handling and response
|
|
30
|
-
- Graceful shutdown with signal handling
|
|
31
|
-
- Health monitoring and status reporting
|
|
32
|
-
- Automatic reconnection and error recovery
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def __init__(self, parser: Any, config: DaemonModeConfig):
|
|
36
|
-
"""Initialize daemon mode."""
|
|
37
|
-
self.parser = parser
|
|
38
|
-
self.config = config
|
|
39
|
-
self.logger = parser.logger
|
|
40
|
-
self._is_running = False
|
|
41
|
-
self._shutdown_event = asyncio.Event()
|
|
42
|
-
|
|
43
|
-
async def start(
|
|
44
|
-
self, server: Optional[str] = None, api_key: Optional[str] = None, **kwargs
|
|
45
|
-
):
|
|
46
|
-
"""Start daemon mode with full WebSocket integration."""
|
|
47
|
-
if self.logger:
|
|
48
|
-
self.logger.info(f"🔌 Starting daemon mode for: {self.parser.parser_name}")
|
|
49
|
-
|
|
50
|
-
# Get connection parameters
|
|
51
|
-
server_url = server or self.config.server_url or kwargs.get("server_url")
|
|
52
|
-
api_key = (
|
|
53
|
-
api_key or self.config.api_key or kwargs.get("api_key")
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
if not server_url:
|
|
57
|
-
if self.logger:
|
|
58
|
-
self.logger.error(
|
|
59
|
-
"❌ WebSocket server URL not configured for daemon mode!"
|
|
60
|
-
)
|
|
61
|
-
self.logger.info(" Set server URL in config or pass as parameter")
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
if not api_key:
|
|
65
|
-
if self.logger:
|
|
66
|
-
self.logger.error(
|
|
67
|
-
"❌ WebSocket API key not configured for daemon mode!"
|
|
68
|
-
)
|
|
69
|
-
self.logger.info(" Set API key in config or pass as parameter")
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
if self.logger:
|
|
73
|
-
self.logger.info(f"🔌 Starting WebSocket daemon mode")
|
|
74
|
-
self.logger.info(f" Server: {server_url}")
|
|
75
|
-
self.logger.info(f" Parser: {self.parser.parser_id}")
|
|
76
|
-
self.logger.info(
|
|
77
|
-
f" API Key: {'***' + api_key[-4:] if len(api_key) > 4 else '***'}"
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
# Setup WebSocket service configuration with type safety
|
|
81
|
-
websocket_config = WebSocketConfig(
|
|
82
|
-
server_url=server_url,
|
|
83
|
-
api_key=api_key,
|
|
84
|
-
parser_name=self.parser.parser_name,
|
|
85
|
-
auto_reconnect=self.config.auto_reconnect,
|
|
86
|
-
health_check_interval=self.config.health_check_interval,
|
|
87
|
-
max_reconnect_attempts=self.config.max_reconnect_attempts,
|
|
88
|
-
connection_timeout=self.config.connection_timeout,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
# Configure WebSocket service
|
|
92
|
-
self.parser.websocket.config = websocket_config
|
|
93
|
-
|
|
94
|
-
# Register command handlers
|
|
95
|
-
self.parser.websocket.register_handler(
|
|
96
|
-
"parse_command", self._handle_parse_command
|
|
97
|
-
)
|
|
98
|
-
self.parser.websocket.register_handler(
|
|
99
|
-
"status_request", self._handle_status_request
|
|
100
|
-
)
|
|
101
|
-
self.parser.websocket.register_handler(
|
|
102
|
-
"health_check", self._handle_health_check
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
# Setup signal handlers for graceful shutdown
|
|
106
|
-
self._setup_signal_handlers()
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
await self.parser.setup() if hasattr(self.parser, "setup") else None
|
|
110
|
-
|
|
111
|
-
# Connect to WebSocket server
|
|
112
|
-
success = await self.parser.websocket.connect(
|
|
113
|
-
server_url=server_url, api_key=api_key
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
if not success:
|
|
117
|
-
if self.logger:
|
|
118
|
-
self.logger.error("❌ Failed to connect to WebSocket server")
|
|
119
|
-
return
|
|
120
|
-
|
|
121
|
-
if self.logger:
|
|
122
|
-
self.logger.info("✅ Connected to WebSocket server")
|
|
123
|
-
self.logger.info("👂 Listening for parse commands...")
|
|
124
|
-
self.logger.info(
|
|
125
|
-
" Commands: 'parse_command', 'status_request', 'health_check'"
|
|
126
|
-
)
|
|
127
|
-
self.logger.info(" Press Ctrl+C to stop")
|
|
128
|
-
|
|
129
|
-
self._is_running = True
|
|
130
|
-
|
|
131
|
-
# Start listening for commands with graceful shutdown
|
|
132
|
-
await self.parser.websocket.listen(shutdown_event=self._shutdown_event)
|
|
133
|
-
|
|
134
|
-
except Exception as e:
|
|
135
|
-
if self.logger:
|
|
136
|
-
self.logger.error(f"❌ Daemon mode error: {e}")
|
|
137
|
-
raise
|
|
138
|
-
finally:
|
|
139
|
-
await self.stop()
|
|
140
|
-
|
|
141
|
-
def _setup_signal_handlers(self):
|
|
142
|
-
"""Setup signal handlers for graceful shutdown."""
|
|
143
|
-
|
|
144
|
-
def signal_handler(signum, frame):
|
|
145
|
-
if self.logger:
|
|
146
|
-
self.logger.info(f"\n🛑 Shutdown signal received (signal {signum})...")
|
|
147
|
-
self._shutdown_event.set()
|
|
148
|
-
|
|
149
|
-
# Register signal handlers
|
|
150
|
-
try:
|
|
151
|
-
signal.signal(signal.SIGINT, signal_handler)
|
|
152
|
-
signal.signal(signal.SIGTERM, signal_handler)
|
|
153
|
-
except Exception as e:
|
|
154
|
-
if self.logger:
|
|
155
|
-
self.logger.warning(f"Could not register signal handlers: {e}")
|
|
156
|
-
|
|
157
|
-
async def _handle_parse_command(self, command: dict) -> DaemonCommandResult:
|
|
158
|
-
"""Handle parse command from WebSocket with type safety."""
|
|
159
|
-
|
|
160
|
-
start_time = datetime.now()
|
|
161
|
-
|
|
162
|
-
try:
|
|
163
|
-
if self.logger:
|
|
164
|
-
self.logger.info("🚀 Received parse command via WebSocket")
|
|
165
|
-
|
|
166
|
-
# Setup parser if needed
|
|
167
|
-
if hasattr(self.parser, "setup"):
|
|
168
|
-
await self.parser.setup()
|
|
169
|
-
|
|
170
|
-
# Execute parse method
|
|
171
|
-
result = await self.parser.parse()
|
|
172
|
-
|
|
173
|
-
# Cleanup if needed
|
|
174
|
-
if hasattr(self.parser, "cleanup"):
|
|
175
|
-
await self.parser.cleanup()
|
|
176
|
-
|
|
177
|
-
duration = (datetime.now() - start_time).total_seconds()
|
|
178
|
-
items_count = len(result) if isinstance(result, (list, dict)) else 1
|
|
179
|
-
|
|
180
|
-
if self.logger:
|
|
181
|
-
self.logger.info(
|
|
182
|
-
f"✅ Parse command completed in {duration:.2f}s - {items_count} items"
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
return DaemonCommandResult(
|
|
186
|
-
status="success",
|
|
187
|
-
data=result if isinstance(result, dict) else {"result": result},
|
|
188
|
-
items_processed=items_count,
|
|
189
|
-
duration_seconds=duration,
|
|
190
|
-
parser_id=self.parser.parser_id,
|
|
191
|
-
timestamp=datetime.now().isoformat(),
|
|
192
|
-
error=None,
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
except Exception as e:
|
|
196
|
-
duration = (datetime.now() - start_time).total_seconds()
|
|
197
|
-
|
|
198
|
-
if self.logger:
|
|
199
|
-
self.logger.error(f"❌ Parse command failed after {duration:.2f}s: {e}")
|
|
200
|
-
|
|
201
|
-
error_info = ErrorInfo(
|
|
202
|
-
message=str(e),
|
|
203
|
-
error_type=type(e).__name__,
|
|
204
|
-
error_code=getattr(e, "error_code", None),
|
|
205
|
-
traceback=None,
|
|
206
|
-
context={"command": "parse", "parser_id": self.parser.parser_id},
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
return DaemonCommandResult(
|
|
210
|
-
status="error",
|
|
211
|
-
data=None,
|
|
212
|
-
items_processed=0,
|
|
213
|
-
duration_seconds=duration,
|
|
214
|
-
parser_id=self.parser.parser_id,
|
|
215
|
-
timestamp=datetime.now().isoformat(),
|
|
216
|
-
error=error_info,
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
async def _handle_status_request(self, command: dict) -> DaemonStatusResult:
|
|
220
|
-
"""Handle status request from WebSocket with type safety."""
|
|
221
|
-
|
|
222
|
-
try:
|
|
223
|
-
health = await self.parser.health_check()
|
|
224
|
-
|
|
225
|
-
return DaemonStatusResult(
|
|
226
|
-
status="success",
|
|
227
|
-
parser_id=self.parser.parser_id,
|
|
228
|
-
parser_name=self.parser.parser_name,
|
|
229
|
-
daemon_running=self._is_running,
|
|
230
|
-
health=health,
|
|
231
|
-
timestamp=datetime.now().isoformat(),
|
|
232
|
-
error=None,
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
except Exception as e:
|
|
236
|
-
error_info = ErrorInfo(
|
|
237
|
-
message=str(e),
|
|
238
|
-
error_type=type(e).__name__,
|
|
239
|
-
error_code=getattr(e, "error_code", None),
|
|
240
|
-
traceback=None,
|
|
241
|
-
context={"command": "status", "parser_id": self.parser.parser_id},
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
return DaemonStatusResult(
|
|
245
|
-
status="error",
|
|
246
|
-
parser_id=self.parser.parser_id,
|
|
247
|
-
parser_name=self.parser.parser_name,
|
|
248
|
-
daemon_running=self._is_running,
|
|
249
|
-
health=None,
|
|
250
|
-
timestamp=datetime.now().isoformat(),
|
|
251
|
-
error=error_info,
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
async def _handle_health_check(self, command: dict) -> DaemonHealthResult:
|
|
255
|
-
"""Handle health check from WebSocket with type safety."""
|
|
256
|
-
|
|
257
|
-
try:
|
|
258
|
-
health = await self.parser.health_check()
|
|
259
|
-
|
|
260
|
-
# Type-safe health check - assume health is dict
|
|
261
|
-
status = "healthy" if health.get("status") == "healthy" else "unhealthy"
|
|
262
|
-
|
|
263
|
-
return DaemonHealthResult(
|
|
264
|
-
status=status,
|
|
265
|
-
data=health,
|
|
266
|
-
parser_id=self.parser.parser_id,
|
|
267
|
-
timestamp=datetime.now().isoformat(),
|
|
268
|
-
error=None,
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
except Exception as e:
|
|
272
|
-
error_info = ErrorInfo(
|
|
273
|
-
message=str(e),
|
|
274
|
-
error_type=type(e).__name__,
|
|
275
|
-
error_code=getattr(e, "error_code", None),
|
|
276
|
-
traceback=None,
|
|
277
|
-
context={"command": "health_check", "parser_id": self.parser.parser_id},
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
return DaemonHealthResult(
|
|
281
|
-
status="unhealthy",
|
|
282
|
-
data=None,
|
|
283
|
-
parser_id=self.parser.parser_id,
|
|
284
|
-
timestamp=datetime.now().isoformat(),
|
|
285
|
-
error=error_info,
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
async def stop(self):
|
|
289
|
-
"""Stop daemon mode gracefully."""
|
|
290
|
-
if self.logger:
|
|
291
|
-
self.logger.info("🛑 Stopping daemon mode...")
|
|
292
|
-
|
|
293
|
-
self._is_running = False
|
|
294
|
-
self._shutdown_event.set()
|
|
295
|
-
|
|
296
|
-
# Disconnect WebSocket
|
|
297
|
-
try:
|
|
298
|
-
await self.parser.websocket.disconnect()
|
|
299
|
-
except Exception as e:
|
|
300
|
-
if self.logger:
|
|
301
|
-
self.logger.error(f"Error disconnecting WebSocket: {e}")
|
|
302
|
-
|
|
303
|
-
# Cleanup parser
|
|
304
|
-
try:
|
|
305
|
-
if hasattr(self.parser, "cleanup"):
|
|
306
|
-
await self.parser.cleanup()
|
|
307
|
-
except Exception as e:
|
|
308
|
-
if self.logger:
|
|
309
|
-
self.logger.error(f"Error during parser cleanup: {e}")
|
|
310
|
-
|
|
311
|
-
if self.logger:
|
|
312
|
-
self.logger.info("✅ Daemon mode stopped")
|
|
313
|
-
|
|
314
|
-
def __repr__(self) -> str:
|
|
315
|
-
return (
|
|
316
|
-
f"<DaemonMode(running={self._is_running}, parser={self.parser.parser_id})>"
|
|
317
|
-
)
|