unrealon 1.1.1__py3-none-any.whl → 1.1.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.
- unrealon/__init__.py +16 -6
- unrealon-1.1.4.dist-info/METADATA +658 -0
- unrealon-1.1.4.dist-info/RECORD +54 -0
- {unrealon-1.1.1.dist-info → unrealon-1.1.4.dist-info}/entry_points.txt +1 -1
- unrealon_browser/__init__.py +3 -6
- unrealon_browser/core/browser_manager.py +86 -84
- unrealon_browser/dto/models/config.py +2 -0
- unrealon_browser/managers/captcha.py +165 -185
- unrealon_browser/managers/cookies.py +57 -28
- unrealon_browser/managers/logger_bridge.py +94 -34
- unrealon_browser/managers/profile.py +186 -158
- unrealon_browser/managers/stealth.py +58 -47
- unrealon_driver/__init__.py +8 -21
- unrealon_driver/exceptions.py +5 -0
- unrealon_driver/html_analyzer/__init__.py +32 -0
- unrealon_driver/{parser/managers/html.py → html_analyzer/cleaner.py} +330 -405
- unrealon_driver/html_analyzer/config.py +64 -0
- unrealon_driver/html_analyzer/manager.py +247 -0
- unrealon_driver/html_analyzer/models.py +115 -0
- unrealon_driver/html_analyzer/websocket_analyzer.py +157 -0
- unrealon_driver/models/__init__.py +31 -0
- unrealon_driver/models/websocket.py +98 -0
- unrealon_driver/parser/__init__.py +4 -23
- unrealon_driver/parser/cli_manager.py +6 -5
- unrealon_driver/parser/daemon_manager.py +242 -66
- unrealon_driver/parser/managers/__init__.py +0 -21
- unrealon_driver/parser/managers/config.py +15 -3
- unrealon_driver/parser/parser_manager.py +225 -395
- unrealon_driver/smart_logging/__init__.py +24 -0
- unrealon_driver/smart_logging/models.py +44 -0
- unrealon_driver/smart_logging/smart_logger.py +406 -0
- unrealon_driver/smart_logging/unified_logger.py +525 -0
- unrealon_driver/websocket/__init__.py +31 -0
- unrealon_driver/websocket/client.py +249 -0
- unrealon_driver/websocket/config.py +188 -0
- unrealon_driver/websocket/manager.py +90 -0
- unrealon-1.1.1.dist-info/METADATA +0 -722
- unrealon-1.1.1.dist-info/RECORD +0 -82
- unrealon_bridge/__init__.py +0 -114
- unrealon_bridge/cli.py +0 -316
- unrealon_bridge/client/__init__.py +0 -93
- unrealon_bridge/client/base.py +0 -78
- unrealon_bridge/client/commands.py +0 -89
- unrealon_bridge/client/connection.py +0 -90
- unrealon_bridge/client/events.py +0 -65
- unrealon_bridge/client/health.py +0 -38
- unrealon_bridge/client/html_parser.py +0 -146
- unrealon_bridge/client/logging.py +0 -139
- unrealon_bridge/client/proxy.py +0 -70
- unrealon_bridge/client/scheduler.py +0 -450
- unrealon_bridge/client/session.py +0 -70
- unrealon_bridge/configs/__init__.py +0 -14
- unrealon_bridge/configs/bridge_config.py +0 -212
- unrealon_bridge/configs/bridge_config.yaml +0 -39
- unrealon_bridge/models/__init__.py +0 -138
- unrealon_bridge/models/base.py +0 -28
- unrealon_bridge/models/command.py +0 -41
- unrealon_bridge/models/events.py +0 -40
- unrealon_bridge/models/html_parser.py +0 -79
- unrealon_bridge/models/logging.py +0 -55
- unrealon_bridge/models/parser.py +0 -63
- unrealon_bridge/models/proxy.py +0 -41
- unrealon_bridge/models/requests.py +0 -95
- unrealon_bridge/models/responses.py +0 -88
- unrealon_bridge/models/scheduler.py +0 -592
- unrealon_bridge/models/session.py +0 -28
- unrealon_bridge/server/__init__.py +0 -91
- unrealon_bridge/server/base.py +0 -171
- unrealon_bridge/server/handlers/__init__.py +0 -23
- unrealon_bridge/server/handlers/command.py +0 -110
- unrealon_bridge/server/handlers/html_parser.py +0 -139
- unrealon_bridge/server/handlers/logging.py +0 -95
- unrealon_bridge/server/handlers/parser.py +0 -95
- unrealon_bridge/server/handlers/proxy.py +0 -75
- unrealon_bridge/server/handlers/scheduler.py +0 -545
- unrealon_bridge/server/handlers/session.py +0 -66
- unrealon_driver/browser/__init__.py +0 -8
- unrealon_driver/browser/config.py +0 -74
- unrealon_driver/browser/manager.py +0 -416
- unrealon_driver/parser/managers/browser.py +0 -51
- unrealon_driver/parser/managers/logging.py +0 -609
- {unrealon-1.1.1.dist-info → unrealon-1.1.4.dist-info}/WHEEL +0 -0
- {unrealon-1.1.1.dist-info → unrealon-1.1.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Bridge Server Configuration
|
|
3
|
-
|
|
4
|
-
Pydantic2-based configuration management for the bridge server.
|
|
5
|
-
Includes default test API keys for debugging.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import os
|
|
9
|
-
import yaml
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from typing import Optional, Dict, List, Any
|
|
12
|
-
from pydantic import BaseModel, Field, ConfigDict, field_validator
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class RedisConfig(BaseModel):
|
|
16
|
-
"""Redis connection configuration."""
|
|
17
|
-
|
|
18
|
-
model_config = ConfigDict(str_strip_whitespace=True)
|
|
19
|
-
|
|
20
|
-
url: str = Field(default="redis://localhost:6379/0", description="Redis connection URL")
|
|
21
|
-
max_connections: int = Field(default=10, description="Maximum Redis connections")
|
|
22
|
-
connection_timeout: int = Field(default=5, description="Redis connection timeout in seconds")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class WebSocketConfig(BaseModel):
|
|
26
|
-
"""WebSocket server configuration."""
|
|
27
|
-
|
|
28
|
-
model_config = ConfigDict(str_strip_whitespace=True)
|
|
29
|
-
|
|
30
|
-
host: str = Field(default="localhost", description="WebSocket server host")
|
|
31
|
-
port: int = Field(default=8002, description="WebSocket server port")
|
|
32
|
-
max_connections: int = Field(default=100, description="Maximum WebSocket connections")
|
|
33
|
-
ping_interval: int = Field(default=20, description="WebSocket ping interval in seconds")
|
|
34
|
-
ping_timeout: int = Field(default=10, description="WebSocket ping timeout in seconds")
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class SecurityConfig(BaseModel):
|
|
38
|
-
"""Security and authentication configuration."""
|
|
39
|
-
|
|
40
|
-
model_config = ConfigDict(str_strip_whitespace=True)
|
|
41
|
-
|
|
42
|
-
# Default test API keys for debugging
|
|
43
|
-
test_api_keys: List[str] = Field(default=["amazon_parser_key_123", "test_parser_key_456", "debug_key_789", "development_key_000"], description="Test API keys for debugging (DO NOT USE IN PRODUCTION)")
|
|
44
|
-
|
|
45
|
-
# Production API keys (loaded from environment or config)
|
|
46
|
-
api_keys: List[str] = Field(default_factory=list, description="Production API keys")
|
|
47
|
-
|
|
48
|
-
require_api_key: bool = Field(default=True, description="Whether API key is required for parser registration")
|
|
49
|
-
|
|
50
|
-
allow_test_keys: bool = Field(default=True, description="Allow test API keys (disable in production)")
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class RPCConfig(BaseModel):
|
|
54
|
-
"""RPC configuration."""
|
|
55
|
-
|
|
56
|
-
model_config = ConfigDict(str_strip_whitespace=True)
|
|
57
|
-
|
|
58
|
-
channel: str = Field(default="amazon_parser_rpc", description="RPC channel name")
|
|
59
|
-
timeout: int = Field(default=30, description="RPC call timeout in seconds")
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class PubSubConfig(BaseModel):
|
|
63
|
-
"""PubSub configuration."""
|
|
64
|
-
|
|
65
|
-
model_config = ConfigDict(str_strip_whitespace=True)
|
|
66
|
-
|
|
67
|
-
prefix: str = Field(default="amazon_parser", description="PubSub channel prefix")
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class LoggingConfig(BaseModel):
|
|
71
|
-
"""Logging configuration."""
|
|
72
|
-
|
|
73
|
-
model_config = ConfigDict(str_strip_whitespace=True)
|
|
74
|
-
|
|
75
|
-
level: str = Field(default="INFO", description="Logging level")
|
|
76
|
-
format: str = Field(default="%(asctime)s - %(name)s - %(levelname)s - %(message)s", description="Log message format")
|
|
77
|
-
enable_debug: bool = Field(default=False, description="Enable debug logging")
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class BridgeConfig(BaseModel):
|
|
81
|
-
"""Main bridge server configuration."""
|
|
82
|
-
|
|
83
|
-
model_config = ConfigDict(str_strip_whitespace=True, validate_assignment=True, extra="forbid")
|
|
84
|
-
|
|
85
|
-
# Sub-configurations
|
|
86
|
-
redis: RedisConfig = Field(default_factory=RedisConfig)
|
|
87
|
-
websocket: WebSocketConfig = Field(default_factory=WebSocketConfig)
|
|
88
|
-
security: SecurityConfig = Field(default_factory=SecurityConfig)
|
|
89
|
-
rpc: RPCConfig = Field(default_factory=RPCConfig)
|
|
90
|
-
pubsub: PubSubConfig = Field(default_factory=PubSubConfig)
|
|
91
|
-
logging: LoggingConfig = Field(default_factory=LoggingConfig)
|
|
92
|
-
|
|
93
|
-
# Environment
|
|
94
|
-
environment: str = Field(default="development", description="Environment (development, testing, production)")
|
|
95
|
-
|
|
96
|
-
def get_all_api_keys(self) -> List[str]:
|
|
97
|
-
"""Get all valid API keys (test + production)."""
|
|
98
|
-
all_keys = []
|
|
99
|
-
|
|
100
|
-
# Add production keys
|
|
101
|
-
all_keys.extend(self.security.api_keys)
|
|
102
|
-
|
|
103
|
-
# Add test keys if allowed
|
|
104
|
-
if self.security.allow_test_keys:
|
|
105
|
-
all_keys.extend(self.security.test_api_keys)
|
|
106
|
-
|
|
107
|
-
return all_keys
|
|
108
|
-
|
|
109
|
-
def is_valid_api_key(self, api_key: str) -> bool:
|
|
110
|
-
"""Check if API key is valid."""
|
|
111
|
-
if not self.security.require_api_key:
|
|
112
|
-
return True
|
|
113
|
-
|
|
114
|
-
return api_key in self.get_all_api_keys()
|
|
115
|
-
|
|
116
|
-
def is_production(self) -> bool:
|
|
117
|
-
"""Check if running in production."""
|
|
118
|
-
return self.environment.lower() == "production"
|
|
119
|
-
|
|
120
|
-
def is_development(self) -> bool:
|
|
121
|
-
"""Check if running in development."""
|
|
122
|
-
return self.environment.lower() in ("development", "dev")
|
|
123
|
-
|
|
124
|
-
@field_validator("environment")
|
|
125
|
-
@classmethod
|
|
126
|
-
def validate_environment(cls, v):
|
|
127
|
-
"""Validate environment value."""
|
|
128
|
-
valid_envs = ["development", "dev", "testing", "test", "production", "prod"]
|
|
129
|
-
if v.lower() not in valid_envs:
|
|
130
|
-
raise ValueError(f"Environment must be one of: {valid_envs}")
|
|
131
|
-
return v.lower()
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# Global config cache
|
|
135
|
-
_config_cache: Optional[BridgeConfig] = None
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def get_config_path() -> Path:
|
|
139
|
-
"""Get configuration file path."""
|
|
140
|
-
# Check environment variable first
|
|
141
|
-
config_path = os.getenv("BRIDGE_CONFIG_PATH")
|
|
142
|
-
if config_path:
|
|
143
|
-
return Path(config_path)
|
|
144
|
-
|
|
145
|
-
# Default path
|
|
146
|
-
return Path(__file__).parent / "bridge_config.yaml"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def load_bridge_config(config_path: Optional[Path] = None) -> BridgeConfig:
|
|
150
|
-
"""
|
|
151
|
-
Load bridge configuration from YAML file.
|
|
152
|
-
|
|
153
|
-
Args:
|
|
154
|
-
config_path: Optional path to config file
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
BridgeConfig instance
|
|
158
|
-
"""
|
|
159
|
-
global _config_cache
|
|
160
|
-
|
|
161
|
-
if _config_cache is not None:
|
|
162
|
-
return _config_cache
|
|
163
|
-
|
|
164
|
-
if config_path is None:
|
|
165
|
-
config_path = get_config_path()
|
|
166
|
-
|
|
167
|
-
if config_path.exists():
|
|
168
|
-
with open(config_path, "r", encoding="utf-8") as f:
|
|
169
|
-
config_data = yaml.safe_load(f)
|
|
170
|
-
_config_cache = BridgeConfig(**config_data)
|
|
171
|
-
else:
|
|
172
|
-
# Create default config
|
|
173
|
-
_config_cache = BridgeConfig()
|
|
174
|
-
save_bridge_config(_config_cache, config_path)
|
|
175
|
-
|
|
176
|
-
return _config_cache
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def save_bridge_config(config: BridgeConfig, config_path: Optional[Path] = None) -> Path:
|
|
180
|
-
"""
|
|
181
|
-
Save bridge configuration to YAML file.
|
|
182
|
-
|
|
183
|
-
Args:
|
|
184
|
-
config: BridgeConfig instance
|
|
185
|
-
config_path: Optional path to save config
|
|
186
|
-
|
|
187
|
-
Returns:
|
|
188
|
-
Path where config was saved
|
|
189
|
-
"""
|
|
190
|
-
if config_path is None:
|
|
191
|
-
config_path = get_config_path()
|
|
192
|
-
|
|
193
|
-
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
194
|
-
|
|
195
|
-
with open(config_path, "w", encoding="utf-8") as f:
|
|
196
|
-
yaml.dump(config.model_dump(), f, default_flow_style=False, indent=2, allow_unicode=True)
|
|
197
|
-
|
|
198
|
-
return config_path
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def reload_config() -> BridgeConfig:
|
|
202
|
-
"""Reload configuration from file, clearing cache."""
|
|
203
|
-
global _config_cache
|
|
204
|
-
_config_cache = None
|
|
205
|
-
return load_bridge_config()
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
def create_sample_config() -> BridgeConfig:
|
|
209
|
-
"""Create a sample configuration for testing."""
|
|
210
|
-
return BridgeConfig(
|
|
211
|
-
environment="development", websocket=WebSocketConfig(host="localhost", port=8002), security=SecurityConfig(test_api_keys=["amazon_parser_key_123", "test_parser_key_456", "debug_key_789"], allow_test_keys=True, require_api_key=True), logging=LoggingConfig(level="DEBUG", enable_debug=True)
|
|
212
|
-
)
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
environment: development
|
|
2
|
-
|
|
3
|
-
redis:
|
|
4
|
-
url: redis://localhost:6379/0
|
|
5
|
-
max_connections: 10
|
|
6
|
-
connection_timeout: 5
|
|
7
|
-
|
|
8
|
-
websocket:
|
|
9
|
-
host: localhost
|
|
10
|
-
port: 8002
|
|
11
|
-
max_connections: 100
|
|
12
|
-
ping_interval: 20
|
|
13
|
-
ping_timeout: 10
|
|
14
|
-
|
|
15
|
-
security:
|
|
16
|
-
# Test API keys for debugging (DO NOT USE IN PRODUCTION)
|
|
17
|
-
test_api_keys:
|
|
18
|
-
- amazon_parser_key_123
|
|
19
|
-
- test_parser_key_456
|
|
20
|
-
- debug_key_789
|
|
21
|
-
- development_key_000
|
|
22
|
-
|
|
23
|
-
# Production API keys (add your keys here)
|
|
24
|
-
api_keys: []
|
|
25
|
-
|
|
26
|
-
require_api_key: true
|
|
27
|
-
allow_test_keys: true
|
|
28
|
-
|
|
29
|
-
rpc:
|
|
30
|
-
channel: amazon_parser_rpc
|
|
31
|
-
timeout: 30
|
|
32
|
-
|
|
33
|
-
pubsub:
|
|
34
|
-
prefix: amazon_parser
|
|
35
|
-
|
|
36
|
-
logging:
|
|
37
|
-
level: INFO
|
|
38
|
-
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
39
|
-
enable_debug: false
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Bridge Parsers Models - Decomposed and strictly typed.
|
|
3
|
-
|
|
4
|
-
All models follow CRITICAL_REQUIREMENTS.md:
|
|
5
|
-
- NO Dict[str, Any] usage
|
|
6
|
-
- Strict Pydantic v2 typing
|
|
7
|
-
- NO raw JSON handling
|
|
8
|
-
- Complete type annotations
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
# Base models
|
|
12
|
-
from .base import BaseParserModel, BaseRPCRequest, BaseRPCResponse
|
|
13
|
-
|
|
14
|
-
# Core domain models
|
|
15
|
-
from .parser import ParserInfo, ParserStats, ParserHealth, ParserSystemStats
|
|
16
|
-
from .command import ParserCommand, CommandResult
|
|
17
|
-
from .proxy import ProxyRequest, ProxyInfo
|
|
18
|
-
from .session import ParserSession
|
|
19
|
-
from .events import ParserEvent, WebhookConfig
|
|
20
|
-
from .html_parser import (
|
|
21
|
-
HTMLParseRequest, HTMLParseResult, HTMLParseResponse,
|
|
22
|
-
HTMLParseRPCRequest, HTMLParseRPCResponse
|
|
23
|
-
)
|
|
24
|
-
from .logging import (
|
|
25
|
-
ParserLogEntry, ParserLogRequest, ParserLogResponse
|
|
26
|
-
)
|
|
27
|
-
from .scheduler import (
|
|
28
|
-
TaskStatus, TaskPriority, ScheduleType, TaskExecutionMode,
|
|
29
|
-
CronExpression, TaskParameters, TaskRetryConfig, ScheduledTask,
|
|
30
|
-
TaskQueue, TaskExecutionResult, ParserStatus,
|
|
31
|
-
SchedulerError, TaskValidationError, TaskExecutionError,
|
|
32
|
-
ParserUnavailableError, QueueError
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
# RPC Request models (strict typing)
|
|
36
|
-
from .requests import (
|
|
37
|
-
ParserRegisterRequest,
|
|
38
|
-
ParserStatusRequest,
|
|
39
|
-
ParserListRequest,
|
|
40
|
-
ParserHealthRequest,
|
|
41
|
-
SessionStartRequest,
|
|
42
|
-
SessionEndRequest,
|
|
43
|
-
CommandExecuteRequest,
|
|
44
|
-
CommandCreateRequest,
|
|
45
|
-
CommandStatusRequest,
|
|
46
|
-
ProxyAllocateRequest,
|
|
47
|
-
ProxyReleaseRequest,
|
|
48
|
-
ProxyCheckRequest,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# RPC Response models (strict typing)
|
|
52
|
-
from .responses import (
|
|
53
|
-
ParserRegisterResponse,
|
|
54
|
-
ParserStatusResponse,
|
|
55
|
-
ParserListResponse,
|
|
56
|
-
ParserHealthResponse,
|
|
57
|
-
SessionStartResponse,
|
|
58
|
-
SessionEndResponse,
|
|
59
|
-
CommandExecuteResponse,
|
|
60
|
-
CommandCreateResponse,
|
|
61
|
-
CommandStatusResponse,
|
|
62
|
-
ProxyAllocateResponse,
|
|
63
|
-
ProxyReleaseResponse,
|
|
64
|
-
ProxyCheckResponse,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
__all__ = [
|
|
68
|
-
# Base models
|
|
69
|
-
"BaseParserModel",
|
|
70
|
-
"BaseRPCRequest",
|
|
71
|
-
"BaseRPCResponse",
|
|
72
|
-
# Core domain models
|
|
73
|
-
"ParserInfo",
|
|
74
|
-
"ParserStats",
|
|
75
|
-
"ParserHealth",
|
|
76
|
-
"ParserSystemStats",
|
|
77
|
-
"ParserCommand",
|
|
78
|
-
"CommandResult",
|
|
79
|
-
"ProxyRequest",
|
|
80
|
-
"ProxyInfo",
|
|
81
|
-
"ParserSession",
|
|
82
|
-
"ParserEvent",
|
|
83
|
-
"WebhookConfig",
|
|
84
|
-
# HTML Parser models
|
|
85
|
-
"HTMLParseRequest",
|
|
86
|
-
"HTMLParseResult",
|
|
87
|
-
"HTMLParseResponse",
|
|
88
|
-
"HTMLParseRPCRequest",
|
|
89
|
-
"HTMLParseRPCResponse",
|
|
90
|
-
# Parser Logging models
|
|
91
|
-
"ParserLogEntry",
|
|
92
|
-
"ParserLogRequest",
|
|
93
|
-
"ParserLogResponse",
|
|
94
|
-
# Scheduler models
|
|
95
|
-
"TaskStatus",
|
|
96
|
-
"TaskPriority",
|
|
97
|
-
"ScheduleType",
|
|
98
|
-
"TaskExecutionMode",
|
|
99
|
-
"CronExpression",
|
|
100
|
-
"TaskParameters",
|
|
101
|
-
"TaskRetryConfig",
|
|
102
|
-
"ScheduledTask",
|
|
103
|
-
"TaskQueue",
|
|
104
|
-
"TaskExecutionResult",
|
|
105
|
-
"ParserStatus",
|
|
106
|
-
# Scheduler exceptions
|
|
107
|
-
"SchedulerError",
|
|
108
|
-
"TaskValidationError",
|
|
109
|
-
"TaskExecutionError",
|
|
110
|
-
"ParserUnavailableError",
|
|
111
|
-
"QueueError",
|
|
112
|
-
# RPC Request models
|
|
113
|
-
"ParserRegisterRequest",
|
|
114
|
-
"ParserStatusRequest",
|
|
115
|
-
"ParserListRequest",
|
|
116
|
-
"ParserHealthRequest",
|
|
117
|
-
"SessionStartRequest",
|
|
118
|
-
"SessionEndRequest",
|
|
119
|
-
"CommandExecuteRequest",
|
|
120
|
-
"CommandCreateRequest",
|
|
121
|
-
"CommandStatusRequest",
|
|
122
|
-
"ProxyAllocateRequest",
|
|
123
|
-
"ProxyReleaseRequest",
|
|
124
|
-
"ProxyCheckRequest",
|
|
125
|
-
# RPC Response models
|
|
126
|
-
"ParserRegisterResponse",
|
|
127
|
-
"ParserStatusResponse",
|
|
128
|
-
"ParserListResponse",
|
|
129
|
-
"ParserHealthResponse",
|
|
130
|
-
"SessionStartResponse",
|
|
131
|
-
"SessionEndResponse",
|
|
132
|
-
"CommandExecuteResponse",
|
|
133
|
-
"CommandCreateResponse",
|
|
134
|
-
"CommandStatusResponse",
|
|
135
|
-
"ProxyAllocateResponse",
|
|
136
|
-
"ProxyReleaseResponse",
|
|
137
|
-
"ProxyCheckResponse",
|
|
138
|
-
]
|
unrealon_bridge/models/base.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Base models for parser bridge operations.
|
|
3
|
-
|
|
4
|
-
Provides common base classes and shared types for all parser models.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from pydantic import BaseModel, Field, ConfigDict
|
|
8
|
-
from typing import Optional
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class BaseParserModel(BaseModel):
|
|
12
|
-
"""Base class for all parser models with strict validation."""
|
|
13
|
-
|
|
14
|
-
model_config = ConfigDict(extra="forbid", validate_assignment=True, str_strip_whitespace=True, validate_default=True)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class BaseRPCRequest(BaseParserModel):
|
|
18
|
-
"""Base class for all RPC requests."""
|
|
19
|
-
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class BaseRPCResponse(BaseParserModel):
|
|
24
|
-
"""Base class for all RPC responses."""
|
|
25
|
-
|
|
26
|
-
success: bool = Field(description="Whether the operation was successful")
|
|
27
|
-
message: Optional[str] = Field(default=None, description="Human-readable message")
|
|
28
|
-
error: Optional[str] = Field(default=None, description="Error message if success=False")
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Command-related models.
|
|
3
|
-
|
|
4
|
-
Contains models for command execution, tracking, and results.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from typing import Optional, Dict, Literal, Any
|
|
8
|
-
from datetime import datetime
|
|
9
|
-
from pydantic import Field
|
|
10
|
-
from typing_extensions import Annotated
|
|
11
|
-
|
|
12
|
-
from .base import BaseParserModel
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ParserCommand(BaseParserModel):
|
|
16
|
-
"""Parser command definition and tracking."""
|
|
17
|
-
|
|
18
|
-
command_id: Annotated[str, Field(min_length=1, description="Unique command identifier")]
|
|
19
|
-
command_type: Annotated[str, Field(min_length=1, description="Type of command (scrape, parse, etc.)")]
|
|
20
|
-
parser_id: Annotated[str, Field(min_length=1, description="Parser ID that will execute the command")]
|
|
21
|
-
parameters: Dict[str, str] = Field(default_factory=dict, description="Command parameters")
|
|
22
|
-
status: Literal["pending", "running", "completed", "failed", "cancelled"] = "pending"
|
|
23
|
-
priority: Annotated[int, Field(ge=1, le=10)] = 5
|
|
24
|
-
timeout: Annotated[int, Field(gt=0, le=3600, description="Command timeout in seconds")] = 300
|
|
25
|
-
created_at: datetime = Field(default_factory=datetime.now)
|
|
26
|
-
started_at: Optional[datetime] = None
|
|
27
|
-
completed_at: Optional[datetime] = None
|
|
28
|
-
retry_count: Annotated[int, Field(ge=0)] = 0
|
|
29
|
-
max_retries: Annotated[int, Field(ge=0)] = 3
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class CommandResult(BaseParserModel):
|
|
33
|
-
"""Result of command execution."""
|
|
34
|
-
|
|
35
|
-
command_id: Annotated[str, Field(min_length=1, description="Command ID")]
|
|
36
|
-
success: bool = Field(description="Whether command executed successfully")
|
|
37
|
-
result_data: Dict[str, Any] = Field(default_factory=dict, description="Command result data")
|
|
38
|
-
error_message: Optional[str] = None
|
|
39
|
-
execution_time: Annotated[float, Field(ge=0)] = 0.0
|
|
40
|
-
output_size: Annotated[int, Field(ge=0)] = 0
|
|
41
|
-
created_at: datetime = Field(default_factory=datetime.now)
|
unrealon_bridge/models/events.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Event and webhook-related models.
|
|
3
|
-
|
|
4
|
-
Contains models for parser events, logging, and webhook configurations.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from typing import Optional, Dict, List, Literal
|
|
8
|
-
from datetime import datetime
|
|
9
|
-
from pydantic import Field
|
|
10
|
-
from typing_extensions import Annotated
|
|
11
|
-
|
|
12
|
-
from .base import BaseParserModel
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ParserEvent(BaseParserModel):
|
|
16
|
-
"""Parser event for logging and monitoring."""
|
|
17
|
-
|
|
18
|
-
event_id: Annotated[str, Field(min_length=1, description="Unique event identifier")]
|
|
19
|
-
parser_id: Annotated[str, Field(min_length=1, description="Parser ID")]
|
|
20
|
-
event_type: Annotated[str, Field(min_length=1, description="Type of event")]
|
|
21
|
-
level: Literal["debug", "info", "warning", "error", "critical"] = "info"
|
|
22
|
-
message: Annotated[str, Field(min_length=1, description="Event message")]
|
|
23
|
-
data: Dict[str, str] = Field(default_factory=dict, description="Additional event data (string values only)")
|
|
24
|
-
command_id: Optional[str] = None
|
|
25
|
-
session_id: Optional[str] = None
|
|
26
|
-
timestamp: datetime = Field(default_factory=datetime.now)
|
|
27
|
-
source: Optional[str] = None
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class WebhookConfig(BaseParserModel):
|
|
31
|
-
"""Webhook configuration for parser events."""
|
|
32
|
-
|
|
33
|
-
webhook_id: Annotated[str, Field(min_length=1, description="Unique webhook identifier")]
|
|
34
|
-
parser_id: Annotated[str, Field(min_length=1, description="Parser ID")]
|
|
35
|
-
url: Annotated[str, Field(min_length=1, description="Webhook URL")]
|
|
36
|
-
events: List[str] = Field(default_factory=list, description="Events to trigger webhook")
|
|
37
|
-
headers: Dict[str, str] = Field(default_factory=dict, description="Custom headers")
|
|
38
|
-
secret: Optional[str] = None
|
|
39
|
-
active: bool = True
|
|
40
|
-
created_at: datetime = Field(default_factory=datetime.now)
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
HTML Parser models for LLM-based HTML parsing.
|
|
3
|
-
|
|
4
|
-
Models for sending HTML content to Django backend for AI-powered parsing.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from typing import Dict, List, Optional, Any
|
|
9
|
-
from pydantic import BaseModel, Field
|
|
10
|
-
|
|
11
|
-
from .base import BaseParserModel
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class HTMLParseRequest(BaseParserModel):
|
|
15
|
-
"""Request for HTML parsing via AI/LLM."""
|
|
16
|
-
|
|
17
|
-
html_content: str = Field(..., description="Raw HTML content to parse")
|
|
18
|
-
parser_id: str = Field(..., description="ID of the parser making the request")
|
|
19
|
-
url: Optional[str] = Field(None, description="Source URL of the HTML (for context)")
|
|
20
|
-
parse_type: str = Field("general", description="Type of parsing (product, listing, article, etc.)")
|
|
21
|
-
instructions: Optional[str] = Field(None, description="Additional parsing instructions")
|
|
22
|
-
timeout: int = Field(60, description="Timeout in seconds (default 60s for LLM processing)")
|
|
23
|
-
metadata: Dict[str, str] = Field(default_factory=dict, description="Additional metadata")
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class HTMLParseResult(BaseParserModel):
|
|
27
|
-
"""Result of HTML parsing."""
|
|
28
|
-
|
|
29
|
-
success: bool = Field(..., description="Whether parsing was successful")
|
|
30
|
-
parsed_data: Optional[Dict[str, Any]] = Field(None, description="Parsed JSON data")
|
|
31
|
-
markdown: Optional[str] = Field(None, description="Markdown instructions from Django parser")
|
|
32
|
-
error_message: Optional[str] = Field(None, description="Error message if parsing failed")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class HTMLParseResponse(BaseParserModel):
|
|
36
|
-
"""Response for HTML parsing request."""
|
|
37
|
-
|
|
38
|
-
success: bool = Field(..., description="Whether the request was successful")
|
|
39
|
-
message: Optional[str] = Field(None, description="Response message")
|
|
40
|
-
error: Optional[str] = Field(None, description="Error message if failed")
|
|
41
|
-
result: Optional[HTMLParseResult] = Field(None, description="Parsing result")
|
|
42
|
-
request_id: Optional[str] = Field(None, description="Request ID for tracking")
|
|
43
|
-
processed_at: datetime = Field(default_factory=datetime.now, description="When the request was processed")
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# Request/Response models for RPC
|
|
53
|
-
class HTMLParseRPCRequest(BaseParserModel):
|
|
54
|
-
"""RPC request for HTML parsing."""
|
|
55
|
-
|
|
56
|
-
html_content: str
|
|
57
|
-
parser_id: str
|
|
58
|
-
url: Optional[str] = None
|
|
59
|
-
parse_type: str = "general"
|
|
60
|
-
instructions: Optional[str] = None
|
|
61
|
-
timeout: int = 60
|
|
62
|
-
metadata: Dict[str, str] = Field(default_factory=dict)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class HTMLParseRPCResponse(BaseParserModel):
|
|
66
|
-
"""RPC response for HTML parsing."""
|
|
67
|
-
|
|
68
|
-
success: bool
|
|
69
|
-
message: Optional[str] = None
|
|
70
|
-
error: Optional[str] = None
|
|
71
|
-
result: Optional[HTMLParseResult] = None
|
|
72
|
-
request_id: Optional[str] = None
|
|
73
|
-
processed_at: datetime = Field(default_factory=datetime.now)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Parser logging models.
|
|
3
|
-
|
|
4
|
-
Models for sending parser logs to Django via WebSocket/Redis.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from typing import Dict, Optional
|
|
9
|
-
from enum import Enum
|
|
10
|
-
from pydantic import BaseModel, Field
|
|
11
|
-
|
|
12
|
-
from .base import BaseParserModel
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ParserLogLevel(str, Enum):
|
|
16
|
-
"""Parser log levels."""
|
|
17
|
-
|
|
18
|
-
DEBUG = "DEBUG"
|
|
19
|
-
INFO = "INFO"
|
|
20
|
-
WARNING = "WARNING"
|
|
21
|
-
ERROR = "ERROR"
|
|
22
|
-
CRITICAL = "CRITICAL"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class ParserLogEntry(BaseParserModel):
|
|
26
|
-
"""Parser log entry to send to Django."""
|
|
27
|
-
|
|
28
|
-
parser_id: str = Field(..., description="ID of the parser")
|
|
29
|
-
level: str = Field(..., description="Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)")
|
|
30
|
-
message: str = Field(..., description="Log message")
|
|
31
|
-
timestamp: datetime = Field(default_factory=datetime.now, description="When the log was created")
|
|
32
|
-
|
|
33
|
-
# Optional context
|
|
34
|
-
session_id: Optional[str] = Field(None, description="Parser session ID")
|
|
35
|
-
command_id: Optional[str] = Field(None, description="Command ID if related to command")
|
|
36
|
-
url: Optional[str] = Field(None, description="URL being processed")
|
|
37
|
-
operation: Optional[str] = Field(None, description="Operation being performed")
|
|
38
|
-
|
|
39
|
-
# Additional data
|
|
40
|
-
data: Dict[str, str] = Field(default_factory=dict, description="Additional log data")
|
|
41
|
-
error_details: Optional[str] = Field(None, description="Error details if error log")
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class ParserLogRequest(BaseParserModel):
|
|
45
|
-
"""RPC request for sending parser log."""
|
|
46
|
-
|
|
47
|
-
log_entry: ParserLogEntry
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class ParserLogResponse(BaseParserModel):
|
|
51
|
-
"""RPC response for parser log."""
|
|
52
|
-
|
|
53
|
-
success: bool = Field(..., description="Whether log was sent successfully")
|
|
54
|
-
message: Optional[str] = Field(None, description="Response message")
|
|
55
|
-
error: Optional[str] = Field(None, description="Error message if failed")
|