swiftshadow 2.2.1__py3-none-any.whl → 2.3.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.
swiftshadow/__init__.py CHANGED
@@ -19,7 +19,7 @@ def QuickProxy(
19
19
  Returns:
20
20
  proxyObject (Proxy): A working proxy object if found or else None.
21
21
  """
22
- for provider in Providers:
22
+ for provider in Providers.values():
23
23
  if protocol not in provider.protocols:
24
24
  continue
25
25
  if (len(countries) != 0) and (not provider.countryFilter):
swiftshadow/classes.py CHANGED
@@ -5,16 +5,17 @@ from pathlib import Path
5
5
  from pickle import dump, dumps, load, loads
6
6
  from random import choice
7
7
  from sys import stdout
8
- from typing import Literal
8
+ from typing import Literal, Any, Callable, Coroutine
9
9
 
10
10
  import aiofiles
11
11
  from appdirs import user_cache_dir
12
12
 
13
13
  from swiftshadow.cache import checkExpiry, getExpiry
14
14
  from swiftshadow.exceptions import UnsupportedProxyProtocol
15
- from swiftshadow.models import CacheData
15
+ from swiftshadow.helpers import deduplicateProxies
16
+ from swiftshadow.models import CacheData, Provider
16
17
  from swiftshadow.models import Proxy as Proxy
17
- from swiftshadow.providers import Providers
18
+ from swiftshadow.providers import Providers as ProvidersMap
18
19
 
19
20
  logger = getLogger("swiftshadow")
20
21
  logger.setLevel(INFO)
@@ -34,6 +35,7 @@ class ProxyInterface:
34
35
  Attributes:
35
36
  countries (list[str]): List of ISO country codes to filter proxies by (e.g., ["US", "CA"]).
36
37
  protocol (Literal['https', 'http']): Proxy protocol to use. Defaults to 'http'.
38
+ selectedProviders (Callable[[list[str], Literal["http", "https"]], Coroutine[Any, Any, list[Proxy]]]]): Selected list of providers to fetch proxies from. Defaults to empty meaning all available Providers.
37
39
  maxproxies (int): Maximum number of proxies to collect from providers. Defaults to 10.
38
40
  autorotate (bool): Whether to automatically rotate proxy on each get() call. Defaults to False.
39
41
  autoUpdate (bool): Whether to automatically update proxies upon class initalisation. Defaults to True.
@@ -62,6 +64,11 @@ class ProxyInterface:
62
64
  self,
63
65
  countries: list[str] = [],
64
66
  protocol: Literal["https", "http"] = "http",
67
+ selectedProviders: list[
68
+ Callable[
69
+ [list[str], Literal["http", "https"]], Coroutine[Any, Any, list[Proxy]]
70
+ ]
71
+ ] = [],
65
72
  maxProxies: int = 10,
66
73
  autoRotate: bool = False,
67
74
  autoUpdate: bool = True,
@@ -75,6 +82,7 @@ class ProxyInterface:
75
82
  Args:
76
83
  countries: List of ISO country codes to filter proxies. Empty list = no filtering.
77
84
  protocol: Proxy protocol to retrieve. Choose between 'http' or 'https'.
85
+ selectedProviders (list[Providers]): Selected list of providers to fetch proxies from. Defaults to empty meaning all available Providers.
78
86
  maxProxies: Maximum proxies to collect from all providers combined.
79
87
  autoRotate: Enable automatic proxy rotation on every get() call.
80
88
  autoUpdate (bool): Whether to automatically update proxies upon class initalisation.
@@ -93,6 +101,18 @@ class ProxyInterface:
93
101
  } is not supported by swiftshadow, please choose between HTTP or HTTPS"
94
102
  )
95
103
  self.protocol: Literal["https", "http"] = protocol
104
+ if selectedProviders != []:
105
+ providers: list[Provider] = []
106
+ for i in selectedProviders:
107
+ try:
108
+ providers.append(ProvidersMap[i])
109
+ except KeyError:
110
+ raise ValueError(
111
+ f"Unkown provider {i.__name__} in the list of Selected Providers."
112
+ )
113
+ self.providers: list[Provider] = providers
114
+ else:
115
+ self.providers: list[Provider] = list(ProvidersMap.values())
96
116
 
97
117
  self.maxproxies: int = maxProxies
98
118
  self.autorotate: bool = autoRotate
@@ -161,7 +181,7 @@ class ProxyInterface:
161
181
 
162
182
  self.proxies = []
163
183
 
164
- for provider in Providers:
184
+ for provider in self.providers:
165
185
  if self.protocol not in provider.protocols:
166
186
  continue
167
187
  if (len(self.countries) != 0) and (not provider.countryFilter):
@@ -184,6 +204,7 @@ class ProxyInterface:
184
204
  raise ValueError("No proxies were found for the current filter settings. Tip: https proxies can be rare; recommend setting protocol to http")
185
205
  raise ValueError("No proxies were found for the current filter settings.")
186
206
 
207
+ self.proxies = deduplicateProxies(self.proxies)
187
208
  async with aiofiles.open(
188
209
  self.cacheFolderPath.joinpath("swiftshadow.pickle"), "wb+"
189
210
  ) as cacheFile:
@@ -232,7 +253,7 @@ class ProxyInterface:
232
253
 
233
254
  self.proxies = []
234
255
 
235
- for provider in Providers:
256
+ for provider in self.providers:
236
257
  if self.protocol not in provider.protocols:
237
258
  continue
238
259
  if (len(self.countries) != 0) and (not provider.countryFilter):
@@ -253,6 +274,7 @@ class ProxyInterface:
253
274
  if len(self.proxies) == 0:
254
275
  raise ValueError("No proxies were found for the current filter settings.")
255
276
 
277
+ self.proxies = deduplicateProxies(self.proxies)
256
278
  with open(
257
279
  self.cacheFolderPath.joinpath("swiftshadow.pickle"), "wb+"
258
280
  ) as cacheFile:
swiftshadow/helpers.py CHANGED
@@ -46,3 +46,14 @@ async def GenericPlainTextProxyProvider(
46
46
  proxies: list[Proxy] = plaintextToProxies(raw, protocol=protocol)
47
47
  results = await validate_proxies(proxies)
48
48
  return results
49
+
50
+
51
+ def deduplicateProxies(proxies: list[Proxy]) -> list[Proxy]:
52
+ seen: list[str] = []
53
+ final: list[Proxy] = []
54
+ for proxy in proxies:
55
+ proxy_str: str = proxy.as_string()
56
+ if proxy_str not in seen:
57
+ final.append(proxy)
58
+ seen.append(proxy_str)
59
+ return final
swiftshadow/providers.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Literal
1
+ from typing import Any, Callable, Coroutine, Literal
2
2
  import aiohttp
3
3
 
4
4
  from requests import get
@@ -168,18 +168,37 @@ async def ProxyDB(
168
168
  return proxies
169
169
 
170
170
 
171
- Providers: list[Provider] = [
172
- Provider(providerFunction=ProxyScrape, countryFilter=True, protocols=["http"]),
173
- Provider(providerFunction=Monosans, countryFilter=True, protocols=["http"]),
174
- Provider(providerFunction=MuRongPIG, countryFilter=False, protocols=["http"]),
175
- Provider(providerFunction=Thespeedx, countryFilter=False, protocols=["http"]),
176
- Provider(
171
+ Providers: dict[
172
+ Callable[[list[str], Literal["http", "https"]], Coroutine[Any, Any, list[Proxy]]],
173
+ Provider,
174
+ ] = {
175
+ ProxyScrape: Provider(
176
+ providerFunction=ProxyScrape, countryFilter=True, protocols=["http"]
177
+ ),
178
+ Monosans: Provider(
179
+ providerFunction=Monosans, countryFilter=True, protocols=["http"]
180
+ ),
181
+ MuRongPIG: Provider(
182
+ providerFunction=MuRongPIG, countryFilter=False, protocols=["http"]
183
+ ),
184
+ Thespeedx: Provider(
185
+ providerFunction=Thespeedx, countryFilter=False, protocols=["http"]
186
+ ),
187
+ Anonym0usWork1221: Provider(
177
188
  providerFunction=Anonym0usWork1221,
178
189
  countryFilter=False,
179
190
  protocols=["http", "https"],
180
191
  ),
181
- Provider(providerFunction=Mmpx12, countryFilter=False, protocols=["http", "https"]),
182
- Provider(providerFunction=GoodProxy, countryFilter=False, protocols=["http"]),
183
- Provider(providerFunction=OpenProxyList, countryFilter=False, protocols=["http"]),
184
- Provider(providerFunction=ProxyDB, countryFilter=True, protocols=["http", "https"]),
185
- ]
192
+ Mmpx12: Provider(
193
+ providerFunction=Mmpx12, countryFilter=False, protocols=["http", "https"]
194
+ ),
195
+ GoodProxy: Provider(
196
+ providerFunction=GoodProxy, countryFilter=False, protocols=["http"]
197
+ ),
198
+ OpenProxyList: Provider(
199
+ providerFunction=OpenProxyList, countryFilter=False, protocols=["http"]
200
+ ),
201
+ ProxyDB: Provider(
202
+ providerFunction=ProxyDB, countryFilter=True, protocols=["http", "https"]
203
+ ),
204
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swiftshadow
3
- Version: 2.2.1
3
+ Version: 2.3.0
4
4
  Summary: Free IP Proxy rotator for python
5
5
  Author-email: sachin-sankar <mail.sachinsankar@gmail.com>
6
6
  License-File: LICENSE
@@ -0,0 +1,14 @@
1
+ swiftshadow/__init__.py,sha256=TYzucigrVBJo8derXriXLDnmLpDyyZdyi_7AinO0PqY,931
2
+ swiftshadow/cache.py,sha256=Mg8xsD6K3K012sILBwD2EZH6CE5kWCQNKCfZ5yadalI,800
3
+ swiftshadow/classes.py,sha256=PpAgvaZSWiS7AQVROBPynukgph7EyntRGlGbA5UzT5s,13561
4
+ swiftshadow/exceptions.py,sha256=qu4eXyrkWD9qd4HCIR-8vRfVcqLlTupo4sD72alCdug,129
5
+ swiftshadow/helpers.py,sha256=Yh5sASdlcTueRsGGrv9uIeAZtmLk_BviYzD2In3FzDQ,1597
6
+ swiftshadow/models.py,sha256=rHOuOFc6UYCI8L2pwxAbvS3Fj0Ag89cHod0rt7kQ2Vc,1790
7
+ swiftshadow/providers.py,sha256=ldEdDcGH19ayNtnofy66J81aiPgnq5h9ZRa3FeA1BZ0,6885
8
+ swiftshadow/types.py,sha256=Alyw3n54OESX1vSR-0kTvpYTlJ8LKfy5J9WZbtglHpE,894
9
+ swiftshadow/validator.py,sha256=3qE-99uljtbin1125uOgqAjnLRjuIgNYO5iiUAmaBC8,3102
10
+ swiftshadow-2.3.0.dist-info/METADATA,sha256=_eNIJV9eHNncPgfAQhxj8ajpLBEvZ00uqXZtkj6ww50,3320
11
+ swiftshadow-2.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ swiftshadow-2.3.0.dist-info/entry_points.txt,sha256=yMj0uEagcmXK2dmMmNXWebTpTT9j5K03oaRrd2wkyLA,49
13
+ swiftshadow-2.3.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
+ swiftshadow-2.3.0.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- swiftshadow/__init__.py,sha256=oxJDmG0YO0XyYGQpa9V_o38lZnoie7U_d4Ik_h46UXs,922
2
- swiftshadow/cache.py,sha256=Mg8xsD6K3K012sILBwD2EZH6CE5kWCQNKCfZ5yadalI,800
3
- swiftshadow/classes.py,sha256=hXAyvRuGXDvj_TsZxJ-bapK0pL82lhZUBGQZbQiGWN0,12280
4
- swiftshadow/exceptions.py,sha256=qu4eXyrkWD9qd4HCIR-8vRfVcqLlTupo4sD72alCdug,129
5
- swiftshadow/helpers.py,sha256=b8my66sBw_lTVLaKu4SaGjYQqEfIaStsuZlmK9Pmy5Y,1294
6
- swiftshadow/models.py,sha256=rHOuOFc6UYCI8L2pwxAbvS3Fj0Ag89cHod0rt7kQ2Vc,1790
7
- swiftshadow/providers.py,sha256=6H-PoXTCQUB7Vop0Wu7DBfMhwiYCvXCF1u_iCM7NcU4,6546
8
- swiftshadow/types.py,sha256=Alyw3n54OESX1vSR-0kTvpYTlJ8LKfy5J9WZbtglHpE,894
9
- swiftshadow/validator.py,sha256=3qE-99uljtbin1125uOgqAjnLRjuIgNYO5iiUAmaBC8,3102
10
- swiftshadow-2.2.1.dist-info/METADATA,sha256=4w-4O9PpR8nCpMVihakZrUNBIKH6QhCNq6OggQOpcVk,3320
11
- swiftshadow-2.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- swiftshadow-2.2.1.dist-info/entry_points.txt,sha256=yMj0uEagcmXK2dmMmNXWebTpTT9j5K03oaRrd2wkyLA,49
13
- swiftshadow-2.2.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
- swiftshadow-2.2.1.dist-info/RECORD,,