unrealon 1.0.8__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- unrealon/__init__.py +23 -21
- unrealon-1.1.0.dist-info/METADATA +164 -0
- unrealon-1.1.0.dist-info/RECORD +82 -0
- {unrealon-1.0.8.dist-info → unrealon-1.1.0.dist-info}/WHEEL +1 -1
- unrealon-1.1.0.dist-info/entry_points.txt +9 -0
- {unrealon-1.0.8.dist-info → unrealon-1.1.0.dist-info/licenses}/LICENSE +1 -1
- unrealon_bridge/__init__.py +114 -0
- unrealon_bridge/cli.py +316 -0
- unrealon_bridge/client/__init__.py +93 -0
- unrealon_bridge/client/base.py +78 -0
- unrealon_bridge/client/commands.py +89 -0
- unrealon_bridge/client/connection.py +90 -0
- unrealon_bridge/client/events.py +65 -0
- unrealon_bridge/client/health.py +38 -0
- unrealon_bridge/client/html_parser.py +146 -0
- unrealon_bridge/client/logging.py +139 -0
- unrealon_bridge/client/proxy.py +70 -0
- unrealon_bridge/client/scheduler.py +450 -0
- unrealon_bridge/client/session.py +70 -0
- unrealon_bridge/configs/__init__.py +14 -0
- unrealon_bridge/configs/bridge_config.py +212 -0
- unrealon_bridge/configs/bridge_config.yaml +39 -0
- unrealon_bridge/models/__init__.py +138 -0
- unrealon_bridge/models/base.py +28 -0
- unrealon_bridge/models/command.py +41 -0
- unrealon_bridge/models/events.py +40 -0
- unrealon_bridge/models/html_parser.py +79 -0
- unrealon_bridge/models/logging.py +55 -0
- unrealon_bridge/models/parser.py +63 -0
- unrealon_bridge/models/proxy.py +41 -0
- unrealon_bridge/models/requests.py +95 -0
- unrealon_bridge/models/responses.py +88 -0
- unrealon_bridge/models/scheduler.py +592 -0
- unrealon_bridge/models/session.py +28 -0
- unrealon_bridge/server/__init__.py +91 -0
- unrealon_bridge/server/base.py +171 -0
- unrealon_bridge/server/handlers/__init__.py +23 -0
- unrealon_bridge/server/handlers/command.py +110 -0
- unrealon_bridge/server/handlers/html_parser.py +139 -0
- unrealon_bridge/server/handlers/logging.py +95 -0
- unrealon_bridge/server/handlers/parser.py +95 -0
- unrealon_bridge/server/handlers/proxy.py +75 -0
- unrealon_bridge/server/handlers/scheduler.py +545 -0
- unrealon_bridge/server/handlers/session.py +66 -0
- unrealon_browser/__init__.py +61 -18
- unrealon_browser/{src/cli → cli}/browser_cli.py +6 -13
- unrealon_browser/{src/cli → cli}/cookies_cli.py +5 -1
- unrealon_browser/{src/core → core}/browser_manager.py +2 -2
- unrealon_browser/{src/managers → managers}/captcha.py +1 -1
- unrealon_browser/{src/managers → managers}/cookies.py +1 -1
- unrealon_browser/managers/logger_bridge.py +231 -0
- unrealon_browser/{src/managers → managers}/profile.py +1 -1
- unrealon_driver/__init__.py +73 -19
- unrealon_driver/browser/__init__.py +8 -0
- unrealon_driver/browser/config.py +74 -0
- unrealon_driver/browser/manager.py +416 -0
- unrealon_driver/exceptions.py +28 -0
- unrealon_driver/parser/__init__.py +55 -0
- unrealon_driver/parser/cli_manager.py +141 -0
- unrealon_driver/parser/daemon_manager.py +227 -0
- unrealon_driver/parser/managers/__init__.py +46 -0
- unrealon_driver/parser/managers/browser.py +51 -0
- unrealon_driver/parser/managers/config.py +281 -0
- unrealon_driver/parser/managers/error.py +412 -0
- unrealon_driver/parser/managers/html.py +732 -0
- unrealon_driver/parser/managers/logging.py +609 -0
- unrealon_driver/parser/managers/result.py +321 -0
- unrealon_driver/parser/parser_manager.py +628 -0
- unrealon/sdk_config.py +0 -88
- unrealon-1.0.8.dist-info/METADATA +0 -803
- unrealon-1.0.8.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,446 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
HTTP client wrapper for UnrealOn SDK v1.0
|
|
3
|
-
|
|
4
|
-
Wraps the auto-generated HTTP client with SDK-specific functionality:
|
|
5
|
-
- Automatic retry with exponential backoff
|
|
6
|
-
- Connection pooling and keep-alive optimization
|
|
7
|
-
- Request/response logging with structured data
|
|
8
|
-
- Type-safe API integration
|
|
9
|
-
- SSL/TLS verification and security
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import asyncio
|
|
13
|
-
import logging
|
|
14
|
-
import aiohttp
|
|
15
|
-
from typing import Optional, Dict, Any, Callable, Awaitable
|
|
16
|
-
from datetime import datetime, timedelta
|
|
17
|
-
|
|
18
|
-
from unrealon_sdk.src.core.config import AdapterConfig
|
|
19
|
-
from unrealon_sdk.src.core.exceptions import ConnectionError, AuthenticationError, TimeoutError
|
|
20
|
-
from unrealon_sdk.src.clients.python_http.models import ServiceStatsResponse
|
|
21
|
-
from unrealon_sdk.src.clients.python_http.api_config import configure_global_api
|
|
22
|
-
from unrealon_sdk.src.clients.python_http.models import (
|
|
23
|
-
ParserRegistrationRequest,
|
|
24
|
-
ParserRegistrationResponse,
|
|
25
|
-
HealthResponse,
|
|
26
|
-
ErrorResponse,
|
|
27
|
-
)
|
|
28
|
-
from unrealon_sdk.src.clients.python_http.services.async_ParserManagement_service import (
|
|
29
|
-
register_parser_api_v1_parsers_register_post,
|
|
30
|
-
)
|
|
31
|
-
from unrealon_sdk.src.clients.python_http.services.async_SystemHealth_service import (
|
|
32
|
-
system_health_check_api_v1_health__get,
|
|
33
|
-
)
|
|
34
|
-
from unrealon_sdk.src.clients.python_http import api_config
|
|
35
|
-
from unrealon_sdk.src.clients.python_http.api_config import APIConfig
|
|
36
|
-
from unrealon_sdk.src.utils import generate_correlation_id, sanitize_log_data
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class HTTPClientWrapper:
|
|
40
|
-
"""
|
|
41
|
-
Wrapper for auto-generated HTTP client.
|
|
42
|
-
|
|
43
|
-
Provides SDK-specific functionality while using the generated client
|
|
44
|
-
for actual HTTP communication.
|
|
45
|
-
|
|
46
|
-
Features:
|
|
47
|
-
- Automatic retry with exponential backoff
|
|
48
|
-
- Connection pooling with keep-alive optimization
|
|
49
|
-
- Comprehensive request/response logging
|
|
50
|
-
- SSL/TLS verification and security
|
|
51
|
-
- Type-safe API integration using generated services
|
|
52
|
-
- Performance monitoring and metrics
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
def __init__(self, config: AdapterConfig, logger: logging.Logger):
|
|
56
|
-
"""
|
|
57
|
-
Initialize HTTP client wrapper.
|
|
58
|
-
|
|
59
|
-
Args:
|
|
60
|
-
config: Adapter configuration
|
|
61
|
-
logger: Logger instance
|
|
62
|
-
"""
|
|
63
|
-
self.config = config
|
|
64
|
-
self.logger = logger
|
|
65
|
-
|
|
66
|
-
# HTTP client session
|
|
67
|
-
self._session: Optional[aiohttp.ClientSession] = None
|
|
68
|
-
|
|
69
|
-
# Performance tracking
|
|
70
|
-
self._request_count = 0
|
|
71
|
-
self._error_count = 0
|
|
72
|
-
self._total_response_time = 0.0
|
|
73
|
-
|
|
74
|
-
# Connection health
|
|
75
|
-
self._last_successful_request: Optional[datetime] = None
|
|
76
|
-
self._consecutive_failures = 0
|
|
77
|
-
|
|
78
|
-
self.logger.debug("HTTPClientWrapper initialized")
|
|
79
|
-
|
|
80
|
-
async def connect(self) -> None:
|
|
81
|
-
"""
|
|
82
|
-
Initialize HTTP client session with optimal configuration.
|
|
83
|
-
|
|
84
|
-
Raises:
|
|
85
|
-
ConnectionError: If session creation fails
|
|
86
|
-
"""
|
|
87
|
-
try:
|
|
88
|
-
# Create connector with connection pooling
|
|
89
|
-
connector = aiohttp.TCPConnector(
|
|
90
|
-
limit=self.config.connection_pool_size,
|
|
91
|
-
limit_per_host=20,
|
|
92
|
-
ttl_dns_cache=300, # 5 minutes DNS cache
|
|
93
|
-
use_dns_cache=True,
|
|
94
|
-
keepalive_timeout=30,
|
|
95
|
-
enable_cleanup_closed=True,
|
|
96
|
-
ssl=True, # Enforce SSL verification
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
# Create timeout configuration
|
|
100
|
-
timeout = aiohttp.ClientTimeout(
|
|
101
|
-
total=self.config.request_timeout_ms / 1000,
|
|
102
|
-
connect=10, # 10 seconds connect timeout
|
|
103
|
-
sock_read=30, # 30 seconds socket read timeout
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Create session with optimal settings
|
|
107
|
-
self._session = aiohttp.ClientSession(
|
|
108
|
-
connector=connector,
|
|
109
|
-
timeout=timeout,
|
|
110
|
-
headers={
|
|
111
|
-
"User-Agent": f"UnrealOn-SDK/1.0 Parser/{self.config.parser_id}",
|
|
112
|
-
"Accept": "application/json",
|
|
113
|
-
"Content-Type": "application/json",
|
|
114
|
-
"Authorization": f"Bearer {self.config.api_key}",
|
|
115
|
-
},
|
|
116
|
-
raise_for_status=False, # We handle status codes manually
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
# Configure the generated API client
|
|
120
|
-
self._configure_api_client()
|
|
121
|
-
|
|
122
|
-
self.logger.info("HTTP client session initialized successfully")
|
|
123
|
-
|
|
124
|
-
except Exception as e:
|
|
125
|
-
self.logger.error(f"Failed to initialize HTTP client: {e}")
|
|
126
|
-
raise ConnectionError(f"HTTP client initialization failed: {e}")
|
|
127
|
-
|
|
128
|
-
def _configure_api_client(self) -> None:
|
|
129
|
-
"""Configure the auto-generated API client using global configuration."""
|
|
130
|
-
# Extract base URL from server URL (convert ws:// to http://)
|
|
131
|
-
base_url = self.config.server_url.replace("wss://", "https://").replace("ws://", "http://")
|
|
132
|
-
|
|
133
|
-
# Remove WebSocket path if present
|
|
134
|
-
if base_url.endswith("/ws"):
|
|
135
|
-
base_url = base_url[:-3]
|
|
136
|
-
|
|
137
|
-
# Configure global API settings - this will be used by all generated API functions
|
|
138
|
-
configure_global_api(
|
|
139
|
-
api_key=self.config.api_key,
|
|
140
|
-
base_url=base_url,
|
|
141
|
-
verify=True
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
self.logger.info(f"Global API client configured: {base_url} with API key: {self.config.api_key[:15]}...")
|
|
145
|
-
|
|
146
|
-
async def disconnect(self) -> None:
|
|
147
|
-
"""Close HTTP client session."""
|
|
148
|
-
if self._session and not self._session.closed:
|
|
149
|
-
try:
|
|
150
|
-
await self._session.close()
|
|
151
|
-
self.logger.info("HTTP client session closed")
|
|
152
|
-
except Exception as e:
|
|
153
|
-
self.logger.error(f"Error closing HTTP session: {e}")
|
|
154
|
-
|
|
155
|
-
self._session = None
|
|
156
|
-
|
|
157
|
-
async def register_parser(
|
|
158
|
-
self, request: ParserRegistrationRequest
|
|
159
|
-
) -> ParserRegistrationResponse:
|
|
160
|
-
"""
|
|
161
|
-
Register parser with the server using generated API client.
|
|
162
|
-
|
|
163
|
-
Args:
|
|
164
|
-
request: Parser registration request
|
|
165
|
-
|
|
166
|
-
Returns:
|
|
167
|
-
Parser registration response
|
|
168
|
-
|
|
169
|
-
Raises:
|
|
170
|
-
AuthenticationError: If authentication fails
|
|
171
|
-
ConnectionError: If request fails
|
|
172
|
-
"""
|
|
173
|
-
correlation_id = generate_correlation_id()
|
|
174
|
-
start_time = datetime.utcnow()
|
|
175
|
-
|
|
176
|
-
try:
|
|
177
|
-
self.logger.info(
|
|
178
|
-
f"Registering parser {request.parser_id}", extra={"correlation_id": correlation_id}
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
# Use the generated API service
|
|
182
|
-
response = await self._make_request_with_retry(
|
|
183
|
-
register_parser_api_v1_parsers_register_post,
|
|
184
|
-
data=request
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
# Track successful request
|
|
188
|
-
self._track_request_success(start_time)
|
|
189
|
-
|
|
190
|
-
if response.success:
|
|
191
|
-
self._last_successful_request = datetime.utcnow()
|
|
192
|
-
self._consecutive_failures = 0
|
|
193
|
-
|
|
194
|
-
self.logger.info(
|
|
195
|
-
f"Parser {request.parser_id} registered successfully",
|
|
196
|
-
extra={
|
|
197
|
-
"correlation_id": correlation_id,
|
|
198
|
-
"response_time_ms": self._calculate_response_time(start_time),
|
|
199
|
-
},
|
|
200
|
-
)
|
|
201
|
-
else:
|
|
202
|
-
self.logger.error(
|
|
203
|
-
f"Parser registration failed: {response.error or response.message}",
|
|
204
|
-
extra={"correlation_id": correlation_id},
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
# Ensure type safety - API should return ParserRegistrationResponse
|
|
208
|
-
assert isinstance(response, ParserRegistrationResponse)
|
|
209
|
-
return response
|
|
210
|
-
|
|
211
|
-
except Exception as e:
|
|
212
|
-
self._track_request_error(start_time)
|
|
213
|
-
|
|
214
|
-
# Determine error type for proper exception
|
|
215
|
-
if "authentication" in str(e).lower() or "unauthorized" in str(e).lower():
|
|
216
|
-
raise AuthenticationError(f"Parser registration authentication failed: {e}")
|
|
217
|
-
|
|
218
|
-
self.logger.error(
|
|
219
|
-
f"Parser registration failed: {e}", extra={"correlation_id": correlation_id}
|
|
220
|
-
)
|
|
221
|
-
raise ConnectionError(f"Parser registration failed: {e}")
|
|
222
|
-
|
|
223
|
-
async def health_check(self) -> HealthResponse:
|
|
224
|
-
"""
|
|
225
|
-
Perform health check using generated API client.
|
|
226
|
-
|
|
227
|
-
Returns:
|
|
228
|
-
Health check response
|
|
229
|
-
|
|
230
|
-
Raises:
|
|
231
|
-
ConnectionError: If health check fails
|
|
232
|
-
"""
|
|
233
|
-
correlation_id = generate_correlation_id()
|
|
234
|
-
start_time = datetime.utcnow()
|
|
235
|
-
|
|
236
|
-
try:
|
|
237
|
-
self.logger.debug("Performing health check", extra={"correlation_id": correlation_id})
|
|
238
|
-
|
|
239
|
-
# Use the generated API service
|
|
240
|
-
response = await self._make_request_with_retry(system_health_check_api_v1_health__get)
|
|
241
|
-
|
|
242
|
-
self._track_request_success(start_time)
|
|
243
|
-
|
|
244
|
-
self.logger.debug(
|
|
245
|
-
f"Health check completed: {response.status}",
|
|
246
|
-
extra={
|
|
247
|
-
"correlation_id": correlation_id,
|
|
248
|
-
"response_time_ms": self._calculate_response_time(start_time),
|
|
249
|
-
},
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
# Ensure type safety - API should return HealthResponse
|
|
253
|
-
assert isinstance(response, HealthResponse)
|
|
254
|
-
return response
|
|
255
|
-
|
|
256
|
-
except Exception as e:
|
|
257
|
-
self._track_request_error(start_time)
|
|
258
|
-
|
|
259
|
-
self.logger.error(f"Health check failed: {e}", extra={"correlation_id": correlation_id})
|
|
260
|
-
raise ConnectionError(f"Health check failed: {e}")
|
|
261
|
-
|
|
262
|
-
async def _make_request_with_retry(
|
|
263
|
-
self, api_function: Callable[..., Awaitable[Any]], **kwargs: Any
|
|
264
|
-
) -> Any:
|
|
265
|
-
"""
|
|
266
|
-
Make API request with automatic retry and exponential backoff.
|
|
267
|
-
|
|
268
|
-
Args:
|
|
269
|
-
api_function: Generated API function to call
|
|
270
|
-
**kwargs: Arguments to pass to the API function
|
|
271
|
-
|
|
272
|
-
Returns:
|
|
273
|
-
API response
|
|
274
|
-
|
|
275
|
-
Raises:
|
|
276
|
-
ConnectionError: If all retries fail
|
|
277
|
-
TimeoutError: If request times out
|
|
278
|
-
"""
|
|
279
|
-
last_exception: Optional[Exception] = None
|
|
280
|
-
|
|
281
|
-
for attempt in range(self.config.max_retries + 1):
|
|
282
|
-
try:
|
|
283
|
-
if attempt > 0:
|
|
284
|
-
# Calculate backoff delay
|
|
285
|
-
delay = min(2**attempt, 30) # Max 30 seconds
|
|
286
|
-
self.logger.debug(f"Retrying request in {delay}s (attempt {attempt + 1})")
|
|
287
|
-
await asyncio.sleep(delay)
|
|
288
|
-
|
|
289
|
-
# Make the actual API call
|
|
290
|
-
if self._session is None:
|
|
291
|
-
raise ConnectionError("HTTP session not initialized")
|
|
292
|
-
|
|
293
|
-
# Create APIConfig with current configuration
|
|
294
|
-
base_url = self.config.server_url.replace("wss://", "https://").replace("ws://", "http://").rstrip("/ws")
|
|
295
|
-
current_api_config = APIConfig(
|
|
296
|
-
base_path=base_url,
|
|
297
|
-
access_token=self.config.api_key,
|
|
298
|
-
verify=True
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
# Debug logging
|
|
302
|
-
self.logger.debug(f"Making request with API config: base_path={current_api_config.base_path}, access_token={current_api_config.access_token[:15] if current_api_config.access_token else None}...")
|
|
303
|
-
self.logger.debug(f"Original config API key: {self.config.api_key[:15] if self.config.api_key else None}...")
|
|
304
|
-
self.logger.debug(f"get_access_token() returns: {current_api_config.get_access_token()[:15] if current_api_config.get_access_token() else None}...")
|
|
305
|
-
|
|
306
|
-
# Pass api_config_override to ensure proper authentication
|
|
307
|
-
# Note: Temporary fix for None header values - should be fixed in generator
|
|
308
|
-
response = await api_function(api_config_override=current_api_config, **kwargs)
|
|
309
|
-
|
|
310
|
-
# Request successful
|
|
311
|
-
return response
|
|
312
|
-
|
|
313
|
-
except asyncio.TimeoutError as e:
|
|
314
|
-
last_exception = TimeoutError(f"Request timed out: {e}")
|
|
315
|
-
self.logger.warning(f"Request timeout on attempt {attempt + 1}")
|
|
316
|
-
|
|
317
|
-
except aiohttp.ClientError as e:
|
|
318
|
-
last_exception = ConnectionError(f"HTTP client error: {e}")
|
|
319
|
-
self.logger.warning(f"HTTP error on attempt {attempt + 1}: {e}")
|
|
320
|
-
|
|
321
|
-
except Exception as e:
|
|
322
|
-
last_exception = ConnectionError(f"Unexpected error: {e}")
|
|
323
|
-
self.logger.warning(f"Unexpected error on attempt {attempt + 1}: {e}")
|
|
324
|
-
self.logger.debug(f"Full exception details: {type(e).__name__}: {e}", exc_info=True)
|
|
325
|
-
|
|
326
|
-
# All retries failed
|
|
327
|
-
self._consecutive_failures += 1
|
|
328
|
-
if last_exception is not None:
|
|
329
|
-
raise last_exception
|
|
330
|
-
else:
|
|
331
|
-
raise ConnectionError("Request failed with unknown error")
|
|
332
|
-
|
|
333
|
-
def _track_request_success(self, start_time: datetime) -> None:
|
|
334
|
-
"""Track successful request metrics."""
|
|
335
|
-
self._request_count += 1
|
|
336
|
-
response_time = (datetime.utcnow() - start_time).total_seconds() * 1000
|
|
337
|
-
self._total_response_time += response_time
|
|
338
|
-
self._last_successful_request = datetime.utcnow()
|
|
339
|
-
self._consecutive_failures = 0
|
|
340
|
-
|
|
341
|
-
def _track_request_error(self, start_time: datetime) -> None:
|
|
342
|
-
"""Track failed request metrics."""
|
|
343
|
-
self._request_count += 1
|
|
344
|
-
self._error_count += 1
|
|
345
|
-
self._consecutive_failures += 1
|
|
346
|
-
response_time = (datetime.utcnow() - start_time).total_seconds() * 1000
|
|
347
|
-
self._total_response_time += response_time
|
|
348
|
-
|
|
349
|
-
def _calculate_response_time(self, start_time: datetime) -> float:
|
|
350
|
-
"""Calculate response time in milliseconds."""
|
|
351
|
-
return (datetime.utcnow() - start_time).total_seconds() * 1000
|
|
352
|
-
|
|
353
|
-
def is_healthy(self) -> bool:
|
|
354
|
-
"""Check if HTTP client is healthy."""
|
|
355
|
-
if self._session is None or self._session.closed:
|
|
356
|
-
return False
|
|
357
|
-
|
|
358
|
-
# Consider unhealthy if too many consecutive failures
|
|
359
|
-
if self._consecutive_failures >= 5:
|
|
360
|
-
return False
|
|
361
|
-
|
|
362
|
-
# Consider unhealthy if no successful requests in last 5 minutes
|
|
363
|
-
if (
|
|
364
|
-
self._last_successful_request is None
|
|
365
|
-
or datetime.utcnow() - self._last_successful_request > timedelta(minutes=5)
|
|
366
|
-
):
|
|
367
|
-
return False
|
|
368
|
-
|
|
369
|
-
return True
|
|
370
|
-
|
|
371
|
-
async def health_check_detailed(self) -> HealthResponse:
|
|
372
|
-
"""
|
|
373
|
-
Perform detailed health check with client metrics.
|
|
374
|
-
|
|
375
|
-
Returns:
|
|
376
|
-
Health response with detailed information
|
|
377
|
-
"""
|
|
378
|
-
try:
|
|
379
|
-
# Perform actual health check
|
|
380
|
-
health_response = await self.health_check()
|
|
381
|
-
|
|
382
|
-
# Add client-specific health information
|
|
383
|
-
client_metrics = {
|
|
384
|
-
"session_active": self._session is not None and not self._session.closed,
|
|
385
|
-
"request_count": self._request_count,
|
|
386
|
-
"error_count": self._error_count,
|
|
387
|
-
"error_rate": self._error_count / max(self._request_count, 1),
|
|
388
|
-
"average_response_time_ms": self._total_response_time / max(self._request_count, 1),
|
|
389
|
-
"consecutive_failures": self._consecutive_failures,
|
|
390
|
-
"last_successful_request": (
|
|
391
|
-
self._last_successful_request.isoformat()
|
|
392
|
-
if self._last_successful_request
|
|
393
|
-
else None
|
|
394
|
-
),
|
|
395
|
-
"is_healthy": self.is_healthy(),
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
# Create enhanced health response (if needed, extend the model)
|
|
399
|
-
# For now, use the original response
|
|
400
|
-
return health_response
|
|
401
|
-
|
|
402
|
-
except Exception as e:
|
|
403
|
-
# Return error health response
|
|
404
|
-
return HealthResponse(
|
|
405
|
-
status="error",
|
|
406
|
-
service="http_client",
|
|
407
|
-
version="1.0.0",
|
|
408
|
-
timestamp=datetime.utcnow().isoformat(),
|
|
409
|
-
components={"error": f"Health check failed: {e}"},
|
|
410
|
-
)
|
|
411
|
-
|
|
412
|
-
def get_statistics(self) -> ServiceStatsResponse:
|
|
413
|
-
"""
|
|
414
|
-
Get HTTP client statistics.
|
|
415
|
-
|
|
416
|
-
Returns:
|
|
417
|
-
ServiceStatsResponse with typed client statistics
|
|
418
|
-
"""
|
|
419
|
-
return ServiceStatsResponse(
|
|
420
|
-
service_name="http_client",
|
|
421
|
-
initialized=True,
|
|
422
|
-
status="healthy" if self.is_healthy() else "unhealthy",
|
|
423
|
-
operations_performed=self._request_count,
|
|
424
|
-
errors_encountered=self._error_count,
|
|
425
|
-
error_rate=(self._error_count / max(self._request_count, 1)) * 100,
|
|
426
|
-
last_operation=(
|
|
427
|
-
self._last_successful_request.isoformat() if self._last_successful_request else None
|
|
428
|
-
),
|
|
429
|
-
uptime_seconds=(
|
|
430
|
-
datetime.utcnow() - getattr(self, "_start_time", datetime.utcnow())
|
|
431
|
-
).total_seconds(),
|
|
432
|
-
additional_metrics={
|
|
433
|
-
"average_response_time_ms": self._total_response_time / max(self._request_count, 1),
|
|
434
|
-
"consecutive_failures": self._consecutive_failures,
|
|
435
|
-
},
|
|
436
|
-
)
|
|
437
|
-
|
|
438
|
-
# Context manager support
|
|
439
|
-
async def __aenter__(self) -> "HTTPClientWrapper":
|
|
440
|
-
"""Async context manager entry."""
|
|
441
|
-
await self.connect()
|
|
442
|
-
return self
|
|
443
|
-
|
|
444
|
-
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
445
|
-
"""Async context manager exit."""
|
|
446
|
-
await self.disconnect()
|