unrealon 1.1.6__py3-none-any.whl → 2.0.4__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.
Files changed (145) hide show
  1. {unrealon-1.1.6.dist-info/licenses → unrealon-2.0.4.dist-info}/LICENSE +1 -1
  2. unrealon-2.0.4.dist-info/METADATA +491 -0
  3. unrealon-2.0.4.dist-info/RECORD +129 -0
  4. {unrealon-1.1.6.dist-info → unrealon-2.0.4.dist-info}/WHEEL +2 -1
  5. unrealon-2.0.4.dist-info/entry_points.txt +3 -0
  6. unrealon-2.0.4.dist-info/top_level.txt +3 -0
  7. unrealon_browser/__init__.py +5 -6
  8. unrealon_browser/cli/browser_cli.py +18 -9
  9. unrealon_browser/cli/interactive_mode.py +13 -4
  10. unrealon_browser/core/browser_manager.py +29 -16
  11. unrealon_browser/dto/__init__.py +21 -0
  12. unrealon_browser/dto/bot_detection.py +175 -0
  13. unrealon_browser/dto/models/config.py +9 -3
  14. unrealon_browser/managers/__init__.py +1 -1
  15. unrealon_browser/managers/logger_bridge.py +1 -4
  16. unrealon_browser/stealth/__init__.py +27 -0
  17. unrealon_browser/stealth/bypass_techniques.pyc +0 -0
  18. unrealon_browser/stealth/manager.pyc +0 -0
  19. unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
  20. unrealon_browser/stealth/playwright_stealth.pyc +0 -0
  21. unrealon_browser/stealth/scanner_tester.pyc +0 -0
  22. unrealon_browser/stealth/undetected_chrome.pyc +0 -0
  23. unrealon_core/__init__.py +160 -0
  24. unrealon_core/config/__init__.py +16 -0
  25. unrealon_core/config/environment.py +98 -0
  26. unrealon_core/config/urls.py +93 -0
  27. unrealon_core/enums/__init__.py +24 -0
  28. unrealon_core/enums/status.py +216 -0
  29. unrealon_core/enums/types.py +240 -0
  30. unrealon_core/error_handling/__init__.py +45 -0
  31. unrealon_core/error_handling/circuit_breaker.py +292 -0
  32. unrealon_core/error_handling/error_context.py +324 -0
  33. unrealon_core/error_handling/recovery.py +371 -0
  34. unrealon_core/error_handling/retry.py +268 -0
  35. unrealon_core/exceptions/__init__.py +46 -0
  36. unrealon_core/exceptions/base.py +292 -0
  37. unrealon_core/exceptions/communication.py +22 -0
  38. unrealon_core/exceptions/driver.py +11 -0
  39. unrealon_core/exceptions/proxy.py +11 -0
  40. unrealon_core/exceptions/task.py +12 -0
  41. unrealon_core/exceptions/validation.py +17 -0
  42. unrealon_core/models/__init__.py +98 -0
  43. unrealon_core/models/arq_context.py +252 -0
  44. unrealon_core/models/arq_responses.py +125 -0
  45. unrealon_core/models/base.py +291 -0
  46. unrealon_core/models/bridge_stats.py +58 -0
  47. unrealon_core/models/communication.py +39 -0
  48. unrealon_core/models/config.py +47 -0
  49. unrealon_core/models/connection_stats.py +47 -0
  50. unrealon_core/models/driver.py +30 -0
  51. unrealon_core/models/driver_details.py +98 -0
  52. unrealon_core/models/logging.py +28 -0
  53. unrealon_core/models/task.py +21 -0
  54. unrealon_core/models/typed_responses.py +210 -0
  55. unrealon_core/models/websocket/__init__.py +91 -0
  56. unrealon_core/models/websocket/base.py +49 -0
  57. unrealon_core/models/websocket/config.py +200 -0
  58. unrealon_core/models/websocket/driver.py +215 -0
  59. unrealon_core/models/websocket/errors.py +138 -0
  60. unrealon_core/models/websocket/heartbeat.py +100 -0
  61. unrealon_core/models/websocket/logging.py +261 -0
  62. unrealon_core/models/websocket/proxy.py +496 -0
  63. unrealon_core/models/websocket/tasks.py +275 -0
  64. unrealon_core/models/websocket/utils.py +153 -0
  65. unrealon_core/models/websocket_session.py +144 -0
  66. unrealon_core/monitoring/__init__.py +43 -0
  67. unrealon_core/monitoring/alerts.py +398 -0
  68. unrealon_core/monitoring/dashboard.py +307 -0
  69. unrealon_core/monitoring/health_check.py +354 -0
  70. unrealon_core/monitoring/metrics.py +352 -0
  71. unrealon_core/utils/__init__.py +11 -0
  72. unrealon_core/utils/time.py +61 -0
  73. unrealon_core/version.py +219 -0
  74. unrealon_driver/__init__.py +90 -51
  75. unrealon_driver/core_module/__init__.py +34 -0
  76. unrealon_driver/core_module/base.py +184 -0
  77. unrealon_driver/core_module/config.py +30 -0
  78. unrealon_driver/core_module/event_manager.py +127 -0
  79. unrealon_driver/core_module/protocols.py +98 -0
  80. unrealon_driver/core_module/registry.py +146 -0
  81. unrealon_driver/decorators/__init__.py +15 -0
  82. unrealon_driver/decorators/retry.py +117 -0
  83. unrealon_driver/decorators/schedule.py +137 -0
  84. unrealon_driver/decorators/task.py +61 -0
  85. unrealon_driver/decorators/timing.py +132 -0
  86. unrealon_driver/driver/__init__.py +20 -0
  87. unrealon_driver/driver/communication/__init__.py +10 -0
  88. unrealon_driver/driver/communication/session.py +203 -0
  89. unrealon_driver/driver/communication/websocket_client.py +197 -0
  90. unrealon_driver/driver/core/__init__.py +10 -0
  91. unrealon_driver/driver/core/config.py +85 -0
  92. unrealon_driver/driver/core/driver.py +221 -0
  93. unrealon_driver/driver/factory/__init__.py +9 -0
  94. unrealon_driver/driver/factory/manager_factory.py +130 -0
  95. unrealon_driver/driver/lifecycle/__init__.py +11 -0
  96. unrealon_driver/driver/lifecycle/daemon.py +76 -0
  97. unrealon_driver/driver/lifecycle/initialization.py +97 -0
  98. unrealon_driver/driver/lifecycle/shutdown.py +48 -0
  99. unrealon_driver/driver/monitoring/__init__.py +9 -0
  100. unrealon_driver/driver/monitoring/health.py +63 -0
  101. unrealon_driver/driver/utilities/__init__.py +10 -0
  102. unrealon_driver/driver/utilities/logging.py +51 -0
  103. unrealon_driver/driver/utilities/serialization.py +61 -0
  104. unrealon_driver/managers/__init__.py +32 -0
  105. unrealon_driver/managers/base.py +174 -0
  106. unrealon_driver/managers/browser.py +98 -0
  107. unrealon_driver/managers/cache.py +116 -0
  108. unrealon_driver/managers/http.py +107 -0
  109. unrealon_driver/managers/logger.py +286 -0
  110. unrealon_driver/managers/proxy.py +99 -0
  111. unrealon_driver/managers/registry.py +87 -0
  112. unrealon_driver/managers/threading.py +54 -0
  113. unrealon_driver/managers/update.py +107 -0
  114. unrealon_driver/utils/__init__.py +9 -0
  115. unrealon_driver/utils/time.py +10 -0
  116. unrealon-1.1.6.dist-info/METADATA +0 -625
  117. unrealon-1.1.6.dist-info/RECORD +0 -55
  118. unrealon-1.1.6.dist-info/entry_points.txt +0 -9
  119. unrealon_browser/managers/stealth.py +0 -388
  120. unrealon_driver/README.md +0 -0
  121. unrealon_driver/exceptions.py +0 -33
  122. unrealon_driver/html_analyzer/__init__.py +0 -32
  123. unrealon_driver/html_analyzer/cleaner.py +0 -657
  124. unrealon_driver/html_analyzer/config.py +0 -64
  125. unrealon_driver/html_analyzer/manager.py +0 -247
  126. unrealon_driver/html_analyzer/models.py +0 -115
  127. unrealon_driver/html_analyzer/websocket_analyzer.py +0 -157
  128. unrealon_driver/models/__init__.py +0 -31
  129. unrealon_driver/models/websocket.py +0 -98
  130. unrealon_driver/parser/__init__.py +0 -36
  131. unrealon_driver/parser/cli_manager.py +0 -142
  132. unrealon_driver/parser/daemon_manager.py +0 -403
  133. unrealon_driver/parser/managers/__init__.py +0 -25
  134. unrealon_driver/parser/managers/config.py +0 -293
  135. unrealon_driver/parser/managers/error.py +0 -412
  136. unrealon_driver/parser/managers/result.py +0 -321
  137. unrealon_driver/parser/parser_manager.py +0 -458
  138. unrealon_driver/smart_logging/__init__.py +0 -24
  139. unrealon_driver/smart_logging/models.py +0 -44
  140. unrealon_driver/smart_logging/smart_logger.py +0 -406
  141. unrealon_driver/smart_logging/unified_logger.py +0 -525
  142. unrealon_driver/websocket/__init__.py +0 -31
  143. unrealon_driver/websocket/client.py +0 -249
  144. unrealon_driver/websocket/config.py +0 -188
  145. unrealon_driver/websocket/manager.py +0 -90
@@ -0,0 +1,291 @@
1
+ """
2
+ Base Pydantic models for UnrealOn system.
3
+
4
+ These models provide common functionality and validation patterns
5
+ used throughout the system. Built with Pydantic v2 for maximum
6
+ performance and type safety.
7
+
8
+ Phase 1: Bedrock Foundation - These models are the foundation
9
+ for all other models in the system.
10
+ """
11
+
12
+ from datetime import datetime
13
+ from typing import Optional, Dict, Any, Union
14
+ from pydantic import BaseModel, Field, ConfigDict, field_validator
15
+ import uuid
16
+
17
+ from ..utils.time import utc_now
18
+
19
+
20
+ class UnrealOnBaseModel(BaseModel):
21
+ """
22
+ Base model for all UnrealOn models.
23
+
24
+ Provides:
25
+ - Strict validation (no extra fields)
26
+ - JSON serialization/deserialization
27
+ - Type safety with Pydantic v2
28
+ - Common utility methods
29
+ """
30
+
31
+ model_config = ConfigDict(
32
+ # Pydantic v2 configuration for maximum strictness
33
+ str_strip_whitespace=True, # Auto-strip whitespace
34
+ validate_assignment=True, # Validate on assignment
35
+ use_enum_values=True, # Use enum values in serialization
36
+ extra='forbid', # Strict - no extra fields allowed
37
+ frozen=False, # Allow mutation by default
38
+ arbitrary_types_allowed=True, # Allow custom types
39
+ validate_default=True, # Validate default values
40
+ )
41
+
42
+ def to_dict(self) -> Dict[str, Any]:
43
+ """Convert model to dictionary for JSON serialization."""
44
+ return self.model_dump(mode='json', exclude_none=True)
45
+
46
+ @classmethod
47
+ def from_dict(cls, data: Dict[str, Any]):
48
+ """Create instance from dictionary."""
49
+ return cls.model_validate(data)
50
+
51
+ def to_json(self) -> str:
52
+ """Convert model to JSON string."""
53
+ return self.model_dump_json(exclude_none=True)
54
+
55
+ @classmethod
56
+ def from_json(cls, json_str: str):
57
+ """Create instance from JSON string."""
58
+ return cls.model_validate_json(json_str)
59
+
60
+ def update_from_dict(self, data: Dict[str, Any]) -> 'UnrealOnBaseModel':
61
+ """Update model fields from dictionary."""
62
+ for key, value in data.items():
63
+ if hasattr(self, key):
64
+ setattr(self, key, value)
65
+ return self
66
+
67
+ def copy_with_updates(self, **updates) -> 'UnrealOnBaseModel':
68
+ """Create a copy with updated fields."""
69
+ return self.model_copy(update=updates)
70
+
71
+
72
+ class TimestampedModel(UnrealOnBaseModel):
73
+ """
74
+ Base model with automatic timestamp fields.
75
+
76
+ Provides:
77
+ - created_at: Auto-set on creation
78
+ - updated_at: Manual update via touch()
79
+ - age_seconds: Calculated property
80
+ """
81
+
82
+ created_at: datetime = Field(
83
+ default_factory=utc_now,
84
+ description="Timestamp when the model was created"
85
+ )
86
+ updated_at: Optional[datetime] = Field(
87
+ default=None,
88
+ description="Timestamp when the model was last updated"
89
+ )
90
+
91
+ def touch(self) -> 'TimestampedModel':
92
+ """Update the updated_at timestamp."""
93
+ self.updated_at = utc_now()
94
+ return self
95
+
96
+ @property
97
+ def age_seconds(self) -> float:
98
+ """Get age of the model in seconds."""
99
+ return (utc_now() - self.created_at).total_seconds()
100
+
101
+ @property
102
+ def last_modified_seconds(self) -> float:
103
+ """Get seconds since last modification."""
104
+ reference_time = self.updated_at or self.created_at
105
+ return (utc_now() - reference_time).total_seconds()
106
+
107
+
108
+ class IdentifiedModel(UnrealOnBaseModel):
109
+ """
110
+ Base model with unique ID field.
111
+
112
+ Provides:
113
+ - id: UUID4 string by default
114
+ - String representation
115
+ - Equality comparison by ID
116
+ """
117
+
118
+ id: str = Field(
119
+ default_factory=lambda: str(uuid.uuid4()),
120
+ description="Unique identifier for the model",
121
+ min_length=1
122
+ )
123
+
124
+ @field_validator('id')
125
+ @classmethod
126
+ def validate_id(cls, v: str) -> str:
127
+ """Validate ID is not empty."""
128
+ if not v or not v.strip():
129
+ raise ValueError("ID cannot be empty")
130
+ return v.strip()
131
+
132
+ def __str__(self) -> str:
133
+ return f"{self.__class__.__name__}(id={self.id})"
134
+
135
+ def __repr__(self) -> str:
136
+ return f"{self.__class__.__name__}(id='{self.id}')"
137
+
138
+ def __eq__(self, other) -> bool:
139
+ """Compare models by ID."""
140
+ if not isinstance(other, IdentifiedModel):
141
+ return False
142
+ return self.id == other.id
143
+
144
+ def __hash__(self) -> int:
145
+ """Hash by ID for use in sets/dicts."""
146
+ return hash(self.id)
147
+
148
+
149
+ class StatusModel(UnrealOnBaseModel):
150
+ """
151
+ Base model with status tracking.
152
+
153
+ Provides:
154
+ - status: Current status string
155
+ - status_message: Optional status description
156
+ - status_updated_at: Timestamp of last status change
157
+ - Status update methods
158
+ """
159
+
160
+ status: str = Field(
161
+ description="Current status of the model",
162
+ min_length=1
163
+ )
164
+ status_message: Optional[str] = Field(
165
+ default=None,
166
+ description="Optional message describing the status"
167
+ )
168
+ status_updated_at: datetime = Field(
169
+ default_factory=utc_now,
170
+ description="Timestamp when status was last updated"
171
+ )
172
+
173
+ @field_validator('status')
174
+ @classmethod
175
+ def validate_status(cls, v: str) -> str:
176
+ """Validate status is not empty."""
177
+ if not v or not v.strip():
178
+ raise ValueError("Status cannot be empty")
179
+ return v.strip()
180
+
181
+ def update_status(self, status: str, message: Optional[str] = None) -> 'StatusModel':
182
+ """Update status with timestamp and optional message."""
183
+ self.status = status
184
+ self.status_message = message
185
+ self.status_updated_at = utc_now()
186
+ return self
187
+
188
+ @property
189
+ def status_age_seconds(self) -> float:
190
+ """Get age of current status in seconds."""
191
+ return (utc_now() - self.status_updated_at).total_seconds()
192
+
193
+ def is_status(self, *statuses: str) -> bool:
194
+ """Check if current status matches any of the provided statuses."""
195
+ return self.status in statuses
196
+
197
+
198
+ class MetadataModel(UnrealOnBaseModel):
199
+ """
200
+ Base model with metadata field.
201
+
202
+ Provides:
203
+ - metadata: Dictionary for arbitrary key-value data
204
+ - Helper methods for metadata manipulation
205
+ """
206
+
207
+ metadata: Dict[str, Any] = Field(
208
+ default_factory=dict,
209
+ description="Arbitrary metadata key-value pairs"
210
+ )
211
+
212
+ def set_metadata(self, key: str, value: Any) -> 'MetadataModel':
213
+ """Set metadata value."""
214
+ self.metadata[key] = value
215
+ return self
216
+
217
+ def get_metadata(self, key: str, default: Any = None) -> Any:
218
+ """Get metadata value with optional default."""
219
+ return self.metadata.get(key, default)
220
+
221
+ def has_metadata(self, key: str) -> bool:
222
+ """Check if metadata key exists."""
223
+ return key in self.metadata
224
+
225
+ def remove_metadata(self, key: str) -> 'MetadataModel':
226
+ """Remove metadata key if it exists."""
227
+ self.metadata.pop(key, None)
228
+ return self
229
+
230
+ def clear_metadata(self) -> 'MetadataModel':
231
+ """Clear all metadata."""
232
+ self.metadata.clear()
233
+ return self
234
+
235
+ def update_metadata(self, **updates) -> 'MetadataModel':
236
+ """Update metadata with multiple key-value pairs."""
237
+ self.metadata.update(updates)
238
+ return self
239
+
240
+
241
+ # Combined base models for common use cases
242
+ class FullBaseModel(IdentifiedModel, TimestampedModel, StatusModel, MetadataModel):
243
+ """
244
+ Complete base model with ID, timestamps, status, and metadata.
245
+
246
+ Use this for complex entities that need full tracking:
247
+ - Drivers
248
+ - Tasks
249
+ - Complex configurations
250
+ """
251
+ pass
252
+
253
+
254
+ class SimpleBaseModel(IdentifiedModel, TimestampedModel):
255
+ """
256
+ Simple base model with ID and timestamps only.
257
+
258
+ Use this for simple entities:
259
+ - Messages
260
+ - Simple configurations
261
+ - Temporary objects
262
+ """
263
+ pass
264
+
265
+
266
+ class ConfigBaseModel(UnrealOnBaseModel):
267
+ """
268
+ Base model for configuration objects.
269
+
270
+ Provides validation for configuration models
271
+ without unnecessary fields like timestamps.
272
+ """
273
+
274
+ def validate_config(self) -> bool:
275
+ """Override in subclasses to add custom validation."""
276
+ return True
277
+
278
+ def merge_with(self, other: 'ConfigBaseModel') -> 'ConfigBaseModel':
279
+ """Merge this config with another, other takes precedence."""
280
+ if not isinstance(other, self.__class__):
281
+ raise ValueError(f"Cannot merge {self.__class__} with {other.__class__}")
282
+
283
+ # Get all fields from both models
284
+ self_dict = self.model_dump()
285
+ other_dict = other.model_dump()
286
+
287
+ # Merge dictionaries (other takes precedence)
288
+ merged = {**self_dict, **other_dict}
289
+
290
+ # Create new instance
291
+ return self.__class__.model_validate(merged)
@@ -0,0 +1,58 @@
1
+ """
2
+ Bridge Statistics Models
3
+
4
+ Strictly typed models for WebSocket bridge statistics.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+
7
+ Phase 2: Core Systems - Bridge Statistics
8
+ """
9
+
10
+ from datetime import datetime
11
+ from typing import Optional
12
+ from pydantic import BaseModel, Field, ConfigDict
13
+
14
+ from .base import UnrealOnBaseModel
15
+ from ..utils.time import utc_now
16
+
17
+
18
+ class BridgeStatsData(UnrealOnBaseModel):
19
+ """Internal bridge statistics data."""
20
+
21
+ model_config = ConfigDict(
22
+ validate_assignment=True,
23
+ extra="forbid"
24
+ )
25
+
26
+ tasks_sent: int = Field(default=0, description="Number of tasks sent")
27
+ tasks_failed: int = Field(default=0, description="Number of tasks failed")
28
+ configs_sent: int = Field(default=0, description="Number of configurations sent")
29
+ configs_failed: int = Field(default=0, description="Number of configurations failed")
30
+ messages_processed: int = Field(default=0, description="Number of messages processed")
31
+ start_time: str = Field(description="Start time ISO string")
32
+
33
+ def increment_tasks_sent(self) -> None:
34
+ """Increment tasks sent counter."""
35
+ self.tasks_sent += 1
36
+
37
+ def increment_tasks_failed(self) -> None:
38
+ """Increment tasks failed counter."""
39
+ self.tasks_failed += 1
40
+
41
+ def increment_configs_sent(self) -> None:
42
+ """Increment configs sent counter."""
43
+ self.configs_sent += 1
44
+
45
+ def increment_configs_failed(self) -> None:
46
+ """Increment configs failed counter."""
47
+ self.configs_failed += 1
48
+
49
+ def increment_messages_processed(self) -> None:
50
+ """Increment messages processed counter."""
51
+ self.messages_processed += 1
52
+
53
+
54
+ def create_initial_bridge_stats() -> BridgeStatsData:
55
+ """Create initial bridge statistics."""
56
+ return BridgeStatsData(
57
+ start_time=utc_now().isoformat()
58
+ )
@@ -0,0 +1,39 @@
1
+ """
2
+ WebSocket Communication Models for UnrealOn RPC.
3
+
4
+ CRITICAL REQUIREMENTS COMPLIANT:
5
+ - No raw Dict[str, Any] usage
6
+ - 100% Pydantic v2 validation
7
+ - Strict typing throughout
8
+ - Files under 500 lines
9
+
10
+ This file imports from strictly typed websocket models.
11
+ All raw dictionaries have been replaced with Pydantic models.
12
+
13
+ Phase 2: Core Systems - WebSocket Bridge
14
+ """
15
+
16
+ # Import all strictly typed models from websocket package
17
+ from .websocket import *
18
+ from .websocket.logging import LogContext
19
+
20
+ # Export commonly used data models for easy access
21
+ __all__ = [
22
+ # Message types and base
23
+ 'MessageType', 'WebSocketMessage',
24
+
25
+ # Message classes
26
+ 'DriverRegistrationMessage', 'RegistrationResponseMessage',
27
+ 'TaskAssignmentMessage', 'TaskResultMessage',
28
+ 'LogEntryMessage', 'LogBatchMessage',
29
+ 'HeartbeatMessage', 'ConfigurationUpdateMessage',
30
+ 'ErrorMessage', 'AckMessage',
31
+
32
+ # Data models for strict typing
33
+ 'TaskAssignmentData', 'TaskResultData', 'TaskParameters',
34
+ 'DriverRegistrationData', 'HeartbeatData', 'LogEntryData', 'LogContext',
35
+
36
+ # Utilities
37
+ 'create_error_message', 'create_ack_message',
38
+
39
+ ]
@@ -0,0 +1,47 @@
1
+ """
2
+ Config models - Phase 2 update.
3
+
4
+ Import from strictly typed websocket models to avoid duplication.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+ """
7
+
8
+ # Import strictly typed models from websocket package
9
+ from .websocket.config import (
10
+ DriverConfiguration,
11
+ LoggingConfiguration,
12
+ TaskConfiguration,
13
+ ProxyConfiguration
14
+ )
15
+ from .base import ConfigBaseModel
16
+
17
+ # System config that doesn't exist in websocket models yet
18
+ class SystemConfig(ConfigBaseModel):
19
+ """System-wide configuration."""
20
+
21
+ redis_url: str = "redis://localhost:6379/0"
22
+ websocket_url: str = "ws://localhost:8000/ws"
23
+ max_workers: int = 10
24
+ debug: bool = False
25
+
26
+ # Legacy compatibility - map to new typed models
27
+ HttpConfig = TaskConfiguration # HTTP settings are part of task config
28
+ ProxyConfig = ProxyConfiguration
29
+ LoggingConfig = LoggingConfiguration
30
+ BrowserConfig = TaskConfiguration # Browser settings are part of task config
31
+ CacheConfig = SystemConfig # Cache settings are system-wide
32
+ ThreadConfig = TaskConfiguration # Thread settings are part of task config
33
+
34
+ __all__ = [
35
+ 'DriverConfiguration',
36
+ 'LoggingConfiguration',
37
+ 'TaskConfiguration',
38
+ 'ProxyConfiguration',
39
+ 'SystemConfig',
40
+ # Legacy names
41
+ 'HttpConfig',
42
+ 'ProxyConfig',
43
+ 'LoggingConfig',
44
+ 'BrowserConfig',
45
+ 'CacheConfig',
46
+ 'ThreadConfig'
47
+ ]
@@ -0,0 +1,47 @@
1
+ """
2
+ Connection Statistics Models
3
+
4
+ Strictly typed models for WebSocket connection statistics.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+
7
+ Phase 2: Core Systems - Connection Statistics
8
+ """
9
+
10
+ from pydantic import BaseModel, Field, ConfigDict
11
+
12
+ from .base import UnrealOnBaseModel
13
+
14
+
15
+ class ConnectionStatsData(UnrealOnBaseModel):
16
+ """Internal connection statistics data."""
17
+
18
+ model_config = ConfigDict(
19
+ validate_assignment=True,
20
+ extra="forbid"
21
+ )
22
+
23
+ total_connections: int = Field(default=0, description="Total connections made")
24
+ active_connections: int = Field(default=0, description="Currently active connections")
25
+ total_messages: int = Field(default=0, description="Total messages sent")
26
+ failed_messages: int = Field(default=0, description="Failed messages")
27
+
28
+ def increment_total_connections(self) -> None:
29
+ """Increment total connections counter."""
30
+ self.total_connections += 1
31
+
32
+ def set_active_connections(self, count: int) -> None:
33
+ """Set active connections count."""
34
+ self.active_connections = count
35
+
36
+ def increment_total_messages(self) -> None:
37
+ """Increment total messages counter."""
38
+ self.total_messages += 1
39
+
40
+ def increment_failed_messages(self) -> None:
41
+ """Increment failed messages counter."""
42
+ self.failed_messages += 1
43
+
44
+
45
+ def create_initial_connection_stats() -> ConnectionStatsData:
46
+ """Create initial connection statistics."""
47
+ return ConnectionStatsData()
@@ -0,0 +1,30 @@
1
+ """
2
+ Driver models - Phase 2 update.
3
+
4
+ Import from strictly typed websocket models to avoid duplication.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+ """
7
+
8
+ # Import strictly typed models from websocket package
9
+ from .websocket.driver import (
10
+ DriverRegistrationData,
11
+ DriverMetadata,
12
+ DriverConfiguration,
13
+ RegistrationResponseData
14
+ )
15
+
16
+ # Legacy compatibility
17
+ DriverInfo = DriverRegistrationData
18
+ DriverConfig = DriverConfiguration
19
+ DriverCapability = DriverMetadata
20
+
21
+ __all__ = [
22
+ 'DriverRegistrationData',
23
+ 'DriverMetadata',
24
+ 'DriverConfiguration',
25
+ 'RegistrationResponseData',
26
+ # Legacy names
27
+ 'DriverInfo',
28
+ 'DriverConfig',
29
+ 'DriverCapability'
30
+ ]
@@ -0,0 +1,98 @@
1
+ """
2
+ Driver Details Models
3
+
4
+ Strictly typed models for driver information and statistics.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+
7
+ Phase 2: Core Systems - Driver Details
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 DriverDetails(UnrealOnBaseModel):
18
+ """Complete driver details with statistics."""
19
+
20
+ model_config = ConfigDict(
21
+ validate_assignment=True,
22
+ extra="forbid"
23
+ )
24
+
25
+ # Basic driver info
26
+ driver_id: str = Field(description="Driver ID")
27
+ driver_name: Optional[str] = Field(default=None, description="Driver name")
28
+ driver_type: str = Field(description="Driver type")
29
+ capabilities: List[str] = Field(default_factory=list, description="Driver capabilities")
30
+ version: Optional[str] = Field(default=None, description="Driver version")
31
+
32
+ # Connection info
33
+ connection_id: str = Field(description="WebSocket connection ID")
34
+ status: str = Field(description="Driver status")
35
+ connected_at: datetime = Field(description="Connection timestamp")
36
+ last_seen: datetime = Field(description="Last activity timestamp")
37
+
38
+ # Task statistics
39
+ active_tasks: int = Field(default=0, description="Number of active tasks")
40
+ completed_tasks: int = Field(default=0, description="Number of completed tasks")
41
+ failed_tasks: int = Field(default=0, description="Number of failed tasks")
42
+
43
+ # Performance metrics
44
+ uptime_seconds: float = Field(default=0.0, description="Uptime in seconds")
45
+ memory_usage_mb: Optional[float] = Field(default=None, description="Memory usage in MB")
46
+ cpu_usage_percent: Optional[float] = Field(default=None, description="CPU usage percentage")
47
+
48
+
49
+ class DriverInfo(UnrealOnBaseModel):
50
+ """Basic driver information."""
51
+
52
+ model_config = ConfigDict(
53
+ validate_assignment=True,
54
+ extra="forbid"
55
+ )
56
+
57
+ driver_id: str = Field(description="Driver ID")
58
+ connection_id: str = Field(description="WebSocket connection ID")
59
+ status: str = Field(description="Driver status")
60
+ last_heartbeat: Optional[datetime] = Field(default=None, description="Last heartbeat timestamp")
61
+
62
+
63
+ class DriverListResult(UnrealOnBaseModel):
64
+ """Result of driver list query."""
65
+
66
+ model_config = ConfigDict(
67
+ validate_assignment=True,
68
+ extra="forbid"
69
+ )
70
+
71
+ drivers: List[DriverDetails] = Field(description="List of driver details")
72
+ total_count: int = Field(description="Total number of drivers")
73
+ filtered_count: int = Field(description="Number of drivers after filtering")
74
+ filter_applied: Optional[str] = Field(default=None, description="Filter that was applied")
75
+
76
+
77
+ def create_driver_details_from_session(
78
+ driver_info: DriverInfo,
79
+ session: "DriverSession"
80
+ ) -> DriverDetails:
81
+ """Create DriverDetails from DriverInfo and DriverSession."""
82
+ return DriverDetails(
83
+ driver_id=driver_info.driver_id,
84
+ driver_name=getattr(session, 'driver_name', None),
85
+ driver_type=session.driver_type,
86
+ capabilities=session.capabilities,
87
+ version=getattr(session, 'version', None),
88
+ connection_id=session.connection_id,
89
+ status=session.status,
90
+ connected_at=session.connected_at,
91
+ last_seen=session.last_seen,
92
+ active_tasks=session.active_tasks,
93
+ completed_tasks=getattr(session, 'completed_tasks', 0),
94
+ failed_tasks=getattr(session, 'failed_tasks', 0),
95
+ uptime_seconds=(utc_now() - session.connected_at).total_seconds(),
96
+ memory_usage_mb=getattr(session, 'memory_usage_mb', None),
97
+ cpu_usage_percent=getattr(session, 'cpu_usage_percent', None)
98
+ )
@@ -0,0 +1,28 @@
1
+ """
2
+ Logging models - Phase 2 update.
3
+
4
+ Import from strictly typed websocket models to avoid duplication.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+ """
7
+
8
+ # Import strictly typed models from websocket package
9
+ from .websocket.logging import (
10
+ LogEntryData,
11
+ LogBatchData,
12
+ LogContext
13
+ )
14
+
15
+ # Legacy compatibility
16
+ LogEntry = LogEntryData
17
+ LogQuery = LogContext
18
+ LogMetrics = LogBatchData
19
+
20
+ __all__ = [
21
+ 'LogEntryData',
22
+ 'LogBatchData',
23
+ 'LogContext',
24
+ # Legacy names
25
+ 'LogEntry',
26
+ 'LogQuery',
27
+ 'LogMetrics'
28
+ ]
@@ -0,0 +1,21 @@
1
+ """
2
+ Task models - Phase 2 update.
3
+
4
+ Import from strictly typed websocket models to avoid duplication.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+ """
7
+
8
+ # Import strictly typed models from websocket package
9
+ from .websocket.tasks import (
10
+ TaskAssignmentData,
11
+ TaskResultData,
12
+ TaskParameters,
13
+ TaskMetadata
14
+ )
15
+
16
+ __all__ = [
17
+ 'TaskAssignmentData',
18
+ 'TaskResultData',
19
+ 'TaskParameters',
20
+ 'TaskMetadata',
21
+ ]