File size: 2,601 Bytes
8356dae d313d81 8356dae | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | """
_httpx_compat.py
----------------
Monkey-patch httpx ≥0.28 to keep accepting the legacy `allow_redirects`
kwarg that transformers ≤4.50 still passes to `Client.head()` when probing
the Hub for model files. httpx 0.28 fully removed `allow_redirects`
(renamed to `follow_redirects` back in 0.21) which throws:
TypeError: Client.head() got an unexpected keyword argument 'allow_redirects'
Versioning around this has been brittle on Colab — `firebase-admin` and
`google-genai` (preinstalled there) hard-pin `httpx==0.28.1`, so downgrade
attempts keep getting clobbered by the resolver. Patching at import time
sidesteps the whole version war.
Imported eagerly by `training/train.py` via `utils/_quiet` so the patch is
live before `transformers` is imported. Also called inline by the Colab
notebook (cell-pip) so the patch covers the in-notebook smoke test.
Idempotent: calling apply() twice is a no-op. Safe on httpx <0.28 too —
just returns False without patching.
"""
def apply() -> bool:
"""Install the kwarg-shim. Returns True iff a patch was applied."""
try:
import httpx
except ImportError:
return False
try:
ver = tuple(int(x) for x in httpx.__version__.split(".")[:2])
except Exception:
return False
if ver < (0, 28):
return False
if getattr(httpx.Client, "_cxr_vlm_compat_patched", False):
return True
def _make_compat(orig):
def patched(self, *args, **kwargs):
if "allow_redirects" in kwargs:
# follow_redirects is the modern equivalent. If both are
# somehow set, allow_redirects wins (matches old behaviour).
kwargs["follow_redirects"] = kwargs.pop("allow_redirects")
# httpx 0.28 also removed per-request `proxies=`. Some
# transformers / huggingface_hub paths still pass it (e.g.
# transformers.utils.hub.has_file → Client.head(proxies=...)),
# raising TypeError. Drop it silently — httpx 0.28 picks up
# proxies from the Client/transport instead.
kwargs.pop("proxies", None)
return orig(self, *args, **kwargs)
return patched
for cls in (httpx.Client, httpx.AsyncClient):
for method in (
"request", "get", "head", "post", "put",
"patch", "delete", "options",
):
if hasattr(cls, method):
setattr(cls, method, _make_compat(getattr(cls, method)))
httpx.Client._cxr_vlm_compat_patched = True
return True
# Apply on import.
_PATCHED = apply()
|