Skip to content

Commit a733933

Browse files
authored
Add HF_DEBUG environment variable for debugging/reproducibility (#2819)
* Add HF_DEBUG environment variable for debugging/reproducibility * make quali
1 parent 63aada5 commit a733933

File tree

5 files changed

+63
-8
lines changed

5 files changed

+63
-8
lines changed

.github/ISSUE_TEMPLATE/bug-report.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ body:
2424
id: logs
2525
attributes:
2626
label: Logs
27-
description: "Please include the Python logs if you can."
27+
description: "Please include the Python logs if you can. If possible, run the code with `HF_DEBUG=1` as environment variable."
2828
render: shell
2929
- type: textarea
3030
id: system-info

docs/source/en/package_reference/environment_variables.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ The following environment variables expect a boolean value. The variable will be
8383
as `True` if its value is one of `{"1", "ON", "YES", "TRUE"}` (case-insensitive). Any other value
8484
(or undefined) will be considered as `False`.
8585

86+
### HF_DEBUG
87+
88+
If set, the log level for the `huggingface_hub` logger is set to DEBUG. Additionally, all requests made by HF libraries will be logged as equivalent cURL commands for easier debugging and reproducibility.
89+
8690
### HF_HUB_OFFLINE
8791

8892
If set, no HTTP calls will be made to the Hugging Face Hub. If you try to download files, only the cached files will be accessed. If no cache file is detected, an error is raised This is useful in case your network is slow and you don't care about having the latest version of a file.
@@ -159,11 +163,11 @@ Please note that using `hf_transfer` comes with certain limitations. Since it is
159163
In order to standardize all environment variables within the Hugging Face ecosystem, some variables have been marked as deprecated. Although they remain functional, they no longer take precedence over their replacements. The following table outlines the deprecated variables and their corresponding alternatives:
160164

161165

162-
| Deprecated Variable | Replacement |
163-
| --- | --- |
164-
| `HUGGINGFACE_HUB_CACHE` | `HF_HUB_CACHE` |
165-
| `HUGGINGFACE_ASSETS_CACHE` | `HF_ASSETS_CACHE` |
166-
| `HUGGING_FACE_HUB_TOKEN` | `HF_TOKEN` |
166+
| Deprecated Variable | Replacement |
167+
| --------------------------- | ------------------ |
168+
| `HUGGINGFACE_HUB_CACHE` | `HF_HUB_CACHE` |
169+
| `HUGGINGFACE_ASSETS_CACHE` | `HF_ASSETS_CACHE` |
170+
| `HUGGING_FACE_HUB_TOKEN` | `HF_TOKEN` |
167171
| `HUGGINGFACE_HUB_VERBOSITY` | `HF_HUB_VERBOSITY` |
168172

169173
## From external tools

src/huggingface_hub/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ def _as_int(value: Optional[str]) -> Optional[int]:
132132

133133
HF_HUB_OFFLINE = _is_true(os.environ.get("HF_HUB_OFFLINE") or os.environ.get("TRANSFORMERS_OFFLINE"))
134134

135+
# If set, log level will be set to DEBUG and all requests made to the Hub will be logged
136+
# as curl commands for reproducibility.
137+
HF_DEBUG = _is_true(os.environ.get("HF_DEBUG"))
138+
135139
# Opt-out from telemetry requests
136140
HF_HUB_DISABLE_TELEMETRY = (
137141
_is_true(os.environ.get("HF_HUB_DISABLE_TELEMETRY")) # HF-specific env variable

src/huggingface_hub/utils/_http.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
import uuid
2323
from functools import lru_cache
2424
from http import HTTPStatus
25-
from typing import Callable, Optional, Tuple, Type, Union
25+
from shlex import quote
26+
from typing import Any, Callable, List, Optional, Tuple, Type, Union
2627

2728
import requests
2829
from requests import HTTPError, Response
@@ -82,13 +83,15 @@ def add_headers(self, request, **kwargs):
8283
request.headers[X_AMZN_TRACE_ID] = request.headers.get(X_REQUEST_ID) or str(uuid.uuid4())
8384

8485
# Add debug log
85-
has_token = str(request.headers.get("authorization", "")).startswith("Bearer hf_")
86+
has_token = len(str(request.headers.get("authorization", ""))) > 0
8687
logger.debug(
8788
f"Request {request.headers[X_AMZN_TRACE_ID]}: {request.method} {request.url} (authenticated: {has_token})"
8889
)
8990

9091
def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
9192
"""Catch any RequestException to append request id to the error message for debugging."""
93+
if constants.HF_DEBUG:
94+
logger.debug(f"Send: {_curlify(request)}")
9295
try:
9396
return super().send(request, *args, **kwargs)
9497
except requests.RequestException as e:
@@ -549,3 +552,41 @@ def _format(error_type: Type[HfHubHTTPError], custom_message: str, response: Res
549552

550553
# Return
551554
return error_type(final_error_message.strip(), response=response, server_message=server_message or None)
555+
556+
557+
def _curlify(request: requests.PreparedRequest) -> str:
558+
"""Convert a `requests.PreparedRequest` into a curl command (str).
559+
560+
Used for debug purposes only.
561+
562+
Implementation vendored from https://github.com/ofw/curlify/blob/master/curlify.py.
563+
MIT License Copyright (c) 2016 Egor.
564+
"""
565+
parts: List[Tuple[Any, Any]] = [
566+
("curl", None),
567+
("-X", request.method),
568+
]
569+
570+
for k, v in sorted(request.headers.items()):
571+
if k.lower() == "authorization":
572+
v = "<TOKEN>" # Hide authorization header, no matter its value (can be Bearer, Key, etc.)
573+
parts += [("-H", "{0}: {1}".format(k, v))]
574+
575+
if request.body:
576+
body = request.body
577+
if isinstance(body, bytes):
578+
body = body.decode("utf-8")
579+
if len(body) > 1000:
580+
body = body[:1000] + " ... [truncated]"
581+
parts += [("-d", body)]
582+
583+
parts += [(None, request.url)]
584+
585+
flat_parts = []
586+
for k, v in parts:
587+
if k:
588+
flat_parts.append(quote(k))
589+
if v:
590+
flat_parts.append(quote(v))
591+
592+
return " ".join(flat_parts)

src/huggingface_hub/utils/logging.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
)
2929
from typing import Optional
3030

31+
from .. import constants
32+
3133

3234
log_levels = {
3335
"debug": logging.DEBUG,
@@ -180,3 +182,7 @@ def enable_propagation() -> None:
180182

181183

182184
_configure_library_root_logger()
185+
186+
if constants.HF_DEBUG:
187+
# If `HF_DEBUG` environment variable is set, set the verbosity of `huggingface_hub` logger to `DEBUG`.
188+
set_verbosity_debug()

0 commit comments

Comments
 (0)