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.
Files changed (302) hide show
  1. unrealon/__init__.py +23 -21
  2. unrealon-1.1.1.dist-info/METADATA +722 -0
  3. unrealon-1.1.1.dist-info/RECORD +82 -0
  4. {unrealon-1.0.9.dist-info → unrealon-1.1.1.dist-info}/WHEEL +1 -1
  5. unrealon-1.1.1.dist-info/entry_points.txt +9 -0
  6. {unrealon-1.0.9.dist-info → unrealon-1.1.1.dist-info/licenses}/LICENSE +1 -1
  7. unrealon_bridge/__init__.py +114 -0
  8. unrealon_bridge/cli.py +316 -0
  9. unrealon_bridge/client/__init__.py +93 -0
  10. unrealon_bridge/client/base.py +78 -0
  11. unrealon_bridge/client/commands.py +89 -0
  12. unrealon_bridge/client/connection.py +90 -0
  13. unrealon_bridge/client/events.py +65 -0
  14. unrealon_bridge/client/health.py +38 -0
  15. unrealon_bridge/client/html_parser.py +146 -0
  16. unrealon_bridge/client/logging.py +139 -0
  17. unrealon_bridge/client/proxy.py +70 -0
  18. unrealon_bridge/client/scheduler.py +450 -0
  19. unrealon_bridge/client/session.py +70 -0
  20. unrealon_bridge/configs/__init__.py +14 -0
  21. unrealon_bridge/configs/bridge_config.py +212 -0
  22. unrealon_bridge/configs/bridge_config.yaml +39 -0
  23. unrealon_bridge/models/__init__.py +138 -0
  24. unrealon_bridge/models/base.py +28 -0
  25. unrealon_bridge/models/command.py +41 -0
  26. unrealon_bridge/models/events.py +40 -0
  27. unrealon_bridge/models/html_parser.py +79 -0
  28. unrealon_bridge/models/logging.py +55 -0
  29. unrealon_bridge/models/parser.py +63 -0
  30. unrealon_bridge/models/proxy.py +41 -0
  31. unrealon_bridge/models/requests.py +95 -0
  32. unrealon_bridge/models/responses.py +88 -0
  33. unrealon_bridge/models/scheduler.py +592 -0
  34. unrealon_bridge/models/session.py +28 -0
  35. unrealon_bridge/server/__init__.py +91 -0
  36. unrealon_bridge/server/base.py +171 -0
  37. unrealon_bridge/server/handlers/__init__.py +23 -0
  38. unrealon_bridge/server/handlers/command.py +110 -0
  39. unrealon_bridge/server/handlers/html_parser.py +139 -0
  40. unrealon_bridge/server/handlers/logging.py +95 -0
  41. unrealon_bridge/server/handlers/parser.py +95 -0
  42. unrealon_bridge/server/handlers/proxy.py +75 -0
  43. unrealon_bridge/server/handlers/scheduler.py +545 -0
  44. unrealon_bridge/server/handlers/session.py +66 -0
  45. unrealon_browser/__init__.py +61 -18
  46. unrealon_browser/{src/cli → cli}/browser_cli.py +6 -13
  47. unrealon_browser/{src/cli → cli}/cookies_cli.py +5 -1
  48. unrealon_browser/{src/core → core}/browser_manager.py +2 -2
  49. unrealon_browser/{src/managers → managers}/captcha.py +1 -1
  50. unrealon_browser/{src/managers → managers}/cookies.py +1 -1
  51. unrealon_browser/managers/logger_bridge.py +231 -0
  52. unrealon_browser/{src/managers → managers}/profile.py +1 -1
  53. unrealon_driver/__init__.py +73 -19
  54. unrealon_driver/browser/__init__.py +8 -0
  55. unrealon_driver/browser/config.py +74 -0
  56. unrealon_driver/browser/manager.py +416 -0
  57. unrealon_driver/exceptions.py +28 -0
  58. unrealon_driver/parser/__init__.py +55 -0
  59. unrealon_driver/parser/cli_manager.py +141 -0
  60. unrealon_driver/parser/daemon_manager.py +227 -0
  61. unrealon_driver/parser/managers/__init__.py +46 -0
  62. unrealon_driver/parser/managers/browser.py +51 -0
  63. unrealon_driver/parser/managers/config.py +281 -0
  64. unrealon_driver/parser/managers/error.py +412 -0
  65. unrealon_driver/parser/managers/html.py +732 -0
  66. unrealon_driver/parser/managers/logging.py +609 -0
  67. unrealon_driver/parser/managers/result.py +321 -0
  68. unrealon_driver/parser/parser_manager.py +628 -0
  69. unrealon/sdk_config.py +0 -88
  70. unrealon-1.0.9.dist-info/METADATA +0 -810
  71. unrealon-1.0.9.dist-info/RECORD +0 -246
  72. unrealon_browser/pyproject.toml +0 -182
  73. unrealon_browser/src/__init__.py +0 -62
  74. unrealon_browser/src/managers/logger_bridge.py +0 -395
  75. unrealon_driver/README.md +0 -204
  76. unrealon_driver/pyproject.toml +0 -187
  77. unrealon_driver/src/__init__.py +0 -90
  78. unrealon_driver/src/cli/__init__.py +0 -10
  79. unrealon_driver/src/cli/main.py +0 -66
  80. unrealon_driver/src/cli/simple.py +0 -510
  81. unrealon_driver/src/config/__init__.py +0 -11
  82. unrealon_driver/src/config/auto_config.py +0 -478
  83. unrealon_driver/src/core/__init__.py +0 -18
  84. unrealon_driver/src/core/exceptions.py +0 -289
  85. unrealon_driver/src/core/parser.py +0 -638
  86. unrealon_driver/src/dto/__init__.py +0 -66
  87. unrealon_driver/src/dto/cli.py +0 -119
  88. unrealon_driver/src/dto/config.py +0 -18
  89. unrealon_driver/src/dto/events.py +0 -237
  90. unrealon_driver/src/dto/execution.py +0 -313
  91. unrealon_driver/src/dto/services.py +0 -311
  92. unrealon_driver/src/execution/__init__.py +0 -23
  93. unrealon_driver/src/execution/daemon_mode.py +0 -317
  94. unrealon_driver/src/execution/interactive_mode.py +0 -88
  95. unrealon_driver/src/execution/modes.py +0 -45
  96. unrealon_driver/src/execution/scheduled_mode.py +0 -209
  97. unrealon_driver/src/execution/test_mode.py +0 -250
  98. unrealon_driver/src/logging/__init__.py +0 -24
  99. unrealon_driver/src/logging/driver_logger.py +0 -512
  100. unrealon_driver/src/services/__init__.py +0 -24
  101. unrealon_driver/src/services/browser_service.py +0 -726
  102. unrealon_driver/src/services/llm/__init__.py +0 -15
  103. unrealon_driver/src/services/llm/browser_llm_service.py +0 -363
  104. unrealon_driver/src/services/llm/llm.py +0 -195
  105. unrealon_driver/src/services/logger_service.py +0 -232
  106. unrealon_driver/src/services/metrics_service.py +0 -185
  107. unrealon_driver/src/services/scheduler_service.py +0 -489
  108. unrealon_driver/src/services/websocket_service.py +0 -362
  109. unrealon_driver/src/utils/__init__.py +0 -16
  110. unrealon_driver/src/utils/service_factory.py +0 -317
  111. unrealon_driver/src/utils/time_formatter.py +0 -338
  112. unrealon_llm/README.md +0 -44
  113. unrealon_llm/__init__.py +0 -26
  114. unrealon_llm/pyproject.toml +0 -154
  115. unrealon_llm/src/__init__.py +0 -228
  116. unrealon_llm/src/cli/__init__.py +0 -0
  117. unrealon_llm/src/core/__init__.py +0 -11
  118. unrealon_llm/src/core/smart_client.py +0 -438
  119. unrealon_llm/src/dto/__init__.py +0 -155
  120. unrealon_llm/src/dto/models/__init__.py +0 -0
  121. unrealon_llm/src/dto/models/config.py +0 -343
  122. unrealon_llm/src/dto/models/core.py +0 -328
  123. unrealon_llm/src/dto/models/enums.py +0 -123
  124. unrealon_llm/src/dto/models/html_analysis.py +0 -345
  125. unrealon_llm/src/dto/models/statistics.py +0 -473
  126. unrealon_llm/src/dto/models/translation.py +0 -383
  127. unrealon_llm/src/dto/models/type_conversion.py +0 -462
  128. unrealon_llm/src/dto/schemas/__init__.py +0 -0
  129. unrealon_llm/src/exceptions.py +0 -392
  130. unrealon_llm/src/llm_config/__init__.py +0 -20
  131. unrealon_llm/src/llm_config/logging_config.py +0 -178
  132. unrealon_llm/src/llm_logging/__init__.py +0 -42
  133. unrealon_llm/src/llm_logging/llm_events.py +0 -107
  134. unrealon_llm/src/llm_logging/llm_logger.py +0 -466
  135. unrealon_llm/src/managers/__init__.py +0 -15
  136. unrealon_llm/src/managers/cache_manager.py +0 -67
  137. unrealon_llm/src/managers/cost_manager.py +0 -107
  138. unrealon_llm/src/managers/request_manager.py +0 -298
  139. unrealon_llm/src/modules/__init__.py +0 -0
  140. unrealon_llm/src/modules/html_processor/__init__.py +0 -25
  141. unrealon_llm/src/modules/html_processor/base_processor.py +0 -415
  142. unrealon_llm/src/modules/html_processor/details_processor.py +0 -85
  143. unrealon_llm/src/modules/html_processor/listing_processor.py +0 -91
  144. unrealon_llm/src/modules/html_processor/models/__init__.py +0 -20
  145. unrealon_llm/src/modules/html_processor/models/processing_models.py +0 -40
  146. unrealon_llm/src/modules/html_processor/models/universal_model.py +0 -56
  147. unrealon_llm/src/modules/html_processor/processor.py +0 -102
  148. unrealon_llm/src/modules/llm/__init__.py +0 -0
  149. unrealon_llm/src/modules/translator/__init__.py +0 -0
  150. unrealon_llm/src/provider.py +0 -116
  151. unrealon_llm/src/utils/__init__.py +0 -95
  152. unrealon_llm/src/utils/common.py +0 -64
  153. unrealon_llm/src/utils/data_extractor.py +0 -188
  154. unrealon_llm/src/utils/html_cleaner.py +0 -767
  155. unrealon_llm/src/utils/language_detector.py +0 -308
  156. unrealon_llm/src/utils/models_cache.py +0 -592
  157. unrealon_llm/src/utils/smart_counter.py +0 -229
  158. unrealon_llm/src/utils/token_counter.py +0 -189
  159. unrealon_sdk/README.md +0 -25
  160. unrealon_sdk/__init__.py +0 -30
  161. unrealon_sdk/pyproject.toml +0 -231
  162. unrealon_sdk/src/__init__.py +0 -150
  163. unrealon_sdk/src/cli/__init__.py +0 -12
  164. unrealon_sdk/src/cli/commands/__init__.py +0 -22
  165. unrealon_sdk/src/cli/commands/benchmark.py +0 -42
  166. unrealon_sdk/src/cli/commands/diagnostics.py +0 -573
  167. unrealon_sdk/src/cli/commands/health.py +0 -46
  168. unrealon_sdk/src/cli/commands/integration.py +0 -498
  169. unrealon_sdk/src/cli/commands/reports.py +0 -43
  170. unrealon_sdk/src/cli/commands/security.py +0 -36
  171. unrealon_sdk/src/cli/commands/server.py +0 -483
  172. unrealon_sdk/src/cli/commands/servers.py +0 -56
  173. unrealon_sdk/src/cli/commands/tests.py +0 -55
  174. unrealon_sdk/src/cli/main.py +0 -126
  175. unrealon_sdk/src/cli/utils/reporter.py +0 -519
  176. unrealon_sdk/src/clients/openapi.yaml +0 -3347
  177. unrealon_sdk/src/clients/python_http/__init__.py +0 -3
  178. unrealon_sdk/src/clients/python_http/api_config.py +0 -228
  179. unrealon_sdk/src/clients/python_http/models/BaseModel.py +0 -12
  180. unrealon_sdk/src/clients/python_http/models/BroadcastDeliveryStats.py +0 -33
  181. unrealon_sdk/src/clients/python_http/models/BroadcastMessage.py +0 -17
  182. unrealon_sdk/src/clients/python_http/models/BroadcastMessageRequest.py +0 -35
  183. unrealon_sdk/src/clients/python_http/models/BroadcastPriority.py +0 -10
  184. unrealon_sdk/src/clients/python_http/models/BroadcastResponse.py +0 -21
  185. unrealon_sdk/src/clients/python_http/models/BroadcastResultResponse.py +0 -33
  186. unrealon_sdk/src/clients/python_http/models/BroadcastTarget.py +0 -11
  187. unrealon_sdk/src/clients/python_http/models/ConnectionStats.py +0 -27
  188. unrealon_sdk/src/clients/python_http/models/ConnectionsResponse.py +0 -21
  189. unrealon_sdk/src/clients/python_http/models/DeveloperMessageResponse.py +0 -23
  190. unrealon_sdk/src/clients/python_http/models/ErrorResponse.py +0 -25
  191. unrealon_sdk/src/clients/python_http/models/HTTPValidationError.py +0 -16
  192. unrealon_sdk/src/clients/python_http/models/HealthResponse.py +0 -23
  193. unrealon_sdk/src/clients/python_http/models/HealthStatus.py +0 -33
  194. unrealon_sdk/src/clients/python_http/models/LogLevel.py +0 -10
  195. unrealon_sdk/src/clients/python_http/models/LoggingRequest.py +0 -27
  196. unrealon_sdk/src/clients/python_http/models/LoggingResponse.py +0 -23
  197. unrealon_sdk/src/clients/python_http/models/MaintenanceMode.py +0 -9
  198. unrealon_sdk/src/clients/python_http/models/MaintenanceModeRequest.py +0 -33
  199. unrealon_sdk/src/clients/python_http/models/MaintenanceStatusResponse.py +0 -39
  200. unrealon_sdk/src/clients/python_http/models/ParserCommandRequest.py +0 -25
  201. unrealon_sdk/src/clients/python_http/models/ParserMessageResponse.py +0 -21
  202. unrealon_sdk/src/clients/python_http/models/ParserRegistrationRequest.py +0 -28
  203. unrealon_sdk/src/clients/python_http/models/ParserRegistrationResponse.py +0 -25
  204. unrealon_sdk/src/clients/python_http/models/ParserType.py +0 -10
  205. unrealon_sdk/src/clients/python_http/models/ProxyBlockRequest.py +0 -19
  206. unrealon_sdk/src/clients/python_http/models/ProxyEndpointResponse.py +0 -20
  207. unrealon_sdk/src/clients/python_http/models/ProxyListResponse.py +0 -19
  208. unrealon_sdk/src/clients/python_http/models/ProxyProvider.py +0 -10
  209. unrealon_sdk/src/clients/python_http/models/ProxyPurchaseRequest.py +0 -25
  210. unrealon_sdk/src/clients/python_http/models/ProxyResponse.py +0 -47
  211. unrealon_sdk/src/clients/python_http/models/ProxyRotationRequest.py +0 -23
  212. unrealon_sdk/src/clients/python_http/models/ProxyStatus.py +0 -10
  213. unrealon_sdk/src/clients/python_http/models/ProxyUsageRequest.py +0 -19
  214. unrealon_sdk/src/clients/python_http/models/ProxyUsageStatsResponse.py +0 -26
  215. unrealon_sdk/src/clients/python_http/models/ServiceRegistrationDto.py +0 -23
  216. unrealon_sdk/src/clients/python_http/models/ServiceStatsResponse.py +0 -31
  217. unrealon_sdk/src/clients/python_http/models/SessionStartRequest.py +0 -23
  218. unrealon_sdk/src/clients/python_http/models/SuccessResponse.py +0 -25
  219. unrealon_sdk/src/clients/python_http/models/SystemNotificationResponse.py +0 -23
  220. unrealon_sdk/src/clients/python_http/models/ValidationError.py +0 -18
  221. unrealon_sdk/src/clients/python_http/models/ValidationErrorResponse.py +0 -21
  222. unrealon_sdk/src/clients/python_http/models/WebSocketMetrics.py +0 -21
  223. unrealon_sdk/src/clients/python_http/models/__init__.py +0 -44
  224. unrealon_sdk/src/clients/python_http/services/None_service.py +0 -35
  225. unrealon_sdk/src/clients/python_http/services/ParserManagement_service.py +0 -190
  226. unrealon_sdk/src/clients/python_http/services/ProxyManagement_service.py +0 -289
  227. unrealon_sdk/src/clients/python_http/services/SocketLogging_service.py +0 -187
  228. unrealon_sdk/src/clients/python_http/services/SystemHealth_service.py +0 -119
  229. unrealon_sdk/src/clients/python_http/services/WebSocketAPI_service.py +0 -198
  230. unrealon_sdk/src/clients/python_http/services/__init__.py +0 -0
  231. unrealon_sdk/src/clients/python_http/services/admin_service.py +0 -125
  232. unrealon_sdk/src/clients/python_http/services/async_None_service.py +0 -35
  233. unrealon_sdk/src/clients/python_http/services/async_ParserManagement_service.py +0 -190
  234. unrealon_sdk/src/clients/python_http/services/async_ProxyManagement_service.py +0 -289
  235. unrealon_sdk/src/clients/python_http/services/async_SocketLogging_service.py +0 -189
  236. unrealon_sdk/src/clients/python_http/services/async_SystemHealth_service.py +0 -123
  237. unrealon_sdk/src/clients/python_http/services/async_WebSocketAPI_service.py +0 -200
  238. unrealon_sdk/src/clients/python_http/services/async_admin_service.py +0 -125
  239. unrealon_sdk/src/clients/python_websocket/__init__.py +0 -28
  240. unrealon_sdk/src/clients/python_websocket/client.py +0 -490
  241. unrealon_sdk/src/clients/python_websocket/events.py +0 -732
  242. unrealon_sdk/src/clients/python_websocket/example.py +0 -136
  243. unrealon_sdk/src/clients/python_websocket/types.py +0 -871
  244. unrealon_sdk/src/core/__init__.py +0 -64
  245. unrealon_sdk/src/core/client.py +0 -556
  246. unrealon_sdk/src/core/config.py +0 -465
  247. unrealon_sdk/src/core/exceptions.py +0 -239
  248. unrealon_sdk/src/core/metadata.py +0 -191
  249. unrealon_sdk/src/core/models.py +0 -142
  250. unrealon_sdk/src/core/types.py +0 -68
  251. unrealon_sdk/src/dto/__init__.py +0 -268
  252. unrealon_sdk/src/dto/authentication.py +0 -108
  253. unrealon_sdk/src/dto/cache.py +0 -208
  254. unrealon_sdk/src/dto/common.py +0 -19
  255. unrealon_sdk/src/dto/concurrency.py +0 -393
  256. unrealon_sdk/src/dto/events.py +0 -108
  257. unrealon_sdk/src/dto/health.py +0 -339
  258. unrealon_sdk/src/dto/load_balancing.py +0 -336
  259. unrealon_sdk/src/dto/logging.py +0 -230
  260. unrealon_sdk/src/dto/performance.py +0 -165
  261. unrealon_sdk/src/dto/rate_limiting.py +0 -295
  262. unrealon_sdk/src/dto/resource_pooling.py +0 -128
  263. unrealon_sdk/src/dto/structured_logging.py +0 -112
  264. unrealon_sdk/src/dto/task_scheduling.py +0 -121
  265. unrealon_sdk/src/dto/websocket.py +0 -55
  266. unrealon_sdk/src/enterprise/__init__.py +0 -59
  267. unrealon_sdk/src/enterprise/authentication.py +0 -401
  268. unrealon_sdk/src/enterprise/cache_manager.py +0 -578
  269. unrealon_sdk/src/enterprise/error_recovery.py +0 -494
  270. unrealon_sdk/src/enterprise/event_system.py +0 -549
  271. unrealon_sdk/src/enterprise/health_monitor.py +0 -747
  272. unrealon_sdk/src/enterprise/load_balancer.py +0 -964
  273. unrealon_sdk/src/enterprise/logging/__init__.py +0 -68
  274. unrealon_sdk/src/enterprise/logging/cleanup.py +0 -156
  275. unrealon_sdk/src/enterprise/logging/development.py +0 -744
  276. unrealon_sdk/src/enterprise/logging/service.py +0 -410
  277. unrealon_sdk/src/enterprise/multithreading_manager.py +0 -853
  278. unrealon_sdk/src/enterprise/performance_monitor.py +0 -539
  279. unrealon_sdk/src/enterprise/proxy_manager.py +0 -696
  280. unrealon_sdk/src/enterprise/rate_limiter.py +0 -652
  281. unrealon_sdk/src/enterprise/resource_pool.py +0 -763
  282. unrealon_sdk/src/enterprise/task_scheduler.py +0 -709
  283. unrealon_sdk/src/internal/__init__.py +0 -10
  284. unrealon_sdk/src/internal/command_router.py +0 -497
  285. unrealon_sdk/src/internal/connection_manager.py +0 -397
  286. unrealon_sdk/src/internal/http_client.py +0 -446
  287. unrealon_sdk/src/internal/websocket_client.py +0 -420
  288. unrealon_sdk/src/provider.py +0 -471
  289. unrealon_sdk/src/utils.py +0 -234
  290. /unrealon_browser/{src/cli → cli}/__init__.py +0 -0
  291. /unrealon_browser/{src/cli → cli}/interactive_mode.py +0 -0
  292. /unrealon_browser/{src/cli → cli}/main.py +0 -0
  293. /unrealon_browser/{src/core → core}/__init__.py +0 -0
  294. /unrealon_browser/{src/dto → dto}/__init__.py +0 -0
  295. /unrealon_browser/{src/dto → dto}/models/config.py +0 -0
  296. /unrealon_browser/{src/dto → dto}/models/core.py +0 -0
  297. /unrealon_browser/{src/dto → dto}/models/dataclasses.py +0 -0
  298. /unrealon_browser/{src/dto → dto}/models/detection.py +0 -0
  299. /unrealon_browser/{src/dto → dto}/models/enums.py +0 -0
  300. /unrealon_browser/{src/dto → dto}/models/statistics.py +0 -0
  301. /unrealon_browser/{src/managers → managers}/__init__.py +0 -0
  302. /unrealon_browser/{src/managers → managers}/stealth.py +0 -0
@@ -0,0 +1,321 @@
1
+ """
2
+ Result Manager - Automatic result tracking and metrics with Pydantic v2
3
+
4
+ Strict compliance with CRITICAL_REQUIREMENTS.md:
5
+ - No Dict[str, Any] usage
6
+ - Complete type annotations
7
+ - Pydantic v2 models everywhere
8
+ - Custom exception hierarchy
9
+ """
10
+
11
+ from typing import Optional, List, TypeVar, Generic
12
+ from datetime import datetime
13
+ from pydantic import BaseModel, Field, ConfigDict, field_validator
14
+ from enum import Enum
15
+
16
+
17
+ T = TypeVar('T', bound=BaseModel)
18
+
19
+
20
+ class OperationStatus(str, Enum):
21
+ """Operation status enumeration"""
22
+ PENDING = "pending"
23
+ RUNNING = "running"
24
+ COMPLETED = "completed"
25
+ FAILED = "failed"
26
+ CANCELLED = "cancelled"
27
+
28
+
29
+ class ParseMetrics(BaseModel):
30
+ """Parse operation metrics with strict typing"""
31
+ model_config = ConfigDict(
32
+ validate_assignment=True,
33
+ extra="forbid"
34
+ )
35
+
36
+ started_at: datetime = Field(
37
+ default_factory=datetime.now,
38
+ description="Operation start time"
39
+ )
40
+ completed_at: Optional[datetime] = Field(
41
+ default=None,
42
+ description="Operation completion time"
43
+ )
44
+ duration_seconds: Optional[float] = Field(
45
+ default=None,
46
+ ge=0.0,
47
+ description="Operation duration in seconds"
48
+ )
49
+ pages_processed: int = Field(
50
+ default=0,
51
+ ge=0,
52
+ description="Number of pages processed"
53
+ )
54
+ items_found: int = Field(
55
+ default=0,
56
+ ge=0,
57
+ description="Number of items found"
58
+ )
59
+ errors_count: int = Field(
60
+ default=0,
61
+ ge=0,
62
+ description="Number of errors encountered"
63
+ )
64
+ warnings_count: int = Field(
65
+ default=0,
66
+ ge=0,
67
+ description="Number of warnings encountered"
68
+ )
69
+ status: OperationStatus = Field(
70
+ default=OperationStatus.PENDING,
71
+ description="Current operation status"
72
+ )
73
+
74
+ def complete(self, status: OperationStatus = OperationStatus.COMPLETED) -> None:
75
+ """Mark operation as completed"""
76
+ self.completed_at = datetime.now()
77
+ if self.completed_at and self.started_at:
78
+ self.duration_seconds = (self.completed_at - self.started_at).total_seconds()
79
+ self.status = status
80
+
81
+
82
+ class ParseResult(BaseModel, Generic[T]):
83
+ """Generic parse result with metrics and strict typing"""
84
+ model_config = ConfigDict(
85
+ validate_assignment=True,
86
+ extra="forbid"
87
+ )
88
+
89
+ data: List[T] = Field(
90
+ default_factory=list,
91
+ description="Parsed data items"
92
+ )
93
+ metrics: ParseMetrics = Field(
94
+ default_factory=ParseMetrics,
95
+ description="Operation metrics"
96
+ )
97
+ source_urls: List[str] = Field(
98
+ default_factory=list,
99
+ description="Source URLs processed"
100
+ )
101
+ parser_id: str = Field(
102
+ ...,
103
+ min_length=1,
104
+ description="Parser identifier"
105
+ )
106
+ error_message: Optional[str] = Field(
107
+ default=None,
108
+ description="Error message if operation failed"
109
+ )
110
+ warnings: List[str] = Field(
111
+ default_factory=list,
112
+ description="Warning messages"
113
+ )
114
+
115
+ @field_validator('source_urls')
116
+ @classmethod
117
+ def validate_urls(cls, v: List[str]) -> List[str]:
118
+ """Validate URL format"""
119
+ for url in v:
120
+ if not url.startswith(('http://', 'https://')):
121
+ raise ValueError(f"Invalid URL format: {url}")
122
+ return v
123
+
124
+ def model_post_init(self, __context) -> None:
125
+ """Update metrics after initialization"""
126
+ self.metrics.items_found = len(self.data)
127
+
128
+
129
+ class ResultManagerError(Exception):
130
+ """Base exception for result manager errors"""
131
+ def __init__(self, message: str, operation: str, details: Optional[dict[str, str]] = None):
132
+ self.message = message
133
+ self.operation = operation
134
+ self.details = details or {}
135
+ super().__init__(message)
136
+
137
+
138
+ class OperationNotFoundError(ResultManagerError):
139
+ """Raised when operation is not found"""
140
+ pass
141
+
142
+
143
+ class InvalidOperationStateError(ResultManagerError):
144
+ """Raised when operation is in invalid state"""
145
+ pass
146
+
147
+
148
+ class ResultManager:
149
+ """
150
+ 🎯 Result Manager - Automatic result tracking and metrics
151
+
152
+ Features:
153
+ - Automatic timing and metrics
154
+ - Result aggregation
155
+ - Error tracking
156
+ - Performance monitoring
157
+ - Type-safe operations
158
+ """
159
+
160
+ def __init__(self, parser_id: str):
161
+ if not parser_id.strip():
162
+ raise ValueError("Parser ID cannot be empty")
163
+
164
+ self.parser_id: str = parser_id
165
+ self._current_metrics: Optional[ParseMetrics] = None
166
+ self._results_history: List[ParseResult] = []
167
+
168
+ def start_operation(self) -> ParseMetrics:
169
+ """Start tracking a new parse operation"""
170
+ if self._current_metrics and self._current_metrics.status == OperationStatus.RUNNING:
171
+ raise InvalidOperationStateError(
172
+ message="Cannot start new operation while another is running",
173
+ operation="start_operation",
174
+ details={"current_status": self._current_metrics.status.value}
175
+ )
176
+
177
+ self._current_metrics = ParseMetrics(status=OperationStatus.RUNNING)
178
+ return self._current_metrics
179
+
180
+ def track_page(self) -> None:
181
+ """Track a processed page"""
182
+ if not self._current_metrics:
183
+ raise OperationNotFoundError(
184
+ message="No operation in progress",
185
+ operation="track_page"
186
+ )
187
+
188
+ self._current_metrics.pages_processed += 1
189
+
190
+ def track_error(self) -> None:
191
+ """Track an error"""
192
+ if not self._current_metrics:
193
+ raise OperationNotFoundError(
194
+ message="No operation in progress",
195
+ operation="track_error"
196
+ )
197
+
198
+ self._current_metrics.errors_count += 1
199
+
200
+ def track_warning(self) -> None:
201
+ """Track a warning"""
202
+ if not self._current_metrics:
203
+ raise OperationNotFoundError(
204
+ message="No operation in progress",
205
+ operation="track_warning"
206
+ )
207
+
208
+ self._current_metrics.warnings_count += 1
209
+
210
+ def complete_operation(
211
+ self,
212
+ data: List[T],
213
+ source_urls: List[str],
214
+ success: bool = True,
215
+ error_message: Optional[str] = None,
216
+ warnings: Optional[List[str]] = None
217
+ ) -> ParseResult[T]:
218
+ """Complete the current operation and return result"""
219
+ if not self._current_metrics:
220
+ raise OperationNotFoundError(
221
+ message="No operation in progress",
222
+ operation="complete_operation"
223
+ )
224
+
225
+ status = OperationStatus.COMPLETED if success else OperationStatus.FAILED
226
+ self._current_metrics.complete(status)
227
+
228
+ result = ParseResult[T](
229
+ data=data,
230
+ metrics=self._current_metrics,
231
+ source_urls=source_urls,
232
+ parser_id=self.parser_id,
233
+ error_message=error_message,
234
+ warnings=warnings or []
235
+ )
236
+
237
+ self._results_history.append(result)
238
+ self._current_metrics = None
239
+
240
+ return result
241
+
242
+ def cancel_operation(self, reason: str) -> None:
243
+ """Cancel the current operation"""
244
+ if not self._current_metrics:
245
+ raise OperationNotFoundError(
246
+ message="No operation in progress",
247
+ operation="cancel_operation"
248
+ )
249
+
250
+ self._current_metrics.complete(OperationStatus.CANCELLED)
251
+
252
+ # Create cancelled result
253
+ result = ParseResult[BaseModel](
254
+ data=[],
255
+ metrics=self._current_metrics,
256
+ source_urls=[],
257
+ parser_id=self.parser_id,
258
+ error_message=f"Operation cancelled: {reason}"
259
+ )
260
+
261
+ self._results_history.append(result)
262
+ self._current_metrics = None
263
+
264
+ def get_current_metrics(self) -> Optional[ParseMetrics]:
265
+ """Get current operation metrics"""
266
+ return self._current_metrics
267
+
268
+ def get_history(self) -> List[ParseResult]:
269
+ """Get results history"""
270
+ return [
271
+ ParseResult.model_validate(result.model_dump())
272
+ for result in self._results_history
273
+ ]
274
+
275
+ def get_stats(self) -> dict[str, float]:
276
+ """Get overall statistics"""
277
+ if not self._results_history:
278
+ return {
279
+ "total_operations": 0.0,
280
+ "success_rate": 0.0,
281
+ "average_duration": 0.0,
282
+ "total_items": 0.0,
283
+ "total_pages": 0.0
284
+ }
285
+
286
+ successful = [
287
+ r for r in self._results_history
288
+ if r.metrics.status == OperationStatus.COMPLETED
289
+ ]
290
+
291
+ total_items = sum(r.metrics.items_found for r in self._results_history)
292
+ total_pages = sum(r.metrics.pages_processed for r in self._results_history)
293
+
294
+ durations = [
295
+ r.metrics.duration_seconds
296
+ for r in self._results_history
297
+ if r.metrics.duration_seconds is not None
298
+ ]
299
+ avg_duration = sum(durations) / len(durations) if durations else 0.0
300
+
301
+ return {
302
+ "total_operations": float(len(self._results_history)),
303
+ "successful_operations": float(len(successful)),
304
+ "failed_operations": float(len(self._results_history) - len(successful)),
305
+ "success_rate": len(successful) / len(self._results_history) * 100.0,
306
+ "total_items_found": float(total_items),
307
+ "total_pages_processed": float(total_pages),
308
+ "average_duration_seconds": round(avg_duration, 2),
309
+ "items_per_operation": total_items / len(self._results_history) if self._results_history else 0.0
310
+ }
311
+
312
+ def clear_history(self) -> None:
313
+ """Clear results history"""
314
+ self._results_history.clear()
315
+
316
+ def get_recent_results(self, limit: int = 10) -> List[ParseResult]:
317
+ """Get recent results with limit"""
318
+ if limit <= 0:
319
+ raise ValueError("Limit must be positive")
320
+
321
+ return self._results_history[-limit:]