diff --git a/README.md b/README.md index 1a372df..fc3492a 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,16 @@ send to the core — inheriting rotation, proxy, retry, and result for free. ## Install ``` -aiowebhooks @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.7 +aiowebhooks @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.8 # discord embeds / identity helpers need the extra: -aiowebhooks[discord] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.7 +aiowebhooks[discord] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.8 ``` The base pulls `aiohttp` and `commons` (for the retry/backoff engine). Only `aiowebhooks[discord]` adds `discord.py` (>=2.3, mainline, not discord.py-self), and only for `DiscordWebhook`. -Drop the `@v0.1.7` suffix from the line above to install the latest unpinned. +Drop the `@v0.1.8` suffix from the line above to install the latest unpinned. ## Core sender @@ -148,6 +148,11 @@ Without the extra installed, importing `aiowebhooks` still works; constructing o ## Changelog +### v0.1.8 + +- Compressed 5 residual internal/trivial docstrings (`MAX_RETRY_AFTER`, `_Retryable`, + `_proxy_string`, `_retry_after`, `_attempt`) to one or two lines; no behavior change. + ### v0.1.7 - Docstrings/comments compressed (module docstrings and internal-method prose); no diff --git a/pyproject.toml b/pyproject.toml index f74c5c4..5fe6965 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "aiowebhooks" -version = "0.1.7" +version = "0.1.8" description = "async webhook sender (aiohttp) with round-robin urls, retry, and proxy rotation; optional discord.py embeds" requires-python = ">=3.10" dependencies = [ diff --git a/src/aiowebhooks/__init__.py b/src/aiowebhooks/__init__.py index 90c7176..58a05ab 100644 --- a/src/aiowebhooks/__init__.py +++ b/src/aiowebhooks/__init__.py @@ -11,4 +11,4 @@ from .sender import Webhook __all__ = ["Webhook", "WebhookResult", "WebhookError", "NoUrlsError"] -__version__ = "0.1.7" +__version__ = "0.1.8" diff --git a/src/aiowebhooks/sender.py b/src/aiowebhooks/sender.py index 9ae71bb..30a5b18 100644 --- a/src/aiowebhooks/sender.py +++ b/src/aiowebhooks/sender.py @@ -21,16 +21,11 @@ from .result import WebhookResult log = logging.getLogger(__name__) MAX_RETRY_AFTER = 300.0 -"""ceiling (seconds) honored from a server-controlled 429 retry_after/Retry-After - -guards against an arbitrarily large or non-finite wait (inf/nan, or a ms-vs-s unit -mismatch) stalling a send() past its ClientTimeout. non-finite values are rejected -outright; finite values are clamped to this ceiling. -""" +"""ceiling (seconds) honored from a 429 retry_after/Retry-After; non-finite values (inf/nan) rejected outright""" class _Retryable(Exception): - """internal signal for commons.aretry: a retryable 429/5xx; carries the real response""" + """internal signal for commons.aretry on a retryable 429/5xx, carrying the real response""" def __init__(self, result: WebhookResult): super().__init__(f"retryable status {result.status}") @@ -38,11 +33,7 @@ class _Retryable(Exception): def _proxy_string(proxies_dict: Optional[Dict[str, str]]) -> Optional[str]: - """canonical host:port:user:pass (or host:port) from an aiohttp proxies dict - - duck-typed: reads whatever the provider's get() returned without importing it. - returns None if the dict is empty or unparseable. - """ + """canonical host:port:user:pass (or host:port) from an aiohttp proxies dict, or None if unparseable""" if not proxies_dict: return None url = proxies_dict.get("http") or proxies_dict.get("https") @@ -95,11 +86,7 @@ class Webhook: @staticmethod def _retry_after(status: int, headers, body) -> Optional[float]: - """seconds to wait on a 429, from body retry_after then Retry-After header - - non-finite values (inf/nan) are rejected as unparseable; finite values are - clamped to MAX_RETRY_AFTER. - """ + """seconds to wait on a 429 from body retry_after then Retry-After header, clamped to MAX_RETRY_AFTER""" if status != 429: return None if isinstance(body, dict) and body.get("retry_after") is not None: @@ -167,10 +154,8 @@ class Webhook: ) -> WebhookResult: """one logical send: proxy rotation + a single POST; may raise _Retryable - a 429 retry_after is carried to the START of the next attempt's sleep, never - slept after the attempt that raises. `counter`/`pending_wait` are per-call - mutable cells threaded from `_send_loop` (aretry calls this fresh each retry, - so a plain local wouldn't survive) - keeps state safe across concurrent sends. + `counter`/`pending_wait` are per-call mutable cells threaded from `_send_loop`, not + instance state - a plain local wouldn't survive aretry calling this fresh each retry. """ timeout = aiohttp.ClientTimeout(total=self.timeout) last_proxy: Optional[str] = None