huggingface-hub 0.28.0rc5__py3-none-any.whl → 0.29.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of huggingface-hub might be problematic. Click here for more details.

Files changed (63) hide show
  1. huggingface_hub/__init__.py +1 -4
  2. huggingface_hub/constants.py +16 -11
  3. huggingface_hub/file_download.py +10 -6
  4. huggingface_hub/hf_api.py +53 -23
  5. huggingface_hub/inference/_client.py +151 -84
  6. huggingface_hub/inference/_common.py +3 -27
  7. huggingface_hub/inference/_generated/_async_client.py +147 -83
  8. huggingface_hub/inference/_generated/types/__init__.py +1 -1
  9. huggingface_hub/inference/_generated/types/audio_classification.py +4 -5
  10. huggingface_hub/inference/_generated/types/audio_to_audio.py +3 -4
  11. huggingface_hub/inference/_generated/types/automatic_speech_recognition.py +7 -8
  12. huggingface_hub/inference/_generated/types/base.py +21 -0
  13. huggingface_hub/inference/_generated/types/chat_completion.py +29 -30
  14. huggingface_hub/inference/_generated/types/depth_estimation.py +3 -4
  15. huggingface_hub/inference/_generated/types/document_question_answering.py +5 -6
  16. huggingface_hub/inference/_generated/types/feature_extraction.py +5 -6
  17. huggingface_hub/inference/_generated/types/fill_mask.py +4 -5
  18. huggingface_hub/inference/_generated/types/image_classification.py +4 -5
  19. huggingface_hub/inference/_generated/types/image_segmentation.py +4 -5
  20. huggingface_hub/inference/_generated/types/image_to_image.py +5 -6
  21. huggingface_hub/inference/_generated/types/image_to_text.py +5 -6
  22. huggingface_hub/inference/_generated/types/object_detection.py +5 -6
  23. huggingface_hub/inference/_generated/types/question_answering.py +5 -6
  24. huggingface_hub/inference/_generated/types/sentence_similarity.py +3 -4
  25. huggingface_hub/inference/_generated/types/summarization.py +4 -5
  26. huggingface_hub/inference/_generated/types/table_question_answering.py +5 -6
  27. huggingface_hub/inference/_generated/types/text2text_generation.py +4 -5
  28. huggingface_hub/inference/_generated/types/text_classification.py +4 -5
  29. huggingface_hub/inference/_generated/types/text_generation.py +12 -13
  30. huggingface_hub/inference/_generated/types/text_to_audio.py +5 -6
  31. huggingface_hub/inference/_generated/types/text_to_image.py +8 -15
  32. huggingface_hub/inference/_generated/types/text_to_speech.py +5 -6
  33. huggingface_hub/inference/_generated/types/text_to_video.py +4 -5
  34. huggingface_hub/inference/_generated/types/token_classification.py +4 -5
  35. huggingface_hub/inference/_generated/types/translation.py +4 -5
  36. huggingface_hub/inference/_generated/types/video_classification.py +4 -5
  37. huggingface_hub/inference/_generated/types/visual_question_answering.py +5 -6
  38. huggingface_hub/inference/_generated/types/zero_shot_classification.py +4 -5
  39. huggingface_hub/inference/_generated/types/zero_shot_image_classification.py +4 -5
  40. huggingface_hub/inference/_generated/types/zero_shot_object_detection.py +5 -6
  41. huggingface_hub/inference/_providers/__init__.py +44 -8
  42. huggingface_hub/inference/_providers/_common.py +239 -0
  43. huggingface_hub/inference/_providers/black_forest_labs.py +66 -0
  44. huggingface_hub/inference/_providers/fal_ai.py +31 -100
  45. huggingface_hub/inference/_providers/fireworks_ai.py +6 -0
  46. huggingface_hub/inference/_providers/hf_inference.py +58 -142
  47. huggingface_hub/inference/_providers/hyperbolic.py +43 -0
  48. huggingface_hub/inference/_providers/nebius.py +41 -0
  49. huggingface_hub/inference/_providers/novita.py +26 -0
  50. huggingface_hub/inference/_providers/replicate.py +24 -119
  51. huggingface_hub/inference/_providers/sambanova.py +3 -86
  52. huggingface_hub/inference/_providers/together.py +36 -130
  53. huggingface_hub/utils/_headers.py +5 -0
  54. huggingface_hub/utils/_hf_folder.py +4 -32
  55. huggingface_hub/utils/_http.py +85 -2
  56. huggingface_hub/utils/_typing.py +1 -1
  57. huggingface_hub/utils/logging.py +6 -0
  58. {huggingface_hub-0.28.0rc5.dist-info → huggingface_hub-0.29.0.dist-info}/METADATA +1 -1
  59. {huggingface_hub-0.28.0rc5.dist-info → huggingface_hub-0.29.0.dist-info}/RECORD +63 -57
  60. {huggingface_hub-0.28.0rc5.dist-info → huggingface_hub-0.29.0.dist-info}/LICENSE +0 -0
  61. {huggingface_hub-0.28.0rc5.dist-info → huggingface_hub-0.29.0.dist-info}/WHEEL +0 -0
  62. {huggingface_hub-0.28.0rc5.dist-info → huggingface_hub-0.29.0.dist-info}/entry_points.txt +0 -0
  63. {huggingface_hub-0.28.0rc5.dist-info → huggingface_hub-0.29.0.dist-info}/top_level.txt +0 -0
@@ -1,114 +1,32 @@
1
1
  from typing import Any, Dict, Optional, Union
2
2
 
3
- from huggingface_hub import constants
4
- from huggingface_hub.inference._common import RequestParameters, TaskProviderHelper, _as_dict
5
- from huggingface_hub.utils import build_hf_headers, get_session, get_token, logging
3
+ from huggingface_hub.inference._common import _as_dict
4
+ from huggingface_hub.inference._providers._common import TaskProviderHelper, filter_none
5
+ from huggingface_hub.utils import get_session
6
6
 
7
7
 
8
- logger = logging.get_logger(__name__)
9
-
10
-
11
- BASE_URL = "https://api.replicate.com"
12
-
13
- SUPPORTED_MODELS = {
14
- "text-to-image": {
15
- "black-forest-labs/FLUX.1-dev": "black-forest-labs/flux-dev",
16
- "black-forest-labs/FLUX.1-schnell": "black-forest-labs/flux-schnell",
17
- "ByteDance/Hyper-SD": "bytedance/hyper-flux-16step:382cf8959fb0f0d665b26e7e80b8d6dc3faaef1510f14ce017e8c732bb3d1eb7",
18
- "ByteDance/SDXL-Lightning": "bytedance/sdxl-lightning-4step:5599ed30703defd1d160a25a63321b4dec97101d98b4674bcc56e41f62f35637",
19
- "playgroundai/playground-v2.5-1024px-aesthetic": "playgroundai/playground-v2.5-1024px-aesthetic:a45f82a1382bed5c7aeb861dac7c7d191b0fdf74d8d57c4a0e6ed7d4d0bf7d24",
20
- "stabilityai/stable-diffusion-3.5-large-turbo": "stability-ai/stable-diffusion-3.5-large-turbo",
21
- "stabilityai/stable-diffusion-3.5-large": "stability-ai/stable-diffusion-3.5-large",
22
- "stabilityai/stable-diffusion-3.5-medium": "stability-ai/stable-diffusion-3.5-medium",
23
- "stabilityai/stable-diffusion-xl-base-1.0": "stability-ai/sdxl:7762fd07cf82c948538e41f63f77d685e02b063e37e496e96eefd46c929f9bdc",
24
- },
25
- "text-to-speech": {
26
- "OuteAI/OuteTTS-0.3-500M": "jbilcke/oute-tts:39a59319327b27327fa3095149c5a746e7f2aee18c75055c3368237a6503cd26",
27
- },
28
- "text-to-video": {
29
- "genmo/mochi-1-preview": "genmoai/mochi-1:1944af04d098ef69bed7f9d335d102e652203f268ec4aaa2d836f6217217e460",
30
- },
31
- }
32
-
33
-
34
- def _build_url(base_url: str, model: str) -> str:
35
- if ":" in model:
36
- return f"{base_url}/v1/predictions"
37
- return f"{base_url}/v1/models/{model}/predictions"
8
+ _PROVIDER = "replicate"
9
+ _BASE_URL = "https://api.replicate.com"
38
10
 
39
11
 
40
12
  class ReplicateTask(TaskProviderHelper):
41
13
  def __init__(self, task: str):
42
- self.task = task
43
-
44
- def prepare_request(
45
- self,
46
- *,
47
- inputs: Any,
48
- parameters: Dict[str, Any],
49
- headers: Dict,
50
- model: Optional[str],
51
- api_key: Optional[str],
52
- extra_payload: Optional[Dict[str, Any]] = None,
53
- ) -> RequestParameters:
54
- if api_key is None:
55
- api_key = get_token()
56
- if api_key is None:
57
- raise ValueError(
58
- "You must provide an api_key to work with Replicate API or log in with `huggingface-cli login`."
59
- )
60
-
61
- # Route to the proxy if the api_key is a HF TOKEN
62
- if api_key.startswith("hf_"):
63
- base_url = constants.INFERENCE_PROXY_TEMPLATE.format(provider="replicate")
64
- logger.info("Calling Replicate provider through Hugging Face proxy.")
65
- else:
66
- base_url = BASE_URL
67
- logger.info("Calling Replicate provider directly.")
68
- mapped_model = self._map_model(model)
69
- url = _build_url(base_url, mapped_model)
70
-
71
- headers = {
72
- **build_hf_headers(token=api_key),
73
- **headers,
74
- "Prefer": "wait",
75
- }
76
-
77
- payload = self._prepare_payload(inputs, parameters=parameters, model=mapped_model)
78
-
79
- return RequestParameters(
80
- url=url,
81
- task=self.task,
82
- model=mapped_model,
83
- json=payload,
84
- data=None,
85
- headers=headers,
86
- )
87
-
88
- def _map_model(self, model: Optional[str]) -> str:
89
- if model is None:
90
- raise ValueError("Please provide a model available on Replicate.")
91
- if self.task not in SUPPORTED_MODELS:
92
- raise ValueError(f"Task {self.task} not supported with Replicate.")
93
- mapped_model = SUPPORTED_MODELS[self.task].get(model)
94
- if mapped_model is None:
95
- raise ValueError(f"Model {model} is not supported with Replicate for task {self.task}.")
96
- return mapped_model
97
-
98
- def _prepare_payload(
99
- self,
100
- inputs: Any,
101
- parameters: Dict[str, Any],
102
- model: str,
103
- ) -> Dict[str, Any]:
104
- payload: Dict[str, Any] = {
105
- "input": {
106
- "prompt": inputs,
107
- **{k: v for k, v in parameters.items() if v is not None},
108
- }
109
- }
110
- if ":" in model:
111
- version = model.split(":", 1)[1]
14
+ super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task)
15
+
16
+ def _prepare_headers(self, headers: Dict, api_key: str) -> Dict:
17
+ headers = super()._prepare_headers(headers, api_key)
18
+ headers["Prefer"] = "wait"
19
+ return headers
20
+
21
+ def _prepare_route(self, mapped_model: str) -> str:
22
+ if ":" in mapped_model:
23
+ return "/v1/predictions"
24
+ return f"/v1/models/{mapped_model}/predictions"
25
+
26
+ def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
27
+ payload: Dict[str, Any] = {"input": {"prompt": inputs, **filter_none(parameters)}}
28
+ if ":" in mapped_model:
29
+ version = mapped_model.split(":", 1)[1]
112
30
  payload["version"] = version
113
31
  return payload
114
32
 
@@ -129,20 +47,7 @@ class ReplicateTextToSpeechTask(ReplicateTask):
129
47
  def __init__(self):
130
48
  super().__init__("text-to-speech")
131
49
 
132
- def _prepare_payload(
133
- self,
134
- inputs: Any,
135
- parameters: Dict[str, Any],
136
- model: str,
137
- ) -> Dict[str, Any]:
138
- # The following payload might work only for a subset of text-to-speech Replicate models.
139
- payload: Dict[str, Any] = {
140
- "input": {
141
- "inputs": inputs,
142
- **{k: v for k, v in parameters.items() if v is not None},
143
- },
144
- }
145
- if ":" in model:
146
- version = model.split(":", 1)[1]
147
- payload["version"] = version
50
+ def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
51
+ payload: Dict = super()._prepare_payload_as_dict(inputs, parameters, mapped_model) # type: ignore[assignment]
52
+ payload["input"]["text"] = payload["input"].pop("prompt") # rename "prompt" to "text" for TTS
148
53
  return payload
@@ -1,89 +1,6 @@
1
- from typing import Any, Dict, Optional, Union
1
+ from huggingface_hub.inference._providers._common import BaseConversationalTask
2
2
 
3
- from huggingface_hub import constants
4
- from huggingface_hub.inference._common import RequestParameters, TaskProviderHelper
5
- from huggingface_hub.utils import build_hf_headers, get_token, logging
6
3
 
7
-
8
- logger = logging.get_logger(__name__)
9
-
10
-
11
- BASE_URL = "https://api.sambanova.ai"
12
-
13
- SUPPORTED_MODELS = {
14
- "conversational": {
15
- "Qwen/Qwen2.5-Coder-32B-Instruct": "Qwen2.5-Coder-32B-Instruct",
16
- "Qwen/Qwen2.5-72B-Instruct": "Qwen2.5-72B-Instruct",
17
- "Qwen/QwQ-32B-Preview": "QwQ-32B-Preview",
18
- "meta-llama/Llama-3.3-70B-Instruct": "Meta-Llama-3.3-70B-Instruct",
19
- "meta-llama/Llama-3.2-1B": "Meta-Llama-3.2-1B-Instruct",
20
- "meta-llama/Llama-3.2-3B": "Meta-Llama-3.2-3B-Instruct",
21
- "meta-llama/Llama-3.2-11B-Vision-Instruct": "Llama-3.2-11B-Vision-Instruct",
22
- "meta-llama/Llama-3.2-90B-Vision-Instruct": "Llama-3.2-90B-Vision-Instruct",
23
- "meta-llama/Llama-3.1-8B-Instruct": "Meta-Llama-3.1-8B-Instruct",
24
- "meta-llama/Llama-3.1-70B-Instruct": "Meta-Llama-3.1-70B-Instruct",
25
- "meta-llama/Llama-3.1-405B-Instruct": "Meta-Llama-3.1-405B-Instruct",
26
- "meta-llama/Llama-Guard-3-8B": "Meta-Llama-Guard-3-8B",
27
- },
28
- }
29
-
30
-
31
- class SambanovaConversationalTask(TaskProviderHelper):
4
+ class SambanovaConversationalTask(BaseConversationalTask):
32
5
  def __init__(self):
33
- # TODO: adapt in a base class when supporting multiple tasks
34
- self.task = "conversational"
35
-
36
- def prepare_request(
37
- self,
38
- *,
39
- inputs: Any,
40
- parameters: Dict[str, Any],
41
- headers: Dict,
42
- model: Optional[str],
43
- api_key: Optional[str],
44
- extra_payload: Optional[Dict[str, Any]] = None,
45
- ) -> RequestParameters:
46
- if api_key is None:
47
- api_key = get_token()
48
- if api_key is None:
49
- raise ValueError(
50
- "You must provide an api_key to work with Sambanova API or log in with `huggingface-cli login`."
51
- )
52
-
53
- # Route to the proxy if the api_key is a HF TOKEN
54
- if api_key.startswith("hf_"):
55
- base_url = constants.INFERENCE_PROXY_TEMPLATE.format(provider="sambanova")
56
- logger.info("Calling Sambanova provider through Hugging Face proxy.")
57
- else:
58
- base_url = BASE_URL
59
- logger.info("Calling Sambanova provider directly.")
60
- headers = {**build_hf_headers(token=api_key), **headers}
61
-
62
- mapped_model = self._map_model(model)
63
- payload = {
64
- "messages": inputs,
65
- **{k: v for k, v in parameters.items() if v is not None},
66
- "model": mapped_model,
67
- }
68
-
69
- return RequestParameters(
70
- url=f"{base_url}/v1/chat/completions",
71
- task=self.task,
72
- model=mapped_model,
73
- json=payload,
74
- data=None,
75
- headers=headers,
76
- )
77
-
78
- def _map_model(self, model: Optional[str]) -> str:
79
- if model is None:
80
- raise ValueError("Please provide a model available on Sambanova.")
81
- if self.task not in SUPPORTED_MODELS:
82
- raise ValueError(f"Task {self.task} not supported with Sambanova.")
83
- mapped_model = SUPPORTED_MODELS[self.task].get(model)
84
- if mapped_model is None:
85
- raise ValueError(f"Model {model} is not supported with Sambanova for task {self.task}.")
86
- return mapped_model
87
-
88
- def get_response(self, response: Union[bytes, Dict]) -> Any:
89
- return response
6
+ super().__init__(provider="sambanova", base_url="https://api.sambanova.ai")
@@ -1,152 +1,58 @@
1
1
  import base64
2
- from abc import ABC, abstractmethod
2
+ from abc import ABC
3
3
  from typing import Any, Dict, Optional, Union
4
4
 
5
- from huggingface_hub import constants
6
- from huggingface_hub.inference._common import RequestParameters, TaskProviderHelper, _as_dict
7
- from huggingface_hub.utils import build_hf_headers, get_token, logging
8
-
9
-
10
- logger = logging.get_logger(__name__)
11
-
12
-
13
- BASE_URL = "https://api.together.xyz"
14
-
15
- SUPPORTED_MODELS = {
16
- "conversational": {
17
- "databricks/dbrx-instruct": "databricks/dbrx-instruct",
18
- "deepseek-ai/DeepSeek-R1": "deepseek-ai/DeepSeek-R1",
19
- "deepseek-ai/DeepSeek-V3": "deepseek-ai/DeepSeek-V3",
20
- "deepseek-ai/deepseek-llm-67b-chat": "deepseek-ai/deepseek-llm-67b-chat",
21
- "google/gemma-2-9b-it": "google/gemma-2-9b-it",
22
- "google/gemma-2b-it": "google/gemma-2-27b-it",
23
- "meta-llama/Llama-2-13b-chat-hf": "meta-llama/Llama-2-13b-chat-hf",
24
- "meta-llama/Llama-2-7b-chat-hf": "meta-llama/Llama-2-7b-chat-hf",
25
- "meta-llama/Llama-3.2-11B-Vision-Instruct": "meta-llama/Llama-Vision-Free",
26
- "meta-llama/Llama-3.2-3B-Instruct": "meta-llama/Llama-3.2-3B-Instruct-Turbo",
27
- "meta-llama/Llama-3.2-90B-Vision-Instruct": "meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo",
28
- "meta-llama/Llama-3.3-70B-Instruct": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
29
- "meta-llama/Meta-Llama-3-70B-Instruct": "meta-llama/Llama-3-70b-chat-hf",
30
- "meta-llama/Meta-Llama-3-8B-Instruct": "meta-llama/Meta-Llama-3-8B-Instruct-Turbo",
31
- "meta-llama/Meta-Llama-3.1-405B-Instruct": "meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo",
32
- "meta-llama/Meta-Llama-3.1-70B-Instruct": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
33
- "meta-llama/Meta-Llama-3.1-8B-Instruct": "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
34
- "microsoft/WizardLM-2-8x22B": "microsoft/WizardLM-2-8x22B",
35
- "mistralai/Mistral-7B-Instruct-v0.3": "mistralai/Mistral-7B-Instruct-v0.3",
36
- "mistralai/Mixtral-8x22B-Instruct-v0.1": "mistralai/Mixtral-8x22B-Instruct-v0.1",
37
- "mistralai/Mixtral-8x7B-Instruct-v0.1": "mistralai/Mixtral-8x7B-Instruct-v0.1",
38
- "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
39
- "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF": "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF",
40
- "Qwen/Qwen2-72B-Instruct": "Qwen/Qwen2-72B-Instruct",
41
- "Qwen/Qwen2.5-72B-Instruct": "Qwen/Qwen2.5-72B-Instruct-Turbo",
42
- "Qwen/Qwen2.5-7B-Instruct": "Qwen/Qwen2.5-7B-Instruct-Turbo",
43
- "Qwen/Qwen2.5-Coder-32B-Instruct": "Qwen/Qwen2.5-Coder-32B-Instruct",
44
- "Qwen/QwQ-32B-Preview": "Qwen/QwQ-32B-Preview",
45
- "scb10x/llama-3-typhoon-v1.5-8b-instruct": "scb10x/scb10x-llama3-typhoon-v1-5-8b-instruct",
46
- "scb10x/llama-3-typhoon-v1.5x-70b-instruct-awq": "scb10x/scb10x-llama3-typhoon-v1-5x-4f316",
47
- },
48
- "text-generation": {
49
- "meta-llama/Llama-2-70b-hf": "meta-llama/Llama-2-70b-hf",
50
- "meta-llama/Meta-Llama-3-8B": "meta-llama/Meta-Llama-3-8B",
51
- "mistralai/Mixtral-8x7B-v0.1": "mistralai/Mixtral-8x7B-v0.1",
52
- },
53
- "text-to-image": {
54
- "black-forest-labs/FLUX.1-Canny-dev": "black-forest-labs/FLUX.1-canny",
55
- "black-forest-labs/FLUX.1-Depth-dev": "black-forest-labs/FLUX.1-depth",
56
- "black-forest-labs/FLUX.1-dev": "black-forest-labs/FLUX.1-dev",
57
- "black-forest-labs/FLUX.1-Redux-dev": "black-forest-labs/FLUX.1-redux",
58
- "black-forest-labs/FLUX.1-schnell": "black-forest-labs/FLUX.1-pro",
59
- "stabilityai/stable-diffusion-xl-base-1.0": "stabilityai/stable-diffusion-xl-base-1.0",
60
- },
61
- }
62
-
63
-
64
- PER_TASK_ROUTES = {
65
- "conversational": "v1/chat/completions",
66
- "text-generation": "v1/completions",
67
- "text-to-image": "v1/images/generations",
68
- }
5
+ from huggingface_hub.inference._common import _as_dict
6
+ from huggingface_hub.inference._providers._common import (
7
+ BaseConversationalTask,
8
+ BaseTextGenerationTask,
9
+ TaskProviderHelper,
10
+ filter_none,
11
+ )
12
+
13
+
14
+ _PROVIDER = "together"
15
+ _BASE_URL = "https://api.together.xyz"
69
16
 
70
17
 
71
18
  class TogetherTask(TaskProviderHelper, ABC):
72
19
  """Base class for Together API tasks."""
73
20
 
74
21
  def __init__(self, task: str):
75
- self.task = task
76
-
77
- def prepare_request(
78
- self,
79
- *,
80
- inputs: Any,
81
- parameters: Dict[str, Any],
82
- headers: Dict,
83
- model: Optional[str],
84
- api_key: Optional[str],
85
- extra_payload: Optional[Dict[str, Any]] = None,
86
- ) -> RequestParameters:
87
- if api_key is None:
88
- api_key = get_token()
89
- if api_key is None:
90
- raise ValueError(
91
- "You must provide an api_key to work with Together API or log in with `huggingface-cli login`."
92
- )
93
- headers = {**build_hf_headers(token=api_key), **headers}
94
-
95
- # Route to the proxy if the api_key is a HF TOKEN
96
- if api_key.startswith("hf_"):
97
- base_url = constants.INFERENCE_PROXY_TEMPLATE.format(provider="together")
98
- logger.info("Calling Together provider through Hugging Face proxy.")
99
- else:
100
- base_url = BASE_URL
101
- logger.info("Calling Together provider directly.")
102
- mapped_model = self._map_model(model)
103
- if "model" in parameters:
104
- parameters["model"] = mapped_model
105
- payload = self._prepare_payload(inputs, parameters=parameters)
106
-
107
- return RequestParameters(
108
- url=f"{base_url}/{PER_TASK_ROUTES[self.task]}",
109
- task=self.task,
110
- model=mapped_model,
111
- json=payload,
112
- data=None,
113
- headers=headers,
114
- )
115
-
116
- def _map_model(self, model: Optional[str]) -> str:
117
- if model is None:
118
- raise ValueError("Please provide a model available on Together.")
119
- if self.task not in SUPPORTED_MODELS:
120
- raise ValueError(f"Task {self.task} not supported with Together.")
121
- mapped_model = SUPPORTED_MODELS[self.task].get(model)
122
- if mapped_model is None:
123
- raise ValueError(f"Model {model} is not supported with Together for task {self.task}.")
124
- return mapped_model
22
+ super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task)
125
23
 
126
- def get_response(self, response: Union[bytes, Dict]) -> Any:
127
- return response
24
+ def _prepare_route(self, mapped_model: str) -> str:
25
+ if self.task == "text-to-image":
26
+ return "/v1/images/generations"
27
+ elif self.task == "conversational":
28
+ return "/v1/chat/completions"
29
+ elif self.task == "text-generation":
30
+ return "/v1/completions"
31
+ raise ValueError(f"Unsupported task '{self.task}' for Together API.")
128
32
 
129
- @abstractmethod
130
- def _prepare_payload(self, inputs: Any, parameters: Dict[str, Any]) -> Dict[str, Any]: ...
131
33
 
34
+ class TogetherTextGenerationTask(BaseTextGenerationTask):
35
+ def __init__(self):
36
+ super().__init__(provider=_PROVIDER, base_url=_BASE_URL)
132
37
 
133
- class TogetherTextGenerationTask(TogetherTask):
134
- # Handle both "text-generation" and "conversational"
135
- def _prepare_payload(self, inputs: Any, parameters: Dict[str, Any]) -> Dict[str, Any]:
136
- return {"messages": inputs, **{k: v for k, v in parameters.items() if v is not None}}
38
+
39
+ class TogetherConversationalTask(BaseConversationalTask):
40
+ def __init__(self):
41
+ super().__init__(provider=_PROVIDER, base_url=_BASE_URL)
137
42
 
138
43
 
139
44
  class TogetherTextToImageTask(TogetherTask):
140
45
  def __init__(self):
141
46
  super().__init__("text-to-image")
142
47
 
143
- def _prepare_payload(self, inputs: Any, parameters: Dict[str, Any]) -> Dict[str, Any]:
144
- payload = {
145
- "prompt": inputs,
146
- "response_format": "base64",
147
- **{k: v for k, v in parameters.items() if v is not None},
148
- }
149
- return payload
48
+ def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
49
+ parameters = filter_none(parameters)
50
+ if "num_inference_steps" in parameters:
51
+ parameters["steps"] = parameters.pop("num_inference_steps")
52
+ if "guidance_scale" in parameters:
53
+ parameters["guidance"] = parameters.pop("guidance_scale")
54
+
55
+ return {"prompt": inputs, "response_format": "base64", **parameters, "model": mapped_model}
150
56
 
151
57
  def get_response(self, response: Union[bytes, Dict]) -> Any:
152
58
  response_dict = _as_dict(response)
@@ -213,6 +213,11 @@ def _http_user_agent(
213
213
  elif isinstance(user_agent, str):
214
214
  ua += "; " + user_agent
215
215
 
216
+ # Retrieve user-agent origin headers from environment variable
217
+ origin = constants.HF_HUB_USER_AGENT_ORIGIN
218
+ if origin is not None:
219
+ ua += "; origin/" + origin
220
+
216
221
  return _deduplicate_user_agent(ua)
217
222
 
218
223
 
@@ -14,7 +14,6 @@
14
14
  # limitations under the License.
15
15
  """Contain helper class to retrieve/store token from/to local cache."""
16
16
 
17
- import warnings
18
17
  from pathlib import Path
19
18
  from typing import Optional
20
19
 
@@ -23,10 +22,6 @@ from ._auth import get_token
23
22
 
24
23
 
25
24
  class HfFolder:
26
- path_token = Path(constants.HF_TOKEN_PATH)
27
- # Private attribute. Will be removed in v0.15
28
- _old_path_token = Path(constants._OLD_HF_TOKEN_PATH)
29
-
30
25
  # TODO: deprecate when adapted in transformers/datasets/gradio
31
26
  # @_deprecate_method(version="1.0", message="Use `huggingface_hub.login` instead.")
32
27
  @classmethod
@@ -41,8 +36,9 @@ class HfFolder:
41
36
  token (`str`):
42
37
  The token to save to the [`HfFolder`]
43
38
  """
44
- cls.path_token.parent.mkdir(parents=True, exist_ok=True)
45
- cls.path_token.write_text(token)
39
+ path_token = Path(constants.HF_TOKEN_PATH)
40
+ path_token.parent.mkdir(parents=True, exist_ok=True)
41
+ path_token.write_text(token)
46
42
 
47
43
  # TODO: deprecate when adapted in transformers/datasets/gradio
48
44
  # @_deprecate_method(version="1.0", message="Use `huggingface_hub.get_token` instead.")
@@ -57,12 +53,6 @@ class HfFolder:
57
53
  Returns:
58
54
  `str` or `None`: The token, `None` if it doesn't exist.
59
55
  """
60
- # 0. Check if token exist in old path but not new location
61
- try:
62
- cls._copy_to_new_path_and_warn()
63
- except Exception: # if not possible (e.g. PermissionError), do not raise
64
- pass
65
-
66
56
  return get_token()
67
57
 
68
58
  # TODO: deprecate when adapted in transformers/datasets/gradio
@@ -73,24 +63,6 @@ class HfFolder:
73
63
  Deletes the token from storage. Does not fail if token does not exist.
74
64
  """
75
65
  try:
76
- cls.path_token.unlink()
77
- except FileNotFoundError:
78
- pass
79
-
80
- try:
81
- cls._old_path_token.unlink()
66
+ Path(constants.HF_TOKEN_PATH).unlink()
82
67
  except FileNotFoundError:
83
68
  pass
84
-
85
- @classmethod
86
- def _copy_to_new_path_and_warn(cls):
87
- if cls._old_path_token.exists() and not cls.path_token.exists():
88
- cls.save_token(cls._old_path_token.read_text())
89
- warnings.warn(
90
- f"A token has been found in `{cls._old_path_token}`. This is the old"
91
- " path where tokens were stored. The new location is"
92
- f" `{cls.path_token}` which is configurable using `HF_HOME` environment"
93
- " variable. Your token has been copied to this new location. You can"
94
- " now safely delete the old token file manually or use"
95
- " `huggingface-cli logout`."
96
- )
@@ -22,7 +22,8 @@ import time
22
22
  import uuid
23
23
  from functools import lru_cache
24
24
  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
26
27
 
27
28
  import requests
28
29
  from requests import HTTPError, Response
@@ -82,13 +83,15 @@ class UniqueRequestIdAdapter(HTTPAdapter):
82
83
  request.headers[X_AMZN_TRACE_ID] = request.headers.get(X_REQUEST_ID) or str(uuid.uuid4())
83
84
 
84
85
  # Add debug log
85
- has_token = str(request.headers.get("authorization", "")).startswith("Bearer hf_")
86
+ has_token = len(str(request.headers.get("authorization", ""))) > 0
86
87
  logger.debug(
87
88
  f"Request {request.headers[X_AMZN_TRACE_ID]}: {request.method} {request.url} (authenticated: {has_token})"
88
89
  )
89
90
 
90
91
  def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
91
92
  """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)}")
92
95
  try:
93
96
  return super().send(request, *args, **kwargs)
94
97
  except requests.RequestException as e:
@@ -434,6 +437,7 @@ def hf_raise_for_status(response: Response, endpoint_name: Optional[str] = None)
434
437
 
435
438
  elif error_code == "RepoNotFound" or (
436
439
  response.status_code == 401
440
+ and error_message != "Invalid credentials in Authorization header"
437
441
  and response.request is not None
438
442
  and response.request.url is not None
439
443
  and REPO_API_REGEX.search(response.request.url) is not None
@@ -549,3 +553,82 @@ def _format(error_type: Type[HfHubHTTPError], custom_message: str, response: Res
549
553
 
550
554
  # Return
551
555
  return error_type(final_error_message.strip(), response=response, server_message=server_message or None)
556
+
557
+
558
+ def _curlify(request: requests.PreparedRequest) -> str:
559
+ """Convert a `requests.PreparedRequest` into a curl command (str).
560
+
561
+ Used for debug purposes only.
562
+
563
+ Implementation vendored from https://github.com/ofw/curlify/blob/master/curlify.py.
564
+ MIT License Copyright (c) 2016 Egor.
565
+ """
566
+ parts: List[Tuple[Any, Any]] = [
567
+ ("curl", None),
568
+ ("-X", request.method),
569
+ ]
570
+
571
+ for k, v in sorted(request.headers.items()):
572
+ if k.lower() == "authorization":
573
+ v = "<TOKEN>" # Hide authorization header, no matter its value (can be Bearer, Key, etc.)
574
+ parts += [("-H", "{0}: {1}".format(k, v))]
575
+
576
+ if request.body:
577
+ body = request.body
578
+ if isinstance(body, bytes):
579
+ body = body.decode("utf-8", errors="ignore")
580
+ if len(body) > 1000:
581
+ body = body[:1000] + " ... [truncated]"
582
+ parts += [("-d", body.replace("\n", ""))]
583
+
584
+ parts += [(None, request.url)]
585
+
586
+ flat_parts = []
587
+ for k, v in parts:
588
+ if k:
589
+ flat_parts.append(quote(k))
590
+ if v:
591
+ flat_parts.append(quote(v))
592
+
593
+ return " ".join(flat_parts)
594
+
595
+
596
+ # Regex to parse HTTP Range header
597
+ RANGE_REGEX = re.compile(r"^\s*bytes\s*=\s*(\d*)\s*-\s*(\d*)\s*$", re.IGNORECASE)
598
+
599
+
600
+ def _adjust_range_header(original_range: Optional[str], resume_size: int) -> Optional[str]:
601
+ """
602
+ Adjust HTTP Range header to account for resume position.
603
+ """
604
+ if not original_range:
605
+ return f"bytes={resume_size}-"
606
+
607
+ if "," in original_range:
608
+ raise ValueError(f"Multiple ranges detected - {original_range!r}, not supported yet.")
609
+
610
+ match = RANGE_REGEX.match(original_range)
611
+ if not match:
612
+ raise RuntimeError(f"Invalid range format - {original_range!r}.")
613
+ start, end = match.groups()
614
+
615
+ if not start:
616
+ if not end:
617
+ raise RuntimeError(f"Invalid range format - {original_range!r}.")
618
+
619
+ new_suffix = int(end) - resume_size
620
+ new_range = f"bytes=-{new_suffix}"
621
+ if new_suffix <= 0:
622
+ raise RuntimeError(f"Empty new range - {new_range!r}.")
623
+ return new_range
624
+
625
+ start = int(start)
626
+ new_start = start + resume_size
627
+ if end:
628
+ end = int(end)
629
+ new_range = f"bytes={new_start}-{end}"
630
+ if new_start > end:
631
+ raise RuntimeError(f"Empty new range - {new_range!r}.")
632
+ return new_range
633
+
634
+ return f"bytes={new_start}-"
@@ -50,7 +50,7 @@ def is_jsonable(obj: Any) -> bool:
50
50
  if isinstance(obj, (list, tuple)):
51
51
  return all(is_jsonable(item) for item in obj)
52
52
  if isinstance(obj, dict):
53
- return all(isinstance(key, str) and is_jsonable(value) for key, value in obj.items())
53
+ return all(isinstance(key, _JSON_SERIALIZABLE_TYPES) and is_jsonable(value) for key, value in obj.items())
54
54
  if hasattr(obj, "__json__"):
55
55
  return True
56
56
  return False
@@ -28,6 +28,8 @@ from logging import (
28
28
  )
29
29
  from typing import Optional
30
30
 
31
+ from .. import constants
32
+
31
33
 
32
34
  log_levels = {
33
35
  "debug": logging.DEBUG,
@@ -180,3 +182,7 @@ def enable_propagation() -> None:
180
182
 
181
183
 
182
184
  _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()