unrealon 1.1.6__py3-none-any.whl → 2.0.5__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-1.1.6.dist-info/licenses → unrealon-2.0.5.dist-info}/LICENSE +1 -1
- unrealon-2.0.5.dist-info/METADATA +491 -0
- unrealon-2.0.5.dist-info/RECORD +128 -0
- {unrealon-1.1.6.dist-info → unrealon-2.0.5.dist-info}/WHEEL +2 -1
- unrealon-2.0.5.dist-info/entry_points.txt +3 -0
- unrealon-2.0.5.dist-info/top_level.txt +3 -0
- unrealon_browser/__init__.py +5 -6
- unrealon_browser/cli/browser_cli.py +18 -9
- unrealon_browser/cli/interactive_mode.py +13 -4
- unrealon_browser/core/browser_manager.py +29 -16
- unrealon_browser/dto/__init__.py +21 -0
- unrealon_browser/dto/bot_detection.py +175 -0
- unrealon_browser/dto/models/config.py +9 -3
- unrealon_browser/managers/__init__.py +1 -1
- unrealon_browser/managers/logger_bridge.py +1 -4
- unrealon_browser/stealth/__init__.py +27 -0
- unrealon_browser/stealth/bypass_techniques.pyc +0 -0
- unrealon_browser/stealth/manager.pyc +0 -0
- unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
- unrealon_browser/stealth/playwright_stealth.pyc +0 -0
- unrealon_browser/stealth/scanner_tester.pyc +0 -0
- unrealon_browser/stealth/undetected_chrome.pyc +0 -0
- unrealon_core/__init__.py +172 -0
- unrealon_core/config/__init__.py +16 -0
- unrealon_core/config/environment.py +151 -0
- unrealon_core/config/urls.py +94 -0
- unrealon_core/enums/__init__.py +24 -0
- unrealon_core/enums/status.py +216 -0
- unrealon_core/enums/types.py +240 -0
- unrealon_core/error_handling/__init__.py +45 -0
- unrealon_core/error_handling/circuit_breaker.py +292 -0
- unrealon_core/error_handling/error_context.py +324 -0
- unrealon_core/error_handling/recovery.py +371 -0
- unrealon_core/error_handling/retry.py +268 -0
- unrealon_core/exceptions/__init__.py +46 -0
- unrealon_core/exceptions/base.py +292 -0
- unrealon_core/exceptions/communication.py +22 -0
- unrealon_core/exceptions/driver.py +11 -0
- unrealon_core/exceptions/proxy.py +11 -0
- unrealon_core/exceptions/task.py +12 -0
- unrealon_core/exceptions/validation.py +17 -0
- unrealon_core/models/__init__.py +79 -0
- unrealon_core/models/arq_context.py +252 -0
- unrealon_core/models/arq_responses.py +125 -0
- unrealon_core/models/base.py +291 -0
- unrealon_core/models/bridge_stats.py +58 -0
- unrealon_core/models/communication.py +39 -0
- unrealon_core/models/connection_stats.py +47 -0
- unrealon_core/models/driver.py +30 -0
- unrealon_core/models/driver_details.py +98 -0
- unrealon_core/models/logging.py +28 -0
- unrealon_core/models/task.py +21 -0
- unrealon_core/models/typed_responses.py +210 -0
- unrealon_core/models/websocket/__init__.py +91 -0
- unrealon_core/models/websocket/base.py +49 -0
- unrealon_core/models/websocket/config.py +200 -0
- unrealon_core/models/websocket/driver.py +215 -0
- unrealon_core/models/websocket/errors.py +138 -0
- unrealon_core/models/websocket/heartbeat.py +100 -0
- unrealon_core/models/websocket/logging.py +261 -0
- unrealon_core/models/websocket/proxy.py +496 -0
- unrealon_core/models/websocket/tasks.py +275 -0
- unrealon_core/models/websocket/utils.py +153 -0
- unrealon_core/models/websocket_session.py +144 -0
- unrealon_core/monitoring/__init__.py +43 -0
- unrealon_core/monitoring/alerts.py +398 -0
- unrealon_core/monitoring/dashboard.py +307 -0
- unrealon_core/monitoring/health_check.py +354 -0
- unrealon_core/monitoring/metrics.py +352 -0
- unrealon_core/utils/__init__.py +11 -0
- unrealon_core/utils/time.py +61 -0
- unrealon_core/version.py +219 -0
- unrealon_driver/__init__.py +90 -51
- unrealon_driver/core_module/__init__.py +34 -0
- unrealon_driver/core_module/base.py +184 -0
- unrealon_driver/core_module/config.py +30 -0
- unrealon_driver/core_module/event_manager.py +127 -0
- unrealon_driver/core_module/protocols.py +98 -0
- unrealon_driver/core_module/registry.py +146 -0
- unrealon_driver/decorators/__init__.py +15 -0
- unrealon_driver/decorators/retry.py +117 -0
- unrealon_driver/decorators/schedule.py +137 -0
- unrealon_driver/decorators/task.py +61 -0
- unrealon_driver/decorators/timing.py +132 -0
- unrealon_driver/driver/__init__.py +20 -0
- unrealon_driver/driver/communication/__init__.py +10 -0
- unrealon_driver/driver/communication/session.py +203 -0
- unrealon_driver/driver/communication/websocket_client.py +205 -0
- unrealon_driver/driver/core/__init__.py +10 -0
- unrealon_driver/driver/core/config.py +175 -0
- unrealon_driver/driver/core/driver.py +221 -0
- unrealon_driver/driver/factory/__init__.py +9 -0
- unrealon_driver/driver/factory/manager_factory.py +130 -0
- unrealon_driver/driver/lifecycle/__init__.py +11 -0
- unrealon_driver/driver/lifecycle/daemon.py +76 -0
- unrealon_driver/driver/lifecycle/initialization.py +97 -0
- unrealon_driver/driver/lifecycle/shutdown.py +48 -0
- unrealon_driver/driver/monitoring/__init__.py +9 -0
- unrealon_driver/driver/monitoring/health.py +63 -0
- unrealon_driver/driver/utilities/__init__.py +10 -0
- unrealon_driver/driver/utilities/logging.py +51 -0
- unrealon_driver/driver/utilities/serialization.py +61 -0
- unrealon_driver/managers/__init__.py +32 -0
- unrealon_driver/managers/base.py +174 -0
- unrealon_driver/managers/browser.py +98 -0
- unrealon_driver/managers/cache.py +116 -0
- unrealon_driver/managers/http.py +107 -0
- unrealon_driver/managers/logger.py +286 -0
- unrealon_driver/managers/proxy.py +99 -0
- unrealon_driver/managers/registry.py +87 -0
- unrealon_driver/managers/threading.py +54 -0
- unrealon_driver/managers/update.py +107 -0
- unrealon_driver/utils/__init__.py +9 -0
- unrealon_driver/utils/time.py +10 -0
- unrealon-1.1.6.dist-info/METADATA +0 -625
- unrealon-1.1.6.dist-info/RECORD +0 -55
- unrealon-1.1.6.dist-info/entry_points.txt +0 -9
- unrealon_browser/managers/stealth.py +0 -388
- unrealon_driver/README.md +0 -0
- unrealon_driver/exceptions.py +0 -33
- unrealon_driver/html_analyzer/__init__.py +0 -32
- unrealon_driver/html_analyzer/cleaner.py +0 -657
- unrealon_driver/html_analyzer/config.py +0 -64
- unrealon_driver/html_analyzer/manager.py +0 -247
- unrealon_driver/html_analyzer/models.py +0 -115
- unrealon_driver/html_analyzer/websocket_analyzer.py +0 -157
- unrealon_driver/models/__init__.py +0 -31
- unrealon_driver/models/websocket.py +0 -98
- unrealon_driver/parser/__init__.py +0 -36
- unrealon_driver/parser/cli_manager.py +0 -142
- unrealon_driver/parser/daemon_manager.py +0 -403
- unrealon_driver/parser/managers/__init__.py +0 -25
- unrealon_driver/parser/managers/config.py +0 -293
- unrealon_driver/parser/managers/error.py +0 -412
- unrealon_driver/parser/managers/result.py +0 -321
- unrealon_driver/parser/parser_manager.py +0 -458
- unrealon_driver/smart_logging/__init__.py +0 -24
- unrealon_driver/smart_logging/models.py +0 -44
- unrealon_driver/smart_logging/smart_logger.py +0 -406
- unrealon_driver/smart_logging/unified_logger.py +0 -525
- unrealon_driver/websocket/__init__.py +0 -31
- unrealon_driver/websocket/client.py +0 -249
- unrealon_driver/websocket/config.py +0 -188
- unrealon_driver/websocket/manager.py +0 -90
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Typed Response Models
|
|
3
|
+
|
|
4
|
+
Strictly typed models to replace Dict[str, Any] usage.
|
|
5
|
+
Following critical requirements - no raw Dict[str, Any].
|
|
6
|
+
|
|
7
|
+
Phase 2: Core Systems - Typed Responses
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from typing import Optional, List
|
|
12
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
13
|
+
|
|
14
|
+
from .base import UnrealOnBaseModel
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HealthCheckDetails(UnrealOnBaseModel):
|
|
18
|
+
"""Health check details model."""
|
|
19
|
+
|
|
20
|
+
model_config = ConfigDict(
|
|
21
|
+
validate_assignment=True,
|
|
22
|
+
extra="forbid"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
manager_status: str = Field(description="Manager status")
|
|
26
|
+
success_rate: float = Field(description="Success rate percentage")
|
|
27
|
+
total_operations: int = Field(description="Total operations count")
|
|
28
|
+
uptime_seconds: float = Field(description="Uptime in seconds")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class HealthCheckResult(UnrealOnBaseModel):
|
|
32
|
+
"""Health check result model."""
|
|
33
|
+
|
|
34
|
+
model_config = ConfigDict(
|
|
35
|
+
validate_assignment=True,
|
|
36
|
+
extra="forbid"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
status: str = Field(description="Health status")
|
|
40
|
+
message: str = Field(description="Health message")
|
|
41
|
+
details: HealthCheckDetails = Field(description="Health details")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class StatusInfo(UnrealOnBaseModel):
|
|
45
|
+
"""Status information model."""
|
|
46
|
+
|
|
47
|
+
model_config = ConfigDict(
|
|
48
|
+
validate_assignment=True,
|
|
49
|
+
extra="forbid"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
name: str = Field(description="Component name")
|
|
53
|
+
status: str = Field(description="Component status")
|
|
54
|
+
enabled: bool = Field(description="Whether component is enabled")
|
|
55
|
+
uptime_seconds: Optional[float] = Field(default=None, description="Uptime in seconds")
|
|
56
|
+
initialization_time: Optional[str] = Field(default=None, description="Initialization time ISO string")
|
|
57
|
+
shutdown_time: Optional[str] = Field(default=None, description="Shutdown time ISO string")
|
|
58
|
+
stats: "StatsModel" = Field(description="Component statistics")
|
|
59
|
+
config: "ConfigModel" = Field(description="Component configuration")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class StatsModel(UnrealOnBaseModel):
|
|
63
|
+
"""Statistics model."""
|
|
64
|
+
|
|
65
|
+
model_config = ConfigDict(
|
|
66
|
+
validate_assignment=True,
|
|
67
|
+
extra="forbid"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
operations_total: int = Field(default=0, description="Total operations")
|
|
71
|
+
operations_successful: int = Field(default=0, description="Successful operations")
|
|
72
|
+
operations_failed: int = Field(default=0, description="Failed operations")
|
|
73
|
+
last_operation_time: Optional[str] = Field(default=None, description="Last operation time ISO string")
|
|
74
|
+
average_operation_time: float = Field(default=0.0, description="Average operation time")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ConfigModel(UnrealOnBaseModel):
|
|
78
|
+
"""Configuration model."""
|
|
79
|
+
|
|
80
|
+
model_config = ConfigDict(
|
|
81
|
+
validate_assignment=True,
|
|
82
|
+
extra="forbid"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
enabled: bool = Field(description="Whether enabled")
|
|
86
|
+
timeout_seconds: float = Field(description="Timeout in seconds")
|
|
87
|
+
retry_count: int = Field(description="Retry count")
|
|
88
|
+
log_level: str = Field(description="Log level")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class SessionInfo(UnrealOnBaseModel):
|
|
92
|
+
"""HTTP session information model."""
|
|
93
|
+
|
|
94
|
+
model_config = ConfigDict(
|
|
95
|
+
validate_assignment=True,
|
|
96
|
+
extra="forbid"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
cookies_count: int = Field(description="Number of cookies")
|
|
100
|
+
has_proxy_manager: bool = Field(description="Whether proxy manager is available")
|
|
101
|
+
use_proxy_manager: bool = Field(description="Whether using proxy manager")
|
|
102
|
+
max_connections: int = Field(description="Maximum connections")
|
|
103
|
+
default_timeout: float = Field(description="Default timeout")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ProxyStats(UnrealOnBaseModel):
|
|
107
|
+
"""Proxy statistics model."""
|
|
108
|
+
|
|
109
|
+
model_config = ConfigDict(
|
|
110
|
+
validate_assignment=True,
|
|
111
|
+
extra="forbid"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
total_proxies: int = Field(description="Total proxies")
|
|
115
|
+
healthy_proxies: int = Field(description="Healthy proxies")
|
|
116
|
+
banned_proxies: int = Field(description="Banned proxies")
|
|
117
|
+
average_success_rate: float = Field(description="Average success rate")
|
|
118
|
+
rotation_strategy: str = Field(description="Rotation strategy")
|
|
119
|
+
current_index: int = Field(description="Current rotation index")
|
|
120
|
+
has_rpc_client: bool = Field(description="Whether RPC client is available")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class ThreadStats(UnrealOnBaseModel):
|
|
124
|
+
"""Thread statistics model."""
|
|
125
|
+
|
|
126
|
+
model_config = ConfigDict(
|
|
127
|
+
validate_assignment=True,
|
|
128
|
+
extra="forbid"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
thread_pools: "ThreadPoolsInfo" = Field(description="Thread pools information")
|
|
132
|
+
concurrency: "ConcurrencyInfo" = Field(description="Concurrency information")
|
|
133
|
+
active_task_names: List[str] = Field(description="Active task names")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class ThreadPoolsInfo(UnrealOnBaseModel):
|
|
137
|
+
"""Thread pools information model."""
|
|
138
|
+
|
|
139
|
+
model_config = ConfigDict(
|
|
140
|
+
validate_assignment=True,
|
|
141
|
+
extra="forbid"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
io_bound: "ThreadPoolInfo" = Field(description="I/O bound thread pool")
|
|
145
|
+
cpu_bound: "ThreadPoolInfo" = Field(description="CPU bound thread pool")
|
|
146
|
+
general: "ThreadPoolInfo" = Field(description="General thread pool")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class ThreadPoolInfo(UnrealOnBaseModel):
|
|
150
|
+
"""Thread pool information model."""
|
|
151
|
+
|
|
152
|
+
model_config = ConfigDict(
|
|
153
|
+
validate_assignment=True,
|
|
154
|
+
extra="forbid"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
max_workers: int = Field(description="Maximum workers")
|
|
158
|
+
available: bool = Field(description="Whether available")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class ConcurrencyInfo(UnrealOnBaseModel):
|
|
162
|
+
"""Concurrency information model."""
|
|
163
|
+
|
|
164
|
+
model_config = ConfigDict(
|
|
165
|
+
validate_assignment=True,
|
|
166
|
+
extra="forbid"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
max_concurrent_tasks: int = Field(description="Maximum concurrent tasks")
|
|
170
|
+
active_tasks: int = Field(description="Active tasks")
|
|
171
|
+
semaphore_available: int = Field(description="Available semaphore permits")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class CacheStats(UnrealOnBaseModel):
|
|
175
|
+
"""Cache statistics model."""
|
|
176
|
+
|
|
177
|
+
model_config = ConfigDict(
|
|
178
|
+
validate_assignment=True,
|
|
179
|
+
extra="forbid"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
entries: int = Field(description="Number of entries")
|
|
183
|
+
max_entries: int = Field(description="Maximum entries")
|
|
184
|
+
memory_usage_mb: float = Field(description="Memory usage in MB")
|
|
185
|
+
max_memory_mb: int = Field(description="Maximum memory in MB")
|
|
186
|
+
hits: int = Field(description="Cache hits")
|
|
187
|
+
misses: int = Field(description="Cache misses")
|
|
188
|
+
hit_rate_percent: float = Field(description="Hit rate percentage")
|
|
189
|
+
evictions: int = Field(description="Number of evictions")
|
|
190
|
+
eviction_strategy: str = Field(description="Eviction strategy")
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class BatchStats(UnrealOnBaseModel):
|
|
194
|
+
"""Batch statistics model."""
|
|
195
|
+
|
|
196
|
+
model_config = ConfigDict(
|
|
197
|
+
validate_assignment=True,
|
|
198
|
+
extra="forbid"
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
current_batch_size: int = Field(description="Current batch size")
|
|
202
|
+
max_batch_size: int = Field(description="Maximum batch size")
|
|
203
|
+
batch_timeout: float = Field(description="Batch timeout")
|
|
204
|
+
has_rpc_client: bool = Field(description="Whether RPC client is available")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# Update forward references
|
|
208
|
+
StatusInfo.model_rebuild()
|
|
209
|
+
ThreadStats.model_rebuild()
|
|
210
|
+
ThreadPoolsInfo.model_rebuild()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
WebSocket Models Package.
|
|
3
|
+
|
|
4
|
+
Strictly typed WebSocket communication models following critical requirements:
|
|
5
|
+
- No raw Dict[str, Any] usage
|
|
6
|
+
- 100% Pydantic v2 validation
|
|
7
|
+
- Files under 500 lines each
|
|
8
|
+
- Complete type safety
|
|
9
|
+
|
|
10
|
+
Phase 2: Core Systems - WebSocket Bridge
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .base import MessageType, WebSocketMessage
|
|
14
|
+
from .driver import (
|
|
15
|
+
DriverRegistrationData, DriverRegistrationMessage,
|
|
16
|
+
RegistrationResponseData, RegistrationResponseMessage
|
|
17
|
+
)
|
|
18
|
+
from .tasks import (
|
|
19
|
+
TaskAssignmentData, TaskAssignmentMessage,
|
|
20
|
+
TaskResultData, TaskResultMessage
|
|
21
|
+
)
|
|
22
|
+
from .logging import (
|
|
23
|
+
LogEntryData, LogEntryMessage,
|
|
24
|
+
LogBatchData, LogBatchMessage
|
|
25
|
+
)
|
|
26
|
+
from .heartbeat import HeartbeatData, HeartbeatMessage
|
|
27
|
+
from .config import ConfigurationUpdateData, ConfigurationUpdateMessage
|
|
28
|
+
from .errors import ErrorData, ErrorMessage, AckData, AckMessage
|
|
29
|
+
from .proxy import (
|
|
30
|
+
# Core models
|
|
31
|
+
ProxyType, ProxyHealthStatus, ProxyCredentials, ProxyInfo, ProxyAssignment,
|
|
32
|
+
# Data payloads
|
|
33
|
+
ProxyRequestData, ProxyResponseData, ProxyHealthReportData,
|
|
34
|
+
ProxyRotationRequestData, ProxyReleaseData,
|
|
35
|
+
# WebSocket messages
|
|
36
|
+
ProxyRequestMessage, ProxyResponseMessage, ProxyHealthReportMessage,
|
|
37
|
+
ProxyRotationRequestMessage, ProxyReleaseMessage
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
from .utils import create_error_message, create_ack_message
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
# Base
|
|
44
|
+
'MessageType',
|
|
45
|
+
'WebSocketMessage',
|
|
46
|
+
|
|
47
|
+
# Driver messages
|
|
48
|
+
'DriverRegistrationData',
|
|
49
|
+
'DriverRegistrationMessage',
|
|
50
|
+
'RegistrationResponseData',
|
|
51
|
+
'RegistrationResponseMessage',
|
|
52
|
+
|
|
53
|
+
# Task messages
|
|
54
|
+
'TaskAssignmentData',
|
|
55
|
+
'TaskAssignmentMessage',
|
|
56
|
+
'TaskResultData',
|
|
57
|
+
'TaskResultMessage',
|
|
58
|
+
|
|
59
|
+
# Logging messages
|
|
60
|
+
'LogEntryData',
|
|
61
|
+
'LogEntryMessage',
|
|
62
|
+
'LogBatchData',
|
|
63
|
+
'LogBatchMessage',
|
|
64
|
+
|
|
65
|
+
# Heartbeat messages
|
|
66
|
+
'HeartbeatData',
|
|
67
|
+
'HeartbeatMessage',
|
|
68
|
+
|
|
69
|
+
# Configuration messages
|
|
70
|
+
'ConfigurationUpdateData',
|
|
71
|
+
'ConfigurationUpdateMessage',
|
|
72
|
+
|
|
73
|
+
# Error messages
|
|
74
|
+
'ErrorData',
|
|
75
|
+
'ErrorMessage',
|
|
76
|
+
'AckData',
|
|
77
|
+
'AckMessage',
|
|
78
|
+
|
|
79
|
+
# Proxy core models
|
|
80
|
+
'ProxyType', 'ProxyHealthStatus', 'ProxyCredentials', 'ProxyInfo', 'ProxyAssignment',
|
|
81
|
+
# Proxy data payloads
|
|
82
|
+
'ProxyRequestData', 'ProxyResponseData', 'ProxyHealthReportData',
|
|
83
|
+
'ProxyRotationRequestData', 'ProxyReleaseData',
|
|
84
|
+
# Proxy messages
|
|
85
|
+
'ProxyRequestMessage', 'ProxyResponseMessage', 'ProxyHealthReportMessage',
|
|
86
|
+
'ProxyRotationRequestMessage', 'ProxyReleaseMessage',
|
|
87
|
+
|
|
88
|
+
# Utilities
|
|
89
|
+
'create_error_message',
|
|
90
|
+
'create_ack_message'
|
|
91
|
+
]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base WebSocket Models.
|
|
3
|
+
|
|
4
|
+
Core message types and base classes for WebSocket communication.
|
|
5
|
+
Strictly typed without raw dictionaries.
|
|
6
|
+
|
|
7
|
+
Phase 2: Core Systems - WebSocket Bridge
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
|
|
13
|
+
from pydantic import Field, ConfigDict, field_serializer
|
|
14
|
+
from ..base import UnrealOnBaseModel, TimestampedModel, IdentifiedModel
|
|
15
|
+
from ...enums.types import MessageType
|
|
16
|
+
from ...utils.time import datetime_to_iso
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class WebSocketMessage(IdentifiedModel, TimestampedModel):
|
|
20
|
+
"""
|
|
21
|
+
Base WebSocket message model.
|
|
22
|
+
|
|
23
|
+
All WebSocket messages inherit from this base class for consistency.
|
|
24
|
+
Provides message ID, timestamp, and optional correlation ID.
|
|
25
|
+
|
|
26
|
+
CRITICAL: No raw Dict[str, Any] - all data must be typed!
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
model_config = ConfigDict(
|
|
30
|
+
validate_assignment=True,
|
|
31
|
+
extra="allow",
|
|
32
|
+
use_enum_values=True
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
type: MessageType = Field(
|
|
36
|
+
description="Type of the WebSocket message"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
correlation_id: Optional[str] = Field(
|
|
40
|
+
default=None,
|
|
41
|
+
description="ID of the message this is responding to"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
@field_serializer('created_at', 'updated_at', when_used='json')
|
|
45
|
+
def serialize_datetime_fields(self, value: Optional[datetime]) -> Optional[str]:
|
|
46
|
+
"""Serialize datetime fields to ISO format."""
|
|
47
|
+
return datetime_to_iso(value)
|
|
48
|
+
|
|
49
|
+
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration WebSocket Models.
|
|
3
|
+
|
|
4
|
+
Strictly typed models for configuration updates.
|
|
5
|
+
No raw dictionaries - all data structures are Pydantic models.
|
|
6
|
+
|
|
7
|
+
Phase 2: Core Systems - WebSocket Bridge
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Optional, List
|
|
11
|
+
from pydantic import Field, ConfigDict
|
|
12
|
+
|
|
13
|
+
from ..base import UnrealOnBaseModel
|
|
14
|
+
from .base import WebSocketMessage, MessageType
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LoggingConfiguration(UnrealOnBaseModel):
|
|
18
|
+
"""Logging configuration - strictly typed."""
|
|
19
|
+
|
|
20
|
+
model_config = ConfigDict(
|
|
21
|
+
validate_assignment=True,
|
|
22
|
+
extra="forbid"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
level: str = Field(
|
|
26
|
+
default="INFO",
|
|
27
|
+
pattern=r"^(DEBUG|INFO|WARNING|ERROR|CRITICAL)$",
|
|
28
|
+
description="Logging level"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
batch_size: int = Field(
|
|
32
|
+
default=10,
|
|
33
|
+
ge=1,
|
|
34
|
+
le=100,
|
|
35
|
+
description="Log batch size"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
send_interval: float = Field(
|
|
39
|
+
default=1.0,
|
|
40
|
+
ge=0.1,
|
|
41
|
+
le=60.0,
|
|
42
|
+
description="Log send interval in seconds"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
local_logging: bool = Field(
|
|
46
|
+
default=True,
|
|
47
|
+
description="Enable local logging"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class TaskConfiguration(UnrealOnBaseModel):
|
|
52
|
+
"""Task configuration - strictly typed."""
|
|
53
|
+
|
|
54
|
+
model_config = ConfigDict(
|
|
55
|
+
validate_assignment=True,
|
|
56
|
+
extra="forbid"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
max_concurrent_tasks: int = Field(
|
|
60
|
+
default=1,
|
|
61
|
+
ge=1,
|
|
62
|
+
le=100,
|
|
63
|
+
description="Maximum concurrent tasks"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
default_timeout: float = Field(
|
|
67
|
+
default=300.0,
|
|
68
|
+
ge=30.0,
|
|
69
|
+
le=3600.0,
|
|
70
|
+
description="Default task timeout in seconds"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
max_retries: int = Field(
|
|
74
|
+
default=3,
|
|
75
|
+
ge=0,
|
|
76
|
+
le=10,
|
|
77
|
+
description="Maximum task retries"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
retry_delay: float = Field(
|
|
81
|
+
default=1.0,
|
|
82
|
+
ge=0.1,
|
|
83
|
+
le=60.0,
|
|
84
|
+
description="Retry delay in seconds"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ProxyConfiguration(UnrealOnBaseModel):
|
|
89
|
+
"""Proxy configuration - strictly typed."""
|
|
90
|
+
|
|
91
|
+
model_config = ConfigDict(
|
|
92
|
+
validate_assignment=True,
|
|
93
|
+
extra="forbid"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
enabled: bool = Field(
|
|
97
|
+
default=False,
|
|
98
|
+
description="Enable proxy usage"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
rotation_enabled: bool = Field(
|
|
102
|
+
default=True,
|
|
103
|
+
description="Enable proxy rotation"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
rotation_interval: int = Field(
|
|
107
|
+
default=10,
|
|
108
|
+
ge=1,
|
|
109
|
+
le=1000,
|
|
110
|
+
description="Proxy rotation interval (requests)"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
health_check_interval: float = Field(
|
|
114
|
+
default=60.0,
|
|
115
|
+
ge=10.0,
|
|
116
|
+
le=3600.0,
|
|
117
|
+
description="Proxy health check interval in seconds"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class DriverConfiguration(UnrealOnBaseModel):
|
|
122
|
+
"""Complete driver configuration - strictly typed."""
|
|
123
|
+
|
|
124
|
+
model_config = ConfigDict(
|
|
125
|
+
validate_assignment=True,
|
|
126
|
+
extra="forbid"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
heartbeat_interval: int = Field(
|
|
130
|
+
default=30,
|
|
131
|
+
ge=5,
|
|
132
|
+
le=300,
|
|
133
|
+
description="Heartbeat interval in seconds"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
logging: LoggingConfiguration = Field(
|
|
137
|
+
default_factory=LoggingConfiguration,
|
|
138
|
+
description="Logging configuration"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
tasks: TaskConfiguration = Field(
|
|
142
|
+
default_factory=TaskConfiguration,
|
|
143
|
+
description="Task configuration"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
proxy: ProxyConfiguration = Field(
|
|
147
|
+
default_factory=ProxyConfiguration,
|
|
148
|
+
description="Proxy configuration"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
enabled_managers: List[str] = Field(
|
|
152
|
+
default_factory=lambda: ["logger", "http", "proxy"],
|
|
153
|
+
description="List of enabled managers"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class ConfigurationUpdateData(UnrealOnBaseModel):
|
|
158
|
+
"""Configuration update data payload - strictly typed."""
|
|
159
|
+
|
|
160
|
+
model_config = ConfigDict(
|
|
161
|
+
validate_assignment=True,
|
|
162
|
+
extra="forbid"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
configuration: DriverConfiguration = Field(
|
|
166
|
+
description="Updated configuration parameters"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
apply_immediately: bool = Field(
|
|
170
|
+
default=True,
|
|
171
|
+
description="Whether to apply configuration immediately"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
restart_required: bool = Field(
|
|
175
|
+
default=False,
|
|
176
|
+
description="Whether driver restart is required"
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
config_version: Optional[str] = Field(
|
|
180
|
+
default=None,
|
|
181
|
+
description="Configuration version"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class ConfigurationUpdateMessage(WebSocketMessage):
|
|
186
|
+
"""Configuration update message (Server → Driver)."""
|
|
187
|
+
|
|
188
|
+
model_config = ConfigDict(
|
|
189
|
+
validate_assignment=True,
|
|
190
|
+
extra="forbid"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
type: MessageType = Field(
|
|
194
|
+
default=MessageType.COMMAND_CONFIG_UPDATE,
|
|
195
|
+
frozen=True
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
data: ConfigurationUpdateData = Field(
|
|
199
|
+
description="Configuration update data"
|
|
200
|
+
)
|