| 199 | |
| 200 | |
| 201 | class Proxy: |
| 202 | def __init__( |
| 203 | self, |
| 204 | url: URL | str, |
| 205 | *, |
| 206 | ssl_context: ssl.SSLContext | None = None, |
| 207 | auth: tuple[str, str] | None = None, |
| 208 | headers: HeaderTypes | None = None, |
| 209 | ) -> None: |
| 210 | url = URL(url) |
| 211 | headers = Headers(headers) |
| 212 | |
| 213 | if url.scheme not in ("http", "https", "socks5", "socks5h"): |
| 214 | raise ValueError(f"Unknown scheme for proxy URL {url!r}") |
| 215 | |
| 216 | if url.username or url.password: |
| 217 | # Remove any auth credentials from the URL. |
| 218 | auth = (url.username, url.password) |
| 219 | url = url.copy_with(username=None, password=None) |
| 220 | |
| 221 | self.url = url |
| 222 | self.auth = auth |
| 223 | self.headers = headers |
| 224 | self.ssl_context = ssl_context |
| 225 | |
| 226 | @property |
| 227 | def raw_auth(self) -> tuple[bytes, bytes] | None: |
| 228 | # The proxy authentication as raw bytes. |
| 229 | return ( |
| 230 | None |
| 231 | if self.auth is None |
| 232 | else (self.auth[0].encode("utf-8"), self.auth[1].encode("utf-8")) |
| 233 | ) |
| 234 | |
| 235 | def __repr__(self) -> str: |
| 236 | # The authentication is represented with the password component masked. |
| 237 | auth = (self.auth[0], "********") if self.auth else None |
| 238 | |
| 239 | # Build a nice concise representation. |
| 240 | url_str = f"{str(self.url)!r}" |
| 241 | auth_str = f", auth={auth!r}" if auth else "" |
| 242 | headers_str = f", headers={dict(self.headers)!r}" if self.headers else "" |
| 243 | return f"Proxy({url_str}{auth_str}{headers_str})" |
| 244 | |
| 245 | |
| 246 | DEFAULT_TIMEOUT_CONFIG = Timeout(timeout=5.0) |
no outgoing calls
no test coverage detected