diff --git a/README.md b/README.md index f2c60ea..2fc9162 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ edits. **Credentials are always injected — never hardcoded.** ## Install ``` -aioproxies @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.1 +aioproxies @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.2 # network helpers (current_ip / reset) need the extra: -aioproxies[net] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.1 +aioproxies[net] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.2 ``` The core has no dependencies. The `net` extra adds `aiohttp` for `current_ip` / diff --git a/pyproject.toml b/pyproject.toml index 2730db2..4bcaab2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "aioproxies" -version = "0.2.1" +version = "0.2.2" description = "proxy parsing, formatting, health, and pool management for aiohttp/aioweb, camoufox, and socks5" requires-python = ">=3.10" dependencies = [] diff --git a/src/aioproxies/__init__.py b/src/aioproxies/__init__.py index 8814edf..899b7ef 100644 --- a/src/aioproxies/__init__.py +++ b/src/aioproxies/__init__.py @@ -18,4 +18,4 @@ __all__ = [ "to_proxy", ] -__version__ = "0.2.1" +__version__ = "0.2.2" diff --git a/src/aioproxies/manager.py b/src/aioproxies/manager.py index 7629a11..7c5b012 100644 --- a/src/aioproxies/manager.py +++ b/src/aioproxies/manager.py @@ -58,6 +58,8 @@ class AioProxies: shuffle: bool = True, cooldown: int = 0, ): + if proxies is not None and len(proxies) == 0: + raise ValueError("proxies list is empty; provide at least one proxy") sources = [s for s in (template, proxies, static) if s] if len(sources) != 1: raise ValueError("provide exactly one of: template, proxies, static") @@ -129,6 +131,10 @@ class AioProxies: raise ValueError( f"template placeholder {exc} not provided; pass it to next(**fields)" ) from exc + except ValueError as exc: + # a malformed template (e.g. an unmatched '{') makes str.format raise a + # bare ValueError; re-raise naming the cause so it isn't cryptic + raise ValueError(f"malformed proxy template {self.template!r}: {exc}") from exc return parse(filled) return self._next_from_list() diff --git a/src/aioproxies/proxy.py b/src/aioproxies/proxy.py index d55a085..a9ffd13 100644 --- a/src/aioproxies/proxy.py +++ b/src/aioproxies/proxy.py @@ -133,8 +133,11 @@ def _proxy_from_dict(spec: Dict[str, str]) -> Proxy: """normalize an aiohttp / camoufox / socks5 dict into a Proxy""" if "server" in spec: proxy = _proxy_from_url(spec["server"]) - user = spec.get("username") - password = spec.get("password") + # prefer explicit dict auth; otherwise fall back to auth embedded in the server + # URL (http://user:pass@host:port) so it isn't silently dropped — which would + # key the proxy auth-less and collide with a genuinely auth-less one + user = spec.get("username") or proxy.user + password = spec.get("password") or proxy.password if user and password: return Proxy(proxy.host, proxy.port, user, password) return Proxy(proxy.host, proxy.port)