diff --git a/README.md b/README.md index 12c9da7..851bb48 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,17 @@ you want; importing the package never fails because an extra is missing. `requirements.txt` (pick the extra you need): ``` -aioweb_tls[curl] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.7 -aioweb_tls[noble] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.7 -aioweb_tls[all] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.7 +aioweb_tls[curl] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.8 +aioweb_tls[noble] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.8 +aioweb_tls[all] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.8 ``` Direct: ```bash -pip install "aioweb_tls[curl] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.7" -pip install "aioweb_tls[noble] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.7" -pip install "aioweb_tls[all] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.7" +pip install "aioweb_tls[curl] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.8" +pip install "aioweb_tls[noble] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.8" +pip install "aioweb_tls[all] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioweb_tls.git@v0.1.8" ``` - `[curl]` → curl_cffi backend · `[noble]` → noble_tls backend · `[all]` → both. @@ -44,7 +44,7 @@ pip install "aioweb_tls[all] @ git+ssh://git@git.rethinkstudios.io/rethink-publi Constructing a backend whose client isn't installed raises that `RuntimeError` at construction, never at import. -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. ## curl_cffi backend @@ -213,6 +213,12 @@ are separate signals. Use this as one component, not a complete anti-bot solutio ## Changelog +### v0.1.8 + +- Compressed 4 residual internal-helper docstrings (`_is_timeout_error`, + `_noble_timeout_seconds`, `_noble_content`, `_jar_to_dict`) to one-liners. + Cosmetic, zero behavior change. + ### v0.1.7 - **Both backends now thread redirect history.** `CurlCffi.raw_request` and diff --git a/pyproject.toml b/pyproject.toml index 4523def..158cbfa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "aioweb_tls" -version = "0.1.7" +version = "0.1.8" description = "TLS-fingerprinting backends (curl_cffi / noble_tls) for aioweb via one injectable TLSSession, config-free, installable." requires-python = ">=3.10" dependencies = [ diff --git a/src/aioweb_tls/backends.py b/src/aioweb_tls/backends.py index 6ceeb28..d87e036 100644 --- a/src/aioweb_tls/backends.py +++ b/src/aioweb_tls/backends.py @@ -23,8 +23,7 @@ _TIMEOUT_TEXT = ("timeout", "timed out", "deadline exceeded") def _is_timeout_error(error: Exception) -> bool: - """whether a backend-native OSError is a timeout: curl_cffi's Timeout type by name, - else fall back to matching noble_tls's Go error text (e.g. "context deadline exceeded")""" + """whether a backend-native OSError is a timeout, by type name (curl_cffi) or Go error text (noble_tls)""" timeout_type = getattr(error, "__class__", None) if timeout_type is not None and any(base.__name__ == "Timeout" for base in timeout_type.__mro__): return True @@ -60,13 +59,8 @@ def _coerce_timeout(value): def _noble_timeout_seconds(value): - """coerce a raw or wrapped timeout into whole seconds for noble's Go int field - - noble's Go timeoutSeconds field is an int: a sub-second float truncates to 0 - (= no timeout) and a non-integer fails Go-side JSON unmarshal outright, so this - rounds up (min 1s). shared by both Noble timeout paths (session-default, per-call). - None if uncoercible. - """ + """coerce a raw or wrapped timeout into whole seconds (min 1), rounding up so noble's Go int + field never truncates to 0/fails unmarshal; None if uncoercible; shared by both Noble timeout paths""" timeout = _coerce_timeout(value) if timeout is None: return None @@ -74,14 +68,8 @@ def _noble_timeout_seconds(value): def _noble_content(response) -> bytes: - """extract true response bytes from a noble_tls response fetched with is_byte_response - - with is_byte_response=True, the Go side returns the body as a - `data:;base64,` URI string in response.text (the whole Go response - is UTF-8-decoded before JSON parsing, so raw bytes travel as base64); decode that - here instead of response.content, which just re-encodes the string. falls back to - a plain utf-8 encode if the body isn't a data-URI. - """ + """extract true response bytes from a noble_tls response fetched with is_byte_response, decoding + the base64 data-URI in response.text (falls back to a plain utf-8 encode if not a data-URI)""" text = getattr(response, "text", "") or "" if text.startswith("data:") and ";base64," in text: _, _, payload = text.partition(";base64,") @@ -122,10 +110,8 @@ def _history_entries(history) -> list: def _jar_to_dict(session): - """best-effort map of a requests-style cookie jar on session to a plain dict - - feeds preview() only; a jar that fails to iterate degrades to {} rather than raising. - """ + """best-effort map of a requests-style cookie jar on session to a plain dict, feeding preview() + only; a jar that fails to iterate degrades to {} rather than raising""" jar = getattr(session, "cookies", None) if not jar: return {}