unrealon 2.0.27__py3-none-any.whl → 2.0.29__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unrealon
3
- Version: 2.0.27
3
+ Version: 2.0.29
4
4
  Summary: Enterprise-grade web scraping platform with AI-powered automation and real-time orchestration capabilities
5
5
  Author-email: UnrealOn Team <team@unrealon.com>
6
6
  License: MIT
@@ -128,14 +128,14 @@ unrealon_driver/utils/time.py,sha256=Oxk1eicKeZl8ZWbf7gu1Ll716k6CpXmVj67FHSnPIsA
128
128
  unrealon_installer/__init__.py,sha256=JxA2hKat5E6R6nt-batuAc-2Cr0nO2M0XW0vOFU_xy0,333
129
129
  unrealon_installer/browser_fixes.py,sha256=f67T41e4vfOpDAu1hiDEZ5-BLJ663Bl7oWiHD83rR6E,8081
130
130
  unrealon_installer/core.py,sha256=VvAi7iNBFUrJFUkANQ0gv4tyYCaf-cgtUboXVnrjr50,3826
131
- unrealon_installer/platform.py,sha256=NI6-j6674jLWjF0RFRDwXW01D0OueEhhijjevgmbAVs,3122
131
+ unrealon_installer/platform.py,sha256=40XrpEN7lI1nALK06JF7wJ_fRhl0IQE70crW44KrC5Y,5595
132
132
  unrealon_installer/templates.py,sha256=PBGfKWlrhtd92h2c68RhtXgICATmHkGObRn6nT0e2Jg,1920
133
133
  unrealon_installer/batch_templates/quick_run.bat.j2,sha256=B5_vNI7qbds-uHA3rQGx77cle19wKRgerCDHafLaQwc,554
134
- unrealon_installer/batch_templates/start.bat.j2,sha256=o7mbo__76BSGj4WGPBYjBgn4d3uLXAoChYbbeyGInXQ,6457
134
+ unrealon_installer/batch_templates/start.bat.j2,sha256=_4M-iKJzcVuh7ORkJWcOE7Yd8X7gyCa5FMKwRhyRW2k,6529
135
135
  unrealon_installer/batch_templates/test.bat.j2,sha256=eq_Bj-zN6jUZWLwgzPtYDCr4YbgjseMSIfDPYT5ODFw,1348
136
- unrealon-2.0.27.dist-info/LICENSE,sha256=eEH8mWZW49YMpl4Sh5MtKqkZ8aVTzKQXiNPEnvL14ns,1070
137
- unrealon-2.0.27.dist-info/METADATA,sha256=GJbUttkVDqzNBjid2oIORE3s7FZ_phH91mdLKXymiQE,15718
138
- unrealon-2.0.27.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
139
- unrealon-2.0.27.dist-info/entry_points.txt,sha256=tBJgozewpyuXznEYIsLwfE1s16VRjy3Wizhuyh26zb4,153
140
- unrealon-2.0.27.dist-info/top_level.txt,sha256=qN6Q72fe4_i8mTOhYcO3fhGa3g4dmBgvZOsqmK4j8D8,66
141
- unrealon-2.0.27.dist-info/RECORD,,
136
+ unrealon-2.0.29.dist-info/LICENSE,sha256=eEH8mWZW49YMpl4Sh5MtKqkZ8aVTzKQXiNPEnvL14ns,1070
137
+ unrealon-2.0.29.dist-info/METADATA,sha256=frshs3rDpoQvs41L5AZELcLgBt42k_4SFd_fDWJNhck,15718
138
+ unrealon-2.0.29.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
139
+ unrealon-2.0.29.dist-info/entry_points.txt,sha256=tBJgozewpyuXznEYIsLwfE1s16VRjy3Wizhuyh26zb4,153
140
+ unrealon-2.0.29.dist-info/top_level.txt,sha256=qN6Q72fe4_i8mTOhYcO3fhGa3g4dmBgvZOsqmK4j8D8,66
141
+ unrealon-2.0.29.dist-info/RECORD,,
@@ -18,8 +18,18 @@ set PLAYWRIGHT_BROWSERS_PATH=0
18
18
  set PYTHONUNBUFFERED=1
19
19
  set UNREALON_PARSER_NAME={{ parser_name }}
20
20
 
21
- REM Apply UnrealOn platform fixes
22
- python -c "from unrealon_installer.platform import apply_platform_fixes; apply_platform_fixes()" 2>nul
21
+ REM Apply UnrealOn platform fixes - CRITICAL for Windows asyncio
22
+ echo Applying Windows compatibility fixes...
23
+ python -c "
24
+ import sys
25
+ print(f'Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} on {sys.platform}')
26
+ try:
27
+ from unrealon_installer.platform import apply_platform_fixes
28
+ fixes = apply_platform_fixes()
29
+ print(f'Applied fixes: {fixes}')
30
+ except Exception as e:
31
+ print(f'Platform fixes failed: {e}')
32
+ " 2>nul
23
33
 
24
34
  :main_menu
25
35
  echo Main Menu:
@@ -52,38 +62,37 @@ echo {{ parser_name }} Parser - Run Mode
52
62
  echo {{ "=" * (parser_name|length + 25) }}
53
63
  echo.
54
64
 
55
- echo Choose parsing mode:
56
- echo [1] ONE-TIME mode (50 requests, 5 concurrent)
57
- {% if has_persistent %}echo [2] PERSISTENT mode (continuous monitoring){% else %}REM [2] PERSISTENT mode not supported{% endif %}
58
- echo [3] QUICK TEST (5 requests, 2 concurrent)
59
- echo [4] PERFORMANCE TEST (100 requests, 10 concurrent)
60
- echo [5] CUSTOM mode
65
+ echo Choose run mode:
66
+ echo [1] QUICK RUN (default parameters)
67
+ echo [2] TEST RUN (minimal test)
68
+ {% if has_persistent %}echo [3] PERSISTENT mode (continuous){% endif %}
69
+ echo [4] CUSTOM mode (specify arguments)
61
70
  echo.
62
- set /p mode="Enter mode (1-5): "
71
+ set /p mode="Enter mode (1-{% if has_persistent %}4{% else %}3{% endif %}): "
63
72
 
64
73
  if "%mode%"=="1" (
65
- echo Starting ONE-TIME mode: 50 requests, 5 concurrent
66
- python main.py 50 5
74
+ echo Starting default run...
75
+ python main.py
67
76
  )
68
- {% if has_persistent %}
69
77
  if "%mode%"=="2" (
70
- echo Starting PERSISTENT mode: continuous monitoring
71
- python main.py 5 --persistent
78
+ echo Starting test run...
79
+ python main.py 1 1
72
80
  )
73
- {% endif %}
81
+ {% if has_persistent %}
74
82
  if "%mode%"=="3" (
75
- echo Starting QUICK TEST: 5 requests, 2 concurrent
76
- python main.py 5 2
83
+ echo Starting persistent mode...
84
+ python main.py --persistent
77
85
  )
78
86
  if "%mode%"=="4" (
79
- echo Starting PERFORMANCE TEST: 100 requests, 10 concurrent
80
- set /p confirm="This will run 100 requests. Continue? (Y/N): "
81
- if /i "%confirm%"=="Y" python main.py 100 10
87
+ set /p args="Enter arguments (e.g. 5 2): "
88
+ python main.py %args%
82
89
  )
83
- if "%mode%"=="5" (
84
- set /p args="Enter custom arguments: "
90
+ {% else %}
91
+ if "%mode%"=="3" (
92
+ set /p args="Enter arguments (e.g. 5 2): "
85
93
  python main.py %args%
86
94
  )
95
+ {% endif %}
87
96
 
88
97
  echo.
89
98
  echo Press any key to return to main menu...
@@ -33,13 +33,34 @@ def _apply_windows_fixes():
33
33
  """Windows-specific fixes."""
34
34
  fixes = []
35
35
 
36
- # Asyncio event loop policy
36
+ # AGGRESSIVE Windows asyncio fixes
37
37
  if sys.version_info >= (3, 8):
38
38
  try:
39
- asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
40
- fixes.append("ProactorEventLoop")
41
- except Exception:
42
- pass
39
+ # Close any existing event loop first
40
+ try:
41
+ current_loop = asyncio.get_event_loop()
42
+ if current_loop and not current_loop.is_closed():
43
+ current_loop.close()
44
+ except Exception:
45
+ pass
46
+
47
+ # Force ProactorEventLoopPolicy to avoid pipe issues
48
+ policy = asyncio.WindowsProactorEventLoopPolicy()
49
+ asyncio.set_event_loop_policy(policy)
50
+
51
+ # Create and set a completely new event loop
52
+ loop = asyncio.new_event_loop()
53
+ asyncio.set_event_loop(loop)
54
+
55
+ fixes.append("ProactorEventLoop + clean loop")
56
+ except Exception as e:
57
+ logger.warning(f"Failed to set Windows event loop policy: {e}")
58
+ # Fallback: try to at least set the policy
59
+ try:
60
+ asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
61
+ fixes.append("ProactorEventLoop (fallback)")
62
+ except Exception:
63
+ pass
43
64
 
44
65
  # Console encoding
45
66
  try:
@@ -50,9 +71,22 @@ def _apply_windows_fixes():
50
71
  except Exception:
51
72
  pass
52
73
 
53
- # Suppress warnings
74
+ # AGGRESSIVE warning suppression for Windows
54
75
  warnings.filterwarnings("ignore", category=ResourceWarning)
55
- fixes.append("ResourceWarning suppression")
76
+ warnings.filterwarnings("ignore", category=DeprecationWarning, module="asyncio")
77
+ warnings.filterwarnings("ignore", message=".*unclosed transport.*")
78
+ warnings.filterwarnings("ignore", message=".*I/O operation on closed pipe.*")
79
+ warnings.filterwarnings("ignore", message=".*unclosed.*")
80
+ warnings.filterwarnings("ignore", message=".*BaseSubprocessTransport.*")
81
+ warnings.filterwarnings("ignore", message=".*ProactorBasePipeTransport.*")
82
+
83
+ # Set asyncio debug mode to False to reduce noise
84
+ try:
85
+ asyncio.get_event_loop().set_debug(False)
86
+ except Exception:
87
+ pass
88
+
89
+ fixes.append("Aggressive Windows warnings suppression")
56
90
 
57
91
  return fixes
58
92
 
@@ -120,3 +154,33 @@ def check_system_requirements():
120
154
  'python_version': sys.version_info >= (3, 9),
121
155
  'platform_supported': platform.system() in ['Windows', 'Darwin', 'Linux']
122
156
  }
157
+
158
+
159
+ def cleanup_asyncio_resources():
160
+ """Force cleanup of all asyncio resources. Call this at program exit on Windows."""
161
+ if platform.system() != "Windows":
162
+ return
163
+
164
+ try:
165
+ # Get current loop and close all pending tasks
166
+ loop = asyncio.get_event_loop()
167
+ if loop and not loop.is_closed():
168
+ # Cancel all pending tasks
169
+ pending = asyncio.all_tasks(loop)
170
+ for task in pending:
171
+ task.cancel()
172
+
173
+ # Wait for tasks to finish cancellation
174
+ if pending:
175
+ loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
176
+
177
+ # Close the loop
178
+ loop.close()
179
+
180
+ except Exception:
181
+ # Ignore all cleanup errors
182
+ pass
183
+
184
+ # Force garbage collection to clean up any remaining references
185
+ import gc
186
+ gc.collect()