proxyproviders 0.2.0__tar.gz → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxyproviders
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: A unified interface for different proxy providers
5
5
  License: MIT License
6
6
 
@@ -85,6 +85,8 @@ python -m pip install proxyproviders
85
85
 
86
86
  Here's a quick bit of code to get you started! There's also a few [examples in the folder](https://github.com/davidteather/proxyproviders/tree/main/examples).
87
87
 
88
+ **📺 Video Tutorial:** [Watch the quick start guide on YouTube](https://youtu.be/h-JouO_orYo) for a walkthrough of getting started with ProxyProviders.
89
+
88
90
  **Note:** If you want to learn how to web scrape websites check my [free and open-source course for learning everything web scraping](https://github.com/davidteather/everything-web-scraping)
89
91
 
90
92
  ### Choose a Proxy Provider
@@ -41,6 +41,8 @@ python -m pip install proxyproviders
41
41
 
42
42
  Here's a quick bit of code to get you started! There's also a few [examples in the folder](https://github.com/davidteather/proxyproviders/tree/main/examples).
43
43
 
44
+ **📺 Video Tutorial:** [Watch the quick start guide on YouTube](https://youtu.be/h-JouO_orYo) for a walkthrough of getting started with ProxyProviders.
45
+
44
46
  **Note:** If you want to learn how to web scrape websites check my [free and open-source course for learning everything web scraping](https://github.com/davidteather/everything-web-scraping)
45
47
 
46
48
  ### Choose a Proxy Provider
@@ -1,13 +1,15 @@
1
1
  from . import algorithms
2
- from .models.proxy import Proxy
2
+ from .models.proxy import Proxy, ProxyFormat
3
3
  from .providers.brightdata import BrightData
4
4
  from .providers.webshare import Webshare
5
5
  from .proxy_provider import ProxyConfig, ProxyProvider
6
+ from .version import __version__
6
7
 
7
8
  __all__ = [
8
9
  "ProxyProvider",
9
10
  "ProxyConfig",
10
11
  "Proxy",
12
+ "ProxyFormat",
11
13
  "Webshare",
12
14
  "BrightData",
13
15
  "algorithms",
@@ -19,6 +19,9 @@ class ProxyFormat(Enum):
19
19
  AIOHTTP = "aiohttp"
20
20
  """AIOHTTP format, for use in aiohttp library HTTP calls"""
21
21
 
22
+ PLAYWRIGHT = "playwright"
23
+ """Playwright format, for use in Playwright browser automation"""
24
+
22
25
  URL = "url"
23
26
  """URL format, for use in URL strings"""
24
27
 
@@ -90,29 +93,57 @@ class Proxy:
90
93
  >>> proxy.format(ProxyFormat.HTTPX)
91
94
  {'http://': 'http://user:pass@192.168.1.1:8080', 'https://': 'http://user:pass@192.168.1.1:8080'}
92
95
  """
96
+ # Convert to ProxyFormat enum, handling both string and enum inputs
93
97
  if isinstance(format_type, str):
94
- format_type = ProxyFormat(format_type)
95
-
96
- if format_type == ProxyFormat.URL:
97
- protocol = kwargs.get("protocol", "http")
98
- return self.to_url(protocol)
99
-
100
- elif format_type == ProxyFormat.REQUESTS:
101
- protocols = kwargs.get("protocols", self.protocols or ["http", "https"])
102
- proxy_url = self.to_url("http")
103
- return {protocol: proxy_url for protocol in protocols}
104
-
105
- elif format_type == ProxyFormat.CURL:
106
- return ["-x", self.to_url("http")]
107
-
108
- elif format_type == ProxyFormat.HTTPX:
109
- # httpx uses 'http://' and 'https://' as keys
110
- proxy_url = self.to_url("http")
111
- return {"http://": proxy_url, "https://": proxy_url}
112
-
113
- elif format_type == ProxyFormat.AIOHTTP:
114
- # aiohttp takes a single URL string
115
- return self.to_url("http")
116
-
117
- else:
118
- raise ValueError(f"Unsupported format: {format_type}")
98
+ try:
99
+ format_type = ProxyFormat(format_type)
100
+ except ValueError:
101
+ raise ValueError(
102
+ f"Invalid format type: '{format_type}'. Valid options are: {[f.value for f in ProxyFormat]}"
103
+ )
104
+ elif not isinstance(format_type, ProxyFormat):
105
+ raise ValueError( # pyright: ignore[reportUnreachable] this is actually reachable
106
+ f"Invalid format type: {type(format_type).__name__}. Expected ProxyFormat enum or string."
107
+ )
108
+
109
+ format_handlers = {
110
+ ProxyFormat.URL: lambda: self.to_url(kwargs.get("protocol", "http")),
111
+ ProxyFormat.REQUESTS: lambda: self._format_requests(kwargs),
112
+ ProxyFormat.CURL: lambda: ["-x", self.to_url("http")],
113
+ ProxyFormat.HTTPX: lambda: self._format_httpx(),
114
+ ProxyFormat.AIOHTTP: lambda: self.to_url("http"),
115
+ ProxyFormat.PLAYWRIGHT: lambda: self._format_playwright(**kwargs),
116
+ }
117
+
118
+ handler = format_handlers[format_type]
119
+ return handler()
120
+
121
+ def _format_requests(self, kwargs):
122
+ """Format proxy for requests library."""
123
+ protocols = kwargs.get("protocols", self.protocols or ["http", "https"])
124
+ proxy_url = self.to_url("http")
125
+ return {protocol: proxy_url for protocol in protocols}
126
+
127
+ def _format_httpx(self):
128
+ """Format proxy for httpx library."""
129
+ proxy_url = self.to_url("http")
130
+ return {"http://": proxy_url, "https://": proxy_url}
131
+
132
+ def _format_playwright(self, **kwargs):
133
+ """Format proxy for Playwright."""
134
+ # Playwright expects server with protocol (e.g., 'http://ip:port', 'socks5://ip:port')
135
+ # Allow protocol selection via kwargs, default to http
136
+ protocol = kwargs.get("protocol", "http")
137
+
138
+ # Validate protocol is supported by the proxy
139
+ if self.protocols and protocol not in self.protocols:
140
+ # If proxy has specific protocols, use the first available one
141
+ protocol = self.protocols[0]
142
+
143
+ playwright_proxy = {"server": f"{protocol}://{self.proxy_address}:{self.port}"}
144
+
145
+ if self.username and self.password:
146
+ playwright_proxy["username"] = self.username
147
+ playwright_proxy["password"] = self.password
148
+
149
+ return playwright_proxy
@@ -92,7 +92,7 @@ class Webshare(ProxyProvider):
92
92
 
93
93
  all_proxies.extend([self._convert_to_proxy(proxy) for proxy in proxy_data])
94
94
 
95
- if data.get("next") is None: # no more pages
95
+ if "page" in self.search_params or data.get("next") is None:
96
96
  break
97
97
 
98
98
  return all_proxies
@@ -0,0 +1,3 @@
1
+ """Version information for proxyproviders package."""
2
+
3
+ __version__ = "0.2.2"
@@ -2,9 +2,18 @@
2
2
  requires = ["poetry-core>=1.0.0"]
3
3
  build-backend = "poetry.core.masonry.api"
4
4
 
5
+ [tool.poetry]
6
+ name = "proxyproviders"
7
+ version = "0.2.2"
8
+ description = "A unified interface for different proxy providers"
9
+ authors = ["David Teather <contact.davidteather@gmail.com>"]
10
+
11
+ [tool.poetry.dependencies]
12
+ python = ">=3.9"
13
+
5
14
  [project]
6
15
  name = "proxyproviders"
7
- version = "0.2.0"
16
+ version = "0.2.2"
8
17
  description = "A unified interface for different proxy providers"
9
18
  readme = "README.md"
10
19
  authors = [{ name = "David Teather", email = "contact.davidteather@gmail.com" }]
File without changes