proxy-reader 3.0.0__tar.gz → 3.0.2__tar.gz
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.
- {proxy_reader-3.0.0/proxy_reader.egg-info → proxy_reader-3.0.2}/PKG-INFO +1 -1
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/__init__.py +1 -1
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/checker.py +42 -15
- {proxy_reader-3.0.0 → proxy_reader-3.0.2/proxy_reader.egg-info}/PKG-INFO +1 -1
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/pyproject.toml +2 -2
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/LICENSE +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/MANIFEST.in +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/README.md +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/constants.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/domains.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/logs_config.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/models/__init__.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/models/proxy.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/models/results.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/py.typed +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/reader.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/types.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader/utils.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader.egg-info/SOURCES.txt +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader.egg-info/dependency_links.txt +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader.egg-info/requires.txt +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/proxy_reader.egg-info/top_level.txt +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/setup.cfg +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/tests/test_checker.py +0 -0
- {proxy_reader-3.0.0 → proxy_reader-3.0.2}/tests/test_reader.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import logging
|
|
2
3
|
import random
|
|
3
4
|
import sys
|
|
4
5
|
|
|
@@ -11,7 +12,7 @@ from .constants import (
|
|
|
11
12
|
DEFAULT_CHECK_THREADS,
|
|
12
13
|
MAX_RESPONSE_TIME,
|
|
13
14
|
)
|
|
14
|
-
from .logs_config import logger
|
|
15
|
+
from .logs_config import logger as package_logger
|
|
15
16
|
from .models.proxy import Proxy
|
|
16
17
|
from .models.results import ProxyCheckResults
|
|
17
18
|
from .reader import ProxiesReader
|
|
@@ -25,16 +26,17 @@ class ProxiesChecker:
|
|
|
25
26
|
max_response_time: int = MAX_RESPONSE_TIME,
|
|
26
27
|
connect_timeout: int = CONNECT_TIMEOUT,
|
|
27
28
|
check_urls: list[str] = [],
|
|
29
|
+
logger: logging.Logger | None = None,
|
|
28
30
|
) -> None:
|
|
29
31
|
self._thread_control: asyncio.Semaphore = asyncio.Semaphore(
|
|
30
32
|
proxy_checking_threads
|
|
31
33
|
)
|
|
32
34
|
self._max_response_time = max_response_time
|
|
33
|
-
self.
|
|
34
|
-
self._proxies_checked = False
|
|
35
|
+
self._connect_timeout = connect_timeout
|
|
35
36
|
|
|
36
37
|
self._default_timeout = aiohttp.ClientTimeout(
|
|
37
|
-
total=
|
|
38
|
+
total=self._max_response_time,
|
|
39
|
+
connect=self._connect_timeout,
|
|
38
40
|
)
|
|
39
41
|
|
|
40
42
|
self._check_urls = check_urls or CHECK_URLS
|
|
@@ -42,13 +44,19 @@ class ProxiesChecker:
|
|
|
42
44
|
self._connector = aiohttp.TCPConnector(limit=self._connections_limit)
|
|
43
45
|
self._session: aiohttp.ClientSession | None = None
|
|
44
46
|
|
|
47
|
+
self._logger = logger or package_logger
|
|
48
|
+
|
|
45
49
|
async def close(self) -> None:
|
|
50
|
+
self._logger.debug("Closing checker resources")
|
|
46
51
|
if self._session:
|
|
47
52
|
await self._session.close()
|
|
48
53
|
await self._connector.close()
|
|
49
54
|
|
|
50
55
|
async def _get_session(self) -> aiohttp.ClientSession:
|
|
51
56
|
if self._session is None or self._session.closed:
|
|
57
|
+
self._logger.debug(
|
|
58
|
+
"Creating ClientSession (connector limit=%s)", self._connections_limit
|
|
59
|
+
)
|
|
52
60
|
self._session = aiohttp.ClientSession(connector=self._connector)
|
|
53
61
|
return self._session
|
|
54
62
|
|
|
@@ -62,7 +70,7 @@ class ProxiesChecker:
|
|
|
62
70
|
check_results: ProxyCheckResults = ProxyCheckResults(),
|
|
63
71
|
) -> bool:
|
|
64
72
|
async with self._thread_control:
|
|
65
|
-
|
|
73
|
+
self._logger.debug("Checking HTTP proxy %s", proxy)
|
|
66
74
|
try:
|
|
67
75
|
session = await self._get_session()
|
|
68
76
|
resp = await session.get(
|
|
@@ -73,20 +81,22 @@ class ProxiesChecker:
|
|
|
73
81
|
)
|
|
74
82
|
|
|
75
83
|
if resp.status in range(200, 300):
|
|
76
|
-
|
|
84
|
+
self._logger.debug("%s: working (status=%s)", proxy, resp.status)
|
|
77
85
|
check_results.add_working(proxy)
|
|
78
86
|
return True
|
|
79
87
|
|
|
80
88
|
else:
|
|
81
|
-
|
|
89
|
+
self._logger.debug("%s: bad response status=%s", proxy, resp.status)
|
|
82
90
|
check_results.add_bad(proxy)
|
|
83
91
|
|
|
84
92
|
except asyncio.TimeoutError as e:
|
|
85
|
-
|
|
93
|
+
self._logger.debug("%s: timeout (%s)", proxy, e)
|
|
86
94
|
check_results.add_timeout(proxy)
|
|
87
95
|
|
|
88
96
|
except Exception as e:
|
|
89
|
-
|
|
97
|
+
self._logger.debug(
|
|
98
|
+
"Proxy check failed: %s (%s)", proxy, e, exc_info=True
|
|
99
|
+
)
|
|
90
100
|
check_results.add_error(proxy)
|
|
91
101
|
|
|
92
102
|
return False
|
|
@@ -97,6 +107,7 @@ class ProxiesChecker:
|
|
|
97
107
|
max_resp_time: int = MAX_RESPONSE_TIME,
|
|
98
108
|
connect_timeout: int = CONNECT_TIMEOUT,
|
|
99
109
|
) -> bool:
|
|
110
|
+
self._logger.debug("check_single_proxy: %s", proxy)
|
|
100
111
|
proxy_dict = parse_proxy_line(proxy)
|
|
101
112
|
return await self._check_proxy(
|
|
102
113
|
Proxy(proxy_dict),
|
|
@@ -113,6 +124,10 @@ class ProxiesChecker:
|
|
|
113
124
|
proxies_list = (
|
|
114
125
|
proxies.proxies if isinstance(proxies, ProxiesReader) else proxies
|
|
115
126
|
)
|
|
127
|
+
self._logger.debug(
|
|
128
|
+
"check_multiple_proxies: starting %d HTTP checks (threads limited by semaphore)",
|
|
129
|
+
len(proxies_list),
|
|
130
|
+
)
|
|
116
131
|
check_results = ProxyCheckResults()
|
|
117
132
|
async with asyncio.TaskGroup() as gp:
|
|
118
133
|
for proxy in proxies_list:
|
|
@@ -125,6 +140,13 @@ class ProxiesChecker:
|
|
|
125
140
|
check_results,
|
|
126
141
|
)
|
|
127
142
|
)
|
|
143
|
+
self._logger.debug(
|
|
144
|
+
"check_multiple_proxies: done working=%d bad=%d timeout=%d error=%d",
|
|
145
|
+
check_results.working_count,
|
|
146
|
+
check_results.bad_count,
|
|
147
|
+
check_results.timeout_count,
|
|
148
|
+
check_results.error_count,
|
|
149
|
+
)
|
|
128
150
|
return check_results
|
|
129
151
|
|
|
130
152
|
async def _check_proxy_socks(
|
|
@@ -135,9 +157,9 @@ class ProxiesChecker:
|
|
|
135
157
|
check_results: ProxyCheckResults = ProxyCheckResults(),
|
|
136
158
|
) -> bool:
|
|
137
159
|
url = self._random_proxy_check_url()
|
|
160
|
+
self._logger.debug("Checking SOCKS5 proxy %s via %s", proxy, url)
|
|
138
161
|
socks_connector = ProxyConnector.from_url(proxy.socks5) # type: ignore
|
|
139
162
|
session = aiohttp.ClientSession(connector=socks_connector) # type: ignore
|
|
140
|
-
logger.debug(f"Checking proxy {proxy} ..")
|
|
141
163
|
try:
|
|
142
164
|
resp = await asyncio.wait_for(
|
|
143
165
|
session.get(
|
|
@@ -150,13 +172,13 @@ class ProxiesChecker:
|
|
|
150
172
|
)
|
|
151
173
|
|
|
152
174
|
except asyncio.TimeoutError:
|
|
153
|
-
|
|
175
|
+
self._logger.debug("%s: SOCKS5 timeout", proxy)
|
|
154
176
|
check_results.add_timeout(proxy)
|
|
155
177
|
await session.close()
|
|
156
178
|
return False
|
|
157
179
|
|
|
158
180
|
except Exception as e:
|
|
159
|
-
|
|
181
|
+
self._logger.debug("SOCKS5 check failed: %s (%s)", proxy, e, exc_info=True)
|
|
160
182
|
check_results.add_error(proxy)
|
|
161
183
|
await session.close()
|
|
162
184
|
return False
|
|
@@ -164,10 +186,10 @@ class ProxiesChecker:
|
|
|
164
186
|
await resp.read()
|
|
165
187
|
await session.close()
|
|
166
188
|
if resp.status == 200:
|
|
167
|
-
|
|
189
|
+
self._logger.debug("%s: SOCKS5 working (status=200)", proxy)
|
|
168
190
|
check_results.add_working(proxy)
|
|
169
191
|
else:
|
|
170
|
-
|
|
192
|
+
self._logger.debug("%s: SOCKS5 bad status=%s", proxy, resp.status)
|
|
171
193
|
check_results.add_bad(proxy)
|
|
172
194
|
|
|
173
195
|
return True
|
|
@@ -183,6 +205,9 @@ class ProxiesChecker:
|
|
|
183
205
|
proxies_list = (
|
|
184
206
|
proxies.proxies if isinstance(proxies, ProxiesReader) else proxies
|
|
185
207
|
)
|
|
208
|
+
self._logger.debug(
|
|
209
|
+
"check_multiple_proxies_socks5: scheduling %d checks", len(proxies_list)
|
|
210
|
+
)
|
|
186
211
|
for proxy in proxies_list:
|
|
187
212
|
tasks.append(
|
|
188
213
|
asyncio.create_task(
|
|
@@ -195,4 +220,6 @@ class ProxiesChecker:
|
|
|
195
220
|
)
|
|
196
221
|
await asyncio.gather(*tasks)
|
|
197
222
|
self._proxies_checked = True
|
|
198
|
-
|
|
223
|
+
self._logger.debug(
|
|
224
|
+
"check_multiple_proxies_socks5: finished %d tasks", len(tasks)
|
|
225
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "proxy-reader"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.2"
|
|
4
4
|
description = "Proxy reader for Python"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -30,7 +30,7 @@ github = "https://github.com/runetech0/proxy-reader"
|
|
|
30
30
|
|
|
31
31
|
[tool.bumpver]
|
|
32
32
|
|
|
33
|
-
current_version = "3.0.
|
|
33
|
+
current_version = "3.0.2"
|
|
34
34
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
35
35
|
commit_message = "bump version {old_version} -> {new_version}"
|
|
36
36
|
tag_message = "{new_version}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|