huggingface-hub 1.0.0rc1__py3-none-any.whl → 1.0.0rc3__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 (59) hide show
  1. huggingface_hub/__init__.py +4 -7
  2. huggingface_hub/_commit_api.py +126 -66
  3. huggingface_hub/_commit_scheduler.py +4 -7
  4. huggingface_hub/_login.py +10 -16
  5. huggingface_hub/_snapshot_download.py +119 -21
  6. huggingface_hub/_tensorboard_logger.py +2 -5
  7. huggingface_hub/_upload_large_folder.py +1 -2
  8. huggingface_hub/_webhooks_server.py +8 -20
  9. huggingface_hub/cli/_cli_utils.py +12 -6
  10. huggingface_hub/cli/download.py +32 -7
  11. huggingface_hub/cli/repo.py +137 -5
  12. huggingface_hub/dataclasses.py +122 -2
  13. huggingface_hub/errors.py +4 -0
  14. huggingface_hub/fastai_utils.py +22 -32
  15. huggingface_hub/file_download.py +234 -38
  16. huggingface_hub/hf_api.py +385 -424
  17. huggingface_hub/hf_file_system.py +55 -65
  18. huggingface_hub/inference/_client.py +27 -48
  19. huggingface_hub/inference/_generated/_async_client.py +27 -48
  20. huggingface_hub/inference/_generated/types/image_to_image.py +6 -2
  21. huggingface_hub/inference/_mcp/agent.py +2 -5
  22. huggingface_hub/inference/_mcp/mcp_client.py +6 -8
  23. huggingface_hub/inference/_providers/__init__.py +16 -0
  24. huggingface_hub/inference/_providers/_common.py +2 -0
  25. huggingface_hub/inference/_providers/fal_ai.py +2 -0
  26. huggingface_hub/inference/_providers/publicai.py +6 -0
  27. huggingface_hub/inference/_providers/scaleway.py +28 -0
  28. huggingface_hub/inference/_providers/zai_org.py +17 -0
  29. huggingface_hub/lfs.py +14 -8
  30. huggingface_hub/repocard.py +12 -16
  31. huggingface_hub/serialization/_base.py +3 -6
  32. huggingface_hub/serialization/_torch.py +16 -34
  33. huggingface_hub/utils/__init__.py +1 -2
  34. huggingface_hub/utils/_cache_manager.py +42 -72
  35. huggingface_hub/utils/_chunk_utils.py +2 -3
  36. huggingface_hub/utils/_http.py +37 -68
  37. huggingface_hub/utils/_validators.py +2 -2
  38. huggingface_hub/utils/logging.py +8 -11
  39. {huggingface_hub-1.0.0rc1.dist-info → huggingface_hub-1.0.0rc3.dist-info}/METADATA +2 -2
  40. {huggingface_hub-1.0.0rc1.dist-info → huggingface_hub-1.0.0rc3.dist-info}/RECORD +44 -56
  41. {huggingface_hub-1.0.0rc1.dist-info → huggingface_hub-1.0.0rc3.dist-info}/entry_points.txt +0 -1
  42. huggingface_hub/commands/__init__.py +0 -27
  43. huggingface_hub/commands/_cli_utils.py +0 -74
  44. huggingface_hub/commands/delete_cache.py +0 -476
  45. huggingface_hub/commands/download.py +0 -195
  46. huggingface_hub/commands/env.py +0 -39
  47. huggingface_hub/commands/huggingface_cli.py +0 -65
  48. huggingface_hub/commands/lfs.py +0 -200
  49. huggingface_hub/commands/repo.py +0 -151
  50. huggingface_hub/commands/repo_files.py +0 -132
  51. huggingface_hub/commands/scan_cache.py +0 -183
  52. huggingface_hub/commands/tag.py +0 -159
  53. huggingface_hub/commands/upload.py +0 -318
  54. huggingface_hub/commands/upload_large_folder.py +0 -131
  55. huggingface_hub/commands/user.py +0 -207
  56. huggingface_hub/commands/version.py +0 -40
  57. {huggingface_hub-1.0.0rc1.dist-info → huggingface_hub-1.0.0rc3.dist-info}/LICENSE +0 -0
  58. {huggingface_hub-1.0.0rc1.dist-info → huggingface_hub-1.0.0rc3.dist-info}/WHEEL +0 -0
  59. {huggingface_hub-1.0.0rc1.dist-info → huggingface_hub-1.0.0rc3.dist-info}/top_level.txt +0 -0
huggingface_hub/hf_api.py CHANGED
@@ -15,7 +15,6 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import inspect
18
- import io
19
18
  import json
20
19
  import re
21
20
  import struct
@@ -42,7 +41,7 @@ from typing import (
42
41
  Union,
43
42
  overload,
44
43
  )
45
- from urllib.parse import quote, unquote
44
+ from urllib.parse import quote
46
45
 
47
46
  import httpx
48
47
  from tqdm.auto import tqdm as base_tqdm
@@ -57,12 +56,11 @@ from ._commit_api import (
57
56
  _fetch_files_to_copy,
58
57
  _fetch_upload_modes,
59
58
  _prepare_commit_payload,
60
- _upload_lfs_files,
61
- _upload_xet_files,
59
+ _upload_files,
62
60
  _warn_on_overwriting_operations,
63
61
  )
64
62
  from ._inference_endpoints import InferenceEndpoint, InferenceEndpointType
65
- from ._jobs_api import JobInfo, ScheduledJobInfo, _create_job_spec
63
+ from ._jobs_api import JobInfo, JobSpec, ScheduledJobInfo, _create_job_spec
66
64
  from ._space_api import SpaceHardware, SpaceRuntime, SpaceStorage, SpaceVariable
67
65
  from ._upload_large_folder import upload_large_folder_internal
68
66
  from .community import (
@@ -81,7 +79,7 @@ from .errors import (
81
79
  RepositoryNotFoundError,
82
80
  RevisionNotFoundError,
83
81
  )
84
- from .file_download import HfFileMetadata, get_hf_file_metadata, hf_hub_url
82
+ from .file_download import DryRunFileInfo, HfFileMetadata, get_hf_file_metadata, hf_hub_url
85
83
  from .repocard_data import DatasetCardData, ModelCardData, SpaceCardData
86
84
  from .utils import (
87
85
  DEFAULT_IGNORE_PATTERNS,
@@ -104,13 +102,8 @@ from .utils import (
104
102
  validate_hf_hub_args,
105
103
  )
106
104
  from .utils import tqdm as hf_tqdm
107
- from .utils._auth import (
108
- _get_token_from_environment,
109
- _get_token_from_file,
110
- _get_token_from_google_colab,
111
- )
105
+ from .utils._auth import _get_token_from_environment, _get_token_from_file, _get_token_from_google_colab
112
106
  from .utils._deprecation import _deprecate_arguments
113
- from .utils._runtime import is_xet_available
114
107
  from .utils._typing import CallableT
115
108
  from .utils.endpoint_helpers import _is_emission_within_threshold
116
109
 
@@ -473,11 +466,15 @@ class WebhookWatchedItem:
473
466
  class WebhookInfo:
474
467
  """Data structure containing information about a webhook.
475
468
 
469
+ One of `url` or `job` is specified, but not both.
470
+
476
471
  Attributes:
477
472
  id (`str`):
478
473
  ID of the webhook.
479
- url (`str`):
474
+ url (`str`, *optional*):
480
475
  URL of the webhook.
476
+ job (`JobSpec`, *optional*):
477
+ Specifications of the Job to trigger.
481
478
  watched (`list[WebhookWatchedItem]`):
482
479
  List of items watched by the webhook, see [`WebhookWatchedItem`].
483
480
  domains (`list[WEBHOOK_DOMAIN_T]`):
@@ -489,7 +486,8 @@ class WebhookInfo:
489
486
  """
490
487
 
491
488
  id: str
492
- url: str
489
+ url: Optional[str]
490
+ job: Optional[JobSpec]
493
491
  watched: list[WebhookWatchedItem]
494
492
  domains: list[constants.WEBHOOK_DOMAIN_T]
495
493
  secret: Optional[str]
@@ -562,15 +560,12 @@ class RepoSibling:
562
560
  """
563
561
  Contains basic information about a repo file inside a repo on the Hub.
564
562
 
565
- <Tip>
566
-
567
- All attributes of this class are optional except `rfilename`. This is because only the file names are returned when
568
- listing repositories on the Hub (with [`list_models`], [`list_datasets`] or [`list_spaces`]). If you need more
569
- information like file size, blob id or lfs details, you must request them specifically from one repo at a time
570
- (using [`model_info`], [`dataset_info`] or [`space_info`]) as it adds more constraints on the backend server to
571
- retrieve these.
572
-
573
- </Tip>
563
+ > [!TIP]
564
+ > All attributes of this class are optional except `rfilename`. This is because only the file names are returned when
565
+ > listing repositories on the Hub (with [`list_models`], [`list_datasets`] or [`list_spaces`]). If you need more
566
+ > information like file size, blob id or lfs details, you must request them specifically from one repo at a time
567
+ > (using [`model_info`], [`dataset_info`] or [`space_info`]) as it adds more constraints on the backend server to
568
+ > retrieve these.
574
569
 
575
570
  Attributes:
576
571
  rfilename (str):
@@ -711,13 +706,10 @@ class ModelInfo:
711
706
  """
712
707
  Contains information about a model on the Hub. This object is returned by [`model_info`] and [`list_models`].
713
708
 
714
- <Tip>
715
-
716
- Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made.
717
- In general, the more specific the query, the more information is returned. On the contrary, when listing models
718
- using [`list_models`] only a subset of the attributes are returned.
719
-
720
- </Tip>
709
+ > [!TIP]
710
+ > Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made.
711
+ > In general, the more specific the query, the more information is returned. On the contrary, when listing models
712
+ > using [`list_models`] only a subset of the attributes are returned.
721
713
 
722
714
  Attributes:
723
715
  id (`str`):
@@ -910,13 +902,10 @@ class DatasetInfo:
910
902
  """
911
903
  Contains information about a dataset on the Hub. This object is returned by [`dataset_info`] and [`list_datasets`].
912
904
 
913
- <Tip>
914
-
915
- Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made.
916
- In general, the more specific the query, the more information is returned. On the contrary, when listing datasets
917
- using [`list_datasets`] only a subset of the attributes are returned.
918
-
919
- </Tip>
905
+ > [!TIP]
906
+ > Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made.
907
+ > In general, the more specific the query, the more information is returned. On the contrary, when listing datasets
908
+ > using [`list_datasets`] only a subset of the attributes are returned.
920
909
 
921
910
  Attributes:
922
911
  id (`str`):
@@ -1029,13 +1018,10 @@ class SpaceInfo:
1029
1018
  """
1030
1019
  Contains information about a Space on the Hub. This object is returned by [`space_info`] and [`list_spaces`].
1031
1020
 
1032
- <Tip>
1033
-
1034
- Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made.
1035
- In general, the more specific the query, the more information is returned. On the contrary, when listing spaces
1036
- using [`list_spaces`] only a subset of the attributes are returned.
1037
-
1038
- </Tip>
1021
+ > [!TIP]
1022
+ > Most attributes of this class are optional. This is because the data returned by the Hub depends on the query made.
1023
+ > In general, the more specific the query, the more information is returned. On the contrary, when listing spaces
1024
+ > using [`list_spaces`] only a subset of the attributes are returned.
1039
1025
 
1040
1026
  Attributes:
1041
1027
  id (`str`):
@@ -2512,17 +2498,14 @@ class HfApi:
2512
2498
  Returns:
2513
2499
  [`huggingface_hub.hf_api.ModelInfo`]: The model repository information.
2514
2500
 
2515
- <Tip>
2516
-
2517
- Raises the following errors:
2518
-
2519
- - [`~utils.RepositoryNotFoundError`]
2520
- If the repository to download from cannot be found. This may be because it doesn't exist,
2521
- or because it is set to `private` and you do not have access.
2522
- - [`~utils.RevisionNotFoundError`]
2523
- If the revision to download from cannot be found.
2524
-
2525
- </Tip>
2501
+ > [!TIP]
2502
+ > Raises the following errors:
2503
+ >
2504
+ > - [`~utils.RepositoryNotFoundError`]
2505
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
2506
+ > or because it is set to `private` and you do not have access.
2507
+ > - [`~utils.RevisionNotFoundError`]
2508
+ > If the revision to download from cannot be found.
2526
2509
  """
2527
2510
  if expand and (securityStatus or files_metadata):
2528
2511
  raise ValueError("`expand` cannot be used if `securityStatus` or `files_metadata` are set.")
@@ -2586,17 +2569,14 @@ class HfApi:
2586
2569
  Returns:
2587
2570
  [`hf_api.DatasetInfo`]: The dataset repository information.
2588
2571
 
2589
- <Tip>
2590
-
2591
- Raises the following errors:
2592
-
2593
- - [`~utils.RepositoryNotFoundError`]
2594
- If the repository to download from cannot be found. This may be because it doesn't exist,
2595
- or because it is set to `private` and you do not have access.
2596
- - [`~utils.RevisionNotFoundError`]
2597
- If the revision to download from cannot be found.
2598
-
2599
- </Tip>
2572
+ > [!TIP]
2573
+ > Raises the following errors:
2574
+ >
2575
+ > - [`~utils.RepositoryNotFoundError`]
2576
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
2577
+ > or because it is set to `private` and you do not have access.
2578
+ > - [`~utils.RevisionNotFoundError`]
2579
+ > If the revision to download from cannot be found.
2600
2580
  """
2601
2581
  if expand and files_metadata:
2602
2582
  raise ValueError("`expand` cannot be used if `files_metadata` is set.")
@@ -2659,17 +2639,14 @@ class HfApi:
2659
2639
  Returns:
2660
2640
  [`~hf_api.SpaceInfo`]: The space repository information.
2661
2641
 
2662
- <Tip>
2663
-
2664
- Raises the following errors:
2665
-
2666
- - [`~utils.RepositoryNotFoundError`]
2667
- If the repository to download from cannot be found. This may be because it doesn't exist,
2668
- or because it is set to `private` and you do not have access.
2669
- - [`~utils.RevisionNotFoundError`]
2670
- If the revision to download from cannot be found.
2671
-
2672
- </Tip>
2642
+ > [!TIP]
2643
+ > Raises the following errors:
2644
+ >
2645
+ > - [`~utils.RepositoryNotFoundError`]
2646
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
2647
+ > or because it is set to `private` and you do not have access.
2648
+ > - [`~utils.RevisionNotFoundError`]
2649
+ > If the revision to download from cannot be found.
2673
2650
  """
2674
2651
  if expand and files_metadata:
2675
2652
  raise ValueError("`expand` cannot be used if `files_metadata` is set.")
@@ -2736,17 +2713,14 @@ class HfApi:
2736
2713
  [`huggingface_hub.hf_api.DatasetInfo`], [`huggingface_hub.hf_api.ModelInfo`]
2737
2714
  or [`huggingface_hub.hf_api.SpaceInfo`] object.
2738
2715
 
2739
- <Tip>
2740
-
2741
- Raises the following errors:
2742
-
2743
- - [`~utils.RepositoryNotFoundError`]
2744
- If the repository to download from cannot be found. This may be because it doesn't exist,
2745
- or because it is set to `private` and you do not have access.
2746
- - [`~utils.RevisionNotFoundError`]
2747
- If the revision to download from cannot be found.
2748
-
2749
- </Tip>
2716
+ > [!TIP]
2717
+ > Raises the following errors:
2718
+ >
2719
+ > - [`~utils.RepositoryNotFoundError`]
2720
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
2721
+ > or because it is set to `private` and you do not have access.
2722
+ > - [`~utils.RevisionNotFoundError`]
2723
+ > If the revision to download from cannot be found.
2750
2724
  """
2751
2725
  if repo_type is None or repo_type == "model":
2752
2726
  method = self.model_info
@@ -3333,18 +3307,12 @@ class HfApi:
3333
3307
  Squashing the repo history is useful when you know you'll make hundreds of commits and you don't want to
3334
3308
  clutter the history. Squashing commits can only be performed from the head of a branch.
3335
3309
 
3336
- <Tip warning={true}>
3337
-
3338
- Once squashed, the commit history cannot be retrieved. This is a non-revertible operation.
3339
-
3340
- </Tip>
3341
-
3342
- <Tip warning={true}>
3343
-
3344
- Once the history of a branch has been squashed, it is not possible to merge it back into another branch since
3345
- their history will have diverged.
3310
+ > [!WARNING]
3311
+ > Once squashed, the commit history cannot be retrieved. This is a non-revertible operation.
3346
3312
 
3347
- </Tip>
3313
+ > [!WARNING]
3314
+ > Once the history of a branch has been squashed, it is not possible to merge it back into another branch since
3315
+ > their history will have diverged.
3348
3316
 
3349
3317
  Args:
3350
3318
  repo_id (`str`):
@@ -3471,12 +3439,9 @@ class HfApi:
3471
3439
  """
3472
3440
  Permanently delete LFS files from a repo on the Hub.
3473
3441
 
3474
- <Tip warning={true}>
3475
-
3476
- This is a permanent action that will affect all commits referencing the deleted files and might corrupt your
3477
- repository. This is a non-revertible operation. Use it only if you know what you are doing.
3478
-
3479
- </Tip>
3442
+ > [!WARNING]
3443
+ > This is a permanent action that will affect all commits referencing the deleted files and might corrupt your
3444
+ > repository. This is a non-revertible operation. Use it only if you know what you are doing.
3480
3445
 
3481
3446
  Args:
3482
3447
  repo_id (`str`):
@@ -3841,15 +3806,12 @@ class HfApi:
3841
3806
  https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
3842
3807
  To disable authentication, pass `False`.
3843
3808
 
3844
- <Tip>
3845
-
3846
- Raises the following errors:
3847
-
3848
- - [`~utils.RepositoryNotFoundError`]
3849
- If the repository to download from cannot be found. This may be because it doesn't exist,
3850
- or because it is set to `private` and you do not have access.
3851
-
3852
- </Tip>
3809
+ > [!TIP]
3810
+ > Raises the following errors:
3811
+ >
3812
+ > - [`~utils.RepositoryNotFoundError`]
3813
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
3814
+ > or because it is set to `private` and you do not have access.
3853
3815
  """
3854
3816
  if len(from_id.split("/")) != 2:
3855
3817
  raise ValueError(f"Invalid repo_id: {from_id}. It should have a namespace (:namespace:/:repo_name:)")
@@ -3928,27 +3890,18 @@ class HfApi:
3928
3890
  """
3929
3891
  Creates a commit in the given repo, deleting & uploading files as needed.
3930
3892
 
3931
- <Tip warning={true}>
3893
+ > [!WARNING]
3894
+ > The input list of `CommitOperation` will be mutated during the commit process. Do not reuse the same objects
3895
+ > for multiple commits.
3932
3896
 
3933
- The input list of `CommitOperation` will be mutated during the commit process. Do not reuse the same objects
3934
- for multiple commits.
3897
+ > [!WARNING]
3898
+ > `create_commit` assumes that the repo already exists on the Hub. If you get a
3899
+ > Client error 404, please make sure you are authenticated and that `repo_id` and
3900
+ > `repo_type` are set correctly. If repo does not exist, create it first using
3901
+ > [`~hf_api.create_repo`].
3935
3902
 
3936
- </Tip>
3937
-
3938
- <Tip warning={true}>
3939
-
3940
- `create_commit` assumes that the repo already exists on the Hub. If you get a
3941
- Client error 404, please make sure you are authenticated and that `repo_id` and
3942
- `repo_type` are set correctly. If repo does not exist, create it first using
3943
- [`~hf_api.create_repo`].
3944
-
3945
- </Tip>
3946
-
3947
- <Tip warning={true}>
3948
-
3949
- `create_commit` is limited to 25k LFS files and a 1GB payload for regular files.
3950
-
3951
- </Tip>
3903
+ > [!WARNING]
3904
+ > `create_commit` is limited to 25k LFS files and a 1GB payload for regular files.
3952
3905
 
3953
3906
  Args:
3954
3907
  repo_id (`str`):
@@ -4222,21 +4175,15 @@ class HfApi:
4222
4175
  This method is useful if you are generating the files to upload on-the-fly and you don't want to store them
4223
4176
  in memory before uploading them all at once.
4224
4177
 
4225
- <Tip warning={true}>
4178
+ > [!WARNING]
4179
+ > This is a power-user method. You shouldn't need to call it directly to make a normal commit.
4180
+ > Use [`create_commit`] directly instead.
4226
4181
 
4227
- This is a power-user method. You shouldn't need to call it directly to make a normal commit.
4228
- Use [`create_commit`] directly instead.
4229
-
4230
- </Tip>
4231
-
4232
- <Tip warning={true}>
4233
-
4234
- Commit operations will be mutated during the process. In particular, the attached `path_or_fileobj` will be
4235
- removed after the upload to save memory (and replaced by an empty `bytes` object). Do not reuse the same
4236
- objects except to pass them to [`create_commit`]. If you don't want to remove the attached content from the
4237
- commit operation object, pass `free_memory=False`.
4238
-
4239
- </Tip>
4182
+ > [!WARNING]
4183
+ > Commit operations will be mutated during the process. In particular, the attached `path_or_fileobj` will be
4184
+ > removed after the upload to save memory (and replaced by an empty `bytes` object). Do not reuse the same
4185
+ > objects except to pass them to [`create_commit`]. If you don't want to remove the attached content from the
4186
+ > commit operation object, pass `free_memory=False`.
4240
4187
 
4241
4188
  Args:
4242
4189
  repo_id (`str`):
@@ -4342,6 +4289,10 @@ class HfApi:
4342
4289
  f"Skipped upload for {len(new_lfs_additions) - len(new_lfs_additions_to_upload)} LFS file(s) "
4343
4290
  "(ignored by gitignore file)."
4344
4291
  )
4292
+ # If no LFS files remain to upload, keep previous behavior and log explicitly
4293
+ if len(new_lfs_additions_to_upload) == 0:
4294
+ logger.debug("No LFS files to upload.")
4295
+ return
4345
4296
  # Prepare upload parameters
4346
4297
  upload_kwargs = {
4347
4298
  "additions": new_lfs_additions_to_upload,
@@ -4354,32 +4305,7 @@ class HfApi:
4354
4305
  # PR (i.e. `revision`).
4355
4306
  "revision": revision if not create_pr else None,
4356
4307
  }
4357
- # Upload files using Xet protocol if all of the following are true:
4358
- # - xet is enabled for the repo,
4359
- # - the files are provided as str or paths objects,
4360
- # - the library is installed.
4361
- # Otherwise, default back to LFS.
4362
- xet_enabled = self.repo_info(
4363
- repo_id=repo_id,
4364
- repo_type=repo_type,
4365
- revision=unquote(revision) if revision is not None else revision,
4366
- expand="xetEnabled",
4367
- token=token,
4368
- ).xet_enabled
4369
- has_buffered_io_data = any(
4370
- isinstance(addition.path_or_fileobj, io.BufferedIOBase) for addition in new_lfs_additions_to_upload
4371
- )
4372
- if xet_enabled and not has_buffered_io_data and is_xet_available():
4373
- logger.debug("Uploading files using Xet Storage..")
4374
- _upload_xet_files(**upload_kwargs, create_pr=create_pr) # type: ignore [arg-type]
4375
- else:
4376
- if xet_enabled and is_xet_available():
4377
- if has_buffered_io_data:
4378
- logger.warning(
4379
- "Uploading files as a binary IO buffer is not supported by Xet Storage. "
4380
- "Falling back to HTTP upload."
4381
- )
4382
- _upload_lfs_files(**upload_kwargs, num_threads=num_threads) # type: ignore [arg-type]
4308
+ _upload_files(**upload_kwargs, num_threads=num_threads, create_pr=create_pr) # type: ignore [arg-type]
4383
4309
  for addition in new_lfs_additions_to_upload:
4384
4310
  addition._is_uploaded = True
4385
4311
  if free_memory:
@@ -4489,30 +4415,24 @@ class HfApi:
4489
4415
  Instance of [`CommitInfo`] containing information about the newly created commit (commit hash, commit
4490
4416
  url, pr url, commit message,...). If `run_as_future=True` is passed, returns a Future object which will
4491
4417
  contain the result when executed.
4492
- <Tip>
4493
-
4494
- Raises the following errors:
4495
-
4496
- - [`HfHubHTTPError`]
4497
- if the HuggingFace API returned an error
4498
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
4499
- if some parameter value is invalid
4500
- - [`~utils.RepositoryNotFoundError`]
4501
- If the repository to download from cannot be found. This may be because it doesn't exist,
4502
- or because it is set to `private` and you do not have access.
4503
- - [`~utils.RevisionNotFoundError`]
4504
- If the revision to download from cannot be found.
4505
-
4506
- </Tip>
4507
-
4508
- <Tip warning={true}>
4509
-
4510
- `upload_file` assumes that the repo already exists on the Hub. If you get a
4511
- Client error 404, please make sure you are authenticated and that `repo_id` and
4512
- `repo_type` are set correctly. If repo does not exist, create it first using
4513
- [`~hf_api.create_repo`].
4514
-
4515
- </Tip>
4418
+ > [!TIP]
4419
+ > Raises the following errors:
4420
+ >
4421
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
4422
+ > if the HuggingFace API returned an error
4423
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
4424
+ > if some parameter value is invalid
4425
+ > - [`~utils.RepositoryNotFoundError`]
4426
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
4427
+ > or because it is set to `private` and you do not have access.
4428
+ > - [`~utils.RevisionNotFoundError`]
4429
+ > If the revision to download from cannot be found.
4430
+
4431
+ > [!WARNING]
4432
+ > `upload_file` assumes that the repo already exists on the Hub. If you get a
4433
+ > Client error 404, please make sure you are authenticated and that `repo_id` and
4434
+ > `repo_type` are set correctly. If repo does not exist, create it first using
4435
+ > [`~hf_api.create_repo`].
4516
4436
 
4517
4437
  Example:
4518
4438
 
@@ -4705,30 +4625,21 @@ class HfApi:
4705
4625
  url, pr url, commit message,...). If `run_as_future=True` is passed, returns a Future object which will
4706
4626
  contain the result when executed.
4707
4627
 
4708
- <Tip>
4628
+ > [!TIP]
4629
+ > Raises the following errors:
4630
+ >
4631
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
4632
+ > if the HuggingFace API returned an error
4633
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
4634
+ > if some parameter value is invalid
4709
4635
 
4710
- Raises the following errors:
4636
+ > [!WARNING]
4637
+ > `upload_folder` assumes that the repo already exists on the Hub. If you get a Client error 404, please make
4638
+ > sure you are authenticated and that `repo_id` and `repo_type` are set correctly. If repo does not exist, create
4639
+ > it first using [`~hf_api.create_repo`].
4711
4640
 
4712
- - [`HfHubHTTPError`]
4713
- if the HuggingFace API returned an error
4714
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
4715
- if some parameter value is invalid
4716
-
4717
- </Tip>
4718
-
4719
- <Tip warning={true}>
4720
-
4721
- `upload_folder` assumes that the repo already exists on the Hub. If you get a Client error 404, please make
4722
- sure you are authenticated and that `repo_id` and `repo_type` are set correctly. If repo does not exist, create
4723
- it first using [`~hf_api.create_repo`].
4724
-
4725
- </Tip>
4726
-
4727
- <Tip>
4728
-
4729
- When dealing with a large folder (thousands of files or hundreds of GB), we recommend using [`~hf_api.upload_large_folder`] instead.
4730
-
4731
- </Tip>
4641
+ > [!TIP]
4642
+ > When dealing with a large folder (thousands of files or hundreds of GB), we recommend using [`~hf_api.upload_large_folder`] instead.
4732
4643
 
4733
4644
  Example:
4734
4645
 
@@ -4871,23 +4782,20 @@ class HfApi:
4871
4782
  especially useful if the repo is updated / committed to concurrently.
4872
4783
 
4873
4784
 
4874
- <Tip>
4875
-
4876
- Raises the following errors:
4877
-
4878
- - [`HfHubHTTPError`]
4879
- if the HuggingFace API returned an error
4880
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
4881
- if some parameter value is invalid
4882
- - [`~utils.RepositoryNotFoundError`]
4883
- If the repository to download from cannot be found. This may be because it doesn't exist,
4884
- or because it is set to `private` and you do not have access.
4885
- - [`~utils.RevisionNotFoundError`]
4886
- If the revision to download from cannot be found.
4887
- - [`~utils.RemoteEntryNotFoundError`]
4888
- If the file to download cannot be found.
4889
-
4890
- </Tip>
4785
+ > [!TIP]
4786
+ > Raises the following errors:
4787
+ >
4788
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
4789
+ > if the HuggingFace API returned an error
4790
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
4791
+ > if some parameter value is invalid
4792
+ > - [`~utils.RepositoryNotFoundError`]
4793
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
4794
+ > or because it is set to `private` and you do not have access.
4795
+ > - [`~utils.RevisionNotFoundError`]
4796
+ > If the revision to download from cannot be found.
4797
+ > - [`~utils.EntryNotFoundError`]
4798
+ > If the file to download cannot be found.
4891
4799
 
4892
4800
  """
4893
4801
  commit_message = (
@@ -5104,25 +5012,19 @@ class HfApi:
5104
5012
  print_report_every (`int`, *optional*):
5105
5013
  Frequency at which the report is printed. Defaults to 60 seconds.
5106
5014
 
5107
- <Tip>
5015
+ > [!TIP]
5016
+ > A few things to keep in mind:
5017
+ > - Repository limits still apply: https://huggingface.co/docs/hub/repositories-recommendations
5018
+ > - Do not start several processes in parallel.
5019
+ > - You can interrupt and resume the process at any time.
5020
+ > - Do not upload the same folder to several repositories. If you need to do so, you must delete the local `.cache/.huggingface/` folder first.
5108
5021
 
5109
- A few things to keep in mind:
5110
- - Repository limits still apply: https://huggingface.co/docs/hub/repositories-recommendations
5111
- - Do not start several processes in parallel.
5112
- - You can interrupt and resume the process at any time.
5113
- - Do not upload the same folder to several repositories. If you need to do so, you must delete the local `.cache/.huggingface/` folder first.
5114
-
5115
- </Tip>
5116
-
5117
- <Tip warning={true}>
5118
-
5119
- While being much more robust to upload large folders, `upload_large_folder` is more limited than [`upload_folder`] feature-wise. In practice:
5120
- - you cannot set a custom `path_in_repo`. If you want to upload to a subfolder, you need to set the proper structure locally.
5121
- - you cannot set a custom `commit_message` and `commit_description` since multiple commits are created.
5122
- - you cannot delete from the repo while uploading. Please make a separate commit first.
5123
- - you cannot create a PR directly. Please create a PR first (from the UI or using [`create_pull_request`]) and then commit to it by passing `revision`.
5124
-
5125
- </Tip>
5022
+ > [!WARNING]
5023
+ > While being much more robust to upload large folders, `upload_large_folder` is more limited than [`upload_folder`] feature-wise. In practice:
5024
+ > - you cannot set a custom `path_in_repo`. If you want to upload to a subfolder, you need to set the proper structure locally.
5025
+ > - you cannot set a custom `commit_message` and `commit_description` since multiple commits are created.
5026
+ > - you cannot delete from the repo while uploading. Please make a separate commit first.
5027
+ > - you cannot create a PR directly. Please create a PR first (from the UI or using [`create_pull_request`]) and then commit to it by passing `revision`.
5126
5028
 
5127
5029
  **Technical details:**
5128
5030
 
@@ -5213,6 +5115,42 @@ class HfApi:
5213
5115
  endpoint=self.endpoint,
5214
5116
  )
5215
5117
 
5118
+ @overload
5119
+ def hf_hub_download(
5120
+ self,
5121
+ repo_id: str,
5122
+ filename: str,
5123
+ *,
5124
+ subfolder: Optional[str] = None,
5125
+ repo_type: Optional[str] = None,
5126
+ revision: Optional[str] = None,
5127
+ cache_dir: Union[str, Path, None] = None,
5128
+ local_dir: Union[str, Path, None] = None,
5129
+ force_download: bool = False,
5130
+ etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT,
5131
+ token: Union[bool, str, None] = None,
5132
+ local_files_only: bool = False,
5133
+ dry_run: Literal[False] = False,
5134
+ ) -> str: ...
5135
+
5136
+ @overload
5137
+ def hf_hub_download(
5138
+ self,
5139
+ repo_id: str,
5140
+ filename: str,
5141
+ *,
5142
+ subfolder: Optional[str] = None,
5143
+ repo_type: Optional[str] = None,
5144
+ revision: Optional[str] = None,
5145
+ cache_dir: Union[str, Path, None] = None,
5146
+ local_dir: Union[str, Path, None] = None,
5147
+ force_download: bool = False,
5148
+ etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT,
5149
+ token: Union[bool, str, None] = None,
5150
+ local_files_only: bool = False,
5151
+ dry_run: Literal[True],
5152
+ ) -> DryRunFileInfo: ...
5153
+
5216
5154
  @validate_hf_hub_args
5217
5155
  def hf_hub_download(
5218
5156
  self,
@@ -5228,7 +5166,8 @@ class HfApi:
5228
5166
  etag_timeout: float = constants.DEFAULT_ETAG_TIMEOUT,
5229
5167
  token: Union[bool, str, None] = None,
5230
5168
  local_files_only: bool = False,
5231
- ) -> str:
5169
+ dry_run: bool = False,
5170
+ ) -> Union[str, DryRunFileInfo]:
5232
5171
  """Download a given file if it's not already present in the local cache.
5233
5172
 
5234
5173
  The new cache file layout looks like this:
@@ -5295,9 +5234,14 @@ class HfApi:
5295
5234
  local_files_only (`bool`, *optional*, defaults to `False`):
5296
5235
  If `True`, avoid downloading the file and return the path to the
5297
5236
  local cached file if it exists.
5237
+ dry_run (`bool`, *optional*, defaults to `False`):
5238
+ If `True`, perform a dry run without actually downloading the file. Returns a
5239
+ [`DryRunFileInfo`] object containing information about what would be downloaded.
5298
5240
 
5299
5241
  Returns:
5300
- `str`: Local path of file or if networking is off, last version of file cached on disk.
5242
+ `str` or [`DryRunFileInfo`]:
5243
+ - If `dry_run=False`: Local path of file or if networking is off, last version of file cached on disk.
5244
+ - If `dry_run=True`: A [`DryRunFileInfo`] object containing download information.
5301
5245
 
5302
5246
  Raises:
5303
5247
  [`~utils.RepositoryNotFoundError`]
@@ -6129,19 +6073,16 @@ class HfApi:
6129
6073
 
6130
6074
  Returns: [`DiscussionWithDetails`]
6131
6075
 
6132
- <Tip>
6133
-
6134
- Raises the following errors:
6135
-
6136
- - [`HfHubHTTPError`]
6137
- if the HuggingFace API returned an error
6138
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6139
- if some parameter value is invalid
6140
- - [`~utils.RepositoryNotFoundError`]
6141
- If the repository to download from cannot be found. This may be because it doesn't exist,
6142
- or because it is set to `private` and you do not have access.
6143
-
6144
- </Tip>
6076
+ > [!TIP]
6077
+ > Raises the following errors:
6078
+ >
6079
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6080
+ > if the HuggingFace API returned an error
6081
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6082
+ > if some parameter value is invalid
6083
+ > - [`~utils.RepositoryNotFoundError`]
6084
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6085
+ > or because it is set to `private` and you do not have access.
6145
6086
  """
6146
6087
  if not isinstance(discussion_num, int) or discussion_num <= 0:
6147
6088
  raise ValueError("Invalid discussion_num, must be a positive integer")
@@ -6222,19 +6163,16 @@ class HfApi:
6222
6163
 
6223
6164
  Returns: [`DiscussionWithDetails`]
6224
6165
 
6225
- <Tip>
6226
-
6227
- Raises the following errors:
6228
-
6229
- - [`HfHubHTTPError`]
6230
- if the HuggingFace API returned an error
6231
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6232
- if some parameter value is invalid
6233
- - [`~utils.RepositoryNotFoundError`]
6234
- If the repository to download from cannot be found. This may be because it doesn't exist,
6235
- or because it is set to `private` and you do not have access.
6236
-
6237
- </Tip>"""
6166
+ > [!TIP]
6167
+ > Raises the following errors:
6168
+ >
6169
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6170
+ > if the HuggingFace API returned an error
6171
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6172
+ > if some parameter value is invalid
6173
+ > - [`~utils.RepositoryNotFoundError`]
6174
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6175
+ > or because it is set to `private` and you do not have access."""
6238
6176
  if repo_type not in constants.REPO_TYPES:
6239
6177
  raise ValueError(f"Invalid repo type, must be one of {constants.REPO_TYPES}")
6240
6178
  if repo_type is None:
@@ -6310,19 +6248,16 @@ class HfApi:
6310
6248
 
6311
6249
  Returns: [`DiscussionWithDetails`]
6312
6250
 
6313
- <Tip>
6314
-
6315
- Raises the following errors:
6316
-
6317
- - [`HfHubHTTPError`]
6318
- if the HuggingFace API returned an error
6319
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6320
- if some parameter value is invalid
6321
- - [`~utils.RepositoryNotFoundError`]
6322
- If the repository to download from cannot be found. This may be because it doesn't exist,
6323
- or because it is set to `private` and you do not have access.
6324
-
6325
- </Tip>"""
6251
+ > [!TIP]
6252
+ > Raises the following errors:
6253
+ >
6254
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6255
+ > if the HuggingFace API returned an error
6256
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6257
+ > if some parameter value is invalid
6258
+ > - [`~utils.RepositoryNotFoundError`]
6259
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6260
+ > or because it is set to `private` and you do not have access."""
6326
6261
  return self.create_discussion(
6327
6262
  repo_id=repo_id,
6328
6263
  title=title,
@@ -6413,19 +6348,16 @@ class HfApi:
6413
6348
 
6414
6349
  ```
6415
6350
 
6416
- <Tip>
6417
-
6418
- Raises the following errors:
6419
-
6420
- - [`HfHubHTTPError`]
6421
- if the HuggingFace API returned an error
6422
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6423
- if some parameter value is invalid
6424
- - [`~utils.RepositoryNotFoundError`]
6425
- If the repository to download from cannot be found. This may be because it doesn't exist,
6426
- or because it is set to `private` and you do not have access.
6427
-
6428
- </Tip>
6351
+ > [!TIP]
6352
+ > Raises the following errors:
6353
+ >
6354
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6355
+ > if the HuggingFace API returned an error
6356
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6357
+ > if some parameter value is invalid
6358
+ > - [`~utils.RepositoryNotFoundError`]
6359
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6360
+ > or because it is set to `private` and you do not have access.
6429
6361
  """
6430
6362
  resp = self._post_discussion_changes(
6431
6363
  repo_id=repo_id,
@@ -6483,19 +6415,16 @@ class HfApi:
6483
6415
 
6484
6416
  ```
6485
6417
 
6486
- <Tip>
6487
-
6488
- Raises the following errors:
6489
-
6490
- - [`HfHubHTTPError`]
6491
- if the HuggingFace API returned an error
6492
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6493
- if some parameter value is invalid
6494
- - [`~utils.RepositoryNotFoundError`]
6495
- If the repository to download from cannot be found. This may be because it doesn't exist,
6496
- or because it is set to `private` and you do not have access.
6497
-
6498
- </Tip>
6418
+ > [!TIP]
6419
+ > Raises the following errors:
6420
+ >
6421
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6422
+ > if the HuggingFace API returned an error
6423
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6424
+ > if some parameter value is invalid
6425
+ > - [`~utils.RepositoryNotFoundError`]
6426
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6427
+ > or because it is set to `private` and you do not have access.
6499
6428
  """
6500
6429
  resp = self._post_discussion_changes(
6501
6430
  repo_id=repo_id,
@@ -6556,19 +6485,16 @@ class HfApi:
6556
6485
 
6557
6486
  ```
6558
6487
 
6559
- <Tip>
6560
-
6561
- Raises the following errors:
6562
-
6563
- - [`HfHubHTTPError`]
6564
- if the HuggingFace API returned an error
6565
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6566
- if some parameter value is invalid
6567
- - [`~utils.RepositoryNotFoundError`]
6568
- If the repository to download from cannot be found. This may be because it doesn't exist,
6569
- or because it is set to `private` and you do not have access.
6570
-
6571
- </Tip>
6488
+ > [!TIP]
6489
+ > Raises the following errors:
6490
+ >
6491
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6492
+ > if the HuggingFace API returned an error
6493
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6494
+ > if some parameter value is invalid
6495
+ > - [`~utils.RepositoryNotFoundError`]
6496
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6497
+ > or because it is set to `private` and you do not have access.
6572
6498
  """
6573
6499
  if new_status not in ["open", "closed"]:
6574
6500
  raise ValueError("Invalid status, valid statuses are: 'open' and 'closed'")
@@ -6618,19 +6544,16 @@ class HfApi:
6618
6544
  Returns:
6619
6545
  [`DiscussionStatusChange`]: the status change event
6620
6546
 
6621
- <Tip>
6622
-
6623
- Raises the following errors:
6624
-
6625
- - [`HfHubHTTPError`]
6626
- if the HuggingFace API returned an error
6627
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6628
- if some parameter value is invalid
6629
- - [`~utils.RepositoryNotFoundError`]
6630
- If the repository to download from cannot be found. This may be because it doesn't exist,
6631
- or because it is set to `private` and you do not have access.
6632
-
6633
- </Tip>
6547
+ > [!TIP]
6548
+ > Raises the following errors:
6549
+ >
6550
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6551
+ > if the HuggingFace API returned an error
6552
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6553
+ > if some parameter value is invalid
6554
+ > - [`~utils.RepositoryNotFoundError`]
6555
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6556
+ > or because it is set to `private` and you do not have access.
6634
6557
  """
6635
6558
  self._post_discussion_changes(
6636
6559
  repo_id=repo_id,
@@ -6677,19 +6600,16 @@ class HfApi:
6677
6600
  Returns:
6678
6601
  [`DiscussionComment`]: the edited comment
6679
6602
 
6680
- <Tip>
6681
-
6682
- Raises the following errors:
6683
-
6684
- - [`HfHubHTTPError`]
6685
- if the HuggingFace API returned an error
6686
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6687
- if some parameter value is invalid
6688
- - [`~utils.RepositoryNotFoundError`]
6689
- If the repository to download from cannot be found. This may be because it doesn't exist,
6690
- or because it is set to `private` and you do not have access.
6691
-
6692
- </Tip>
6603
+ > [!TIP]
6604
+ > Raises the following errors:
6605
+ >
6606
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6607
+ > if the HuggingFace API returned an error
6608
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6609
+ > if some parameter value is invalid
6610
+ > - [`~utils.RepositoryNotFoundError`]
6611
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6612
+ > or because it is set to `private` and you do not have access.
6693
6613
  """
6694
6614
  resp = self._post_discussion_changes(
6695
6615
  repo_id=repo_id,
@@ -6713,9 +6633,8 @@ class HfApi:
6713
6633
  ) -> DiscussionComment:
6714
6634
  """Hides a comment on a Discussion / Pull Request.
6715
6635
 
6716
- <Tip warning={true}>
6717
- Hidden comments' content cannot be retrieved anymore. Hiding a comment is irreversible.
6718
- </Tip>
6636
+ > [!WARNING]
6637
+ > Hidden comments' content cannot be retrieved anymore. Hiding a comment is irreversible.
6719
6638
 
6720
6639
  Args:
6721
6640
  repo_id (`str`):
@@ -6738,19 +6657,16 @@ class HfApi:
6738
6657
  Returns:
6739
6658
  [`DiscussionComment`]: the hidden comment
6740
6659
 
6741
- <Tip>
6742
-
6743
- Raises the following errors:
6744
-
6745
- - [`HfHubHTTPError`]
6746
- if the HuggingFace API returned an error
6747
- - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6748
- if some parameter value is invalid
6749
- - [`~utils.RepositoryNotFoundError`]
6750
- If the repository to download from cannot be found. This may be because it doesn't exist,
6751
- or because it is set to `private` and you do not have access.
6752
-
6753
- </Tip>
6660
+ > [!TIP]
6661
+ > Raises the following errors:
6662
+ >
6663
+ > - [`HTTPError`](https://requests.readthedocs.io/en/latest/api/#requests.HTTPError)
6664
+ > if the HuggingFace API returned an error
6665
+ > - [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
6666
+ > if some parameter value is invalid
6667
+ > - [`~utils.RepositoryNotFoundError`]
6668
+ > If the repository to download from cannot be found. This may be because it doesn't exist,
6669
+ > or because it is set to `private` and you do not have access.
6754
6670
  """
6755
6671
  warnings.warn(
6756
6672
  "Hidden comments' content cannot be retrieved anymore. Hiding a comment is irreversible.",
@@ -6974,11 +6890,8 @@ class HfApi:
6974
6890
  Returns:
6975
6891
  [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware.
6976
6892
 
6977
- <Tip>
6978
-
6979
- It is also possible to request hardware directly when creating the Space repo! See [`create_repo`] for details.
6980
-
6981
- </Tip>
6893
+ > [!TIP]
6894
+ > It is also possible to request hardware directly when creating the Space repo! See [`create_repo`] for details.
6982
6895
  """
6983
6896
  if sleep_time is not None and hardware == SpaceHardware.CPU_BASIC:
6984
6897
  warnings.warn(
@@ -7025,11 +6938,8 @@ class HfApi:
7025
6938
  Returns:
7026
6939
  [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware.
7027
6940
 
7028
- <Tip>
7029
-
7030
- It is also possible to set a custom sleep time when requesting hardware with [`request_space_hardware`].
7031
-
7032
- </Tip>
6941
+ > [!TIP]
6942
+ > It is also possible to set a custom sleep time when requesting hardware with [`request_space_hardware`].
7033
6943
  """
7034
6944
  r = get_session().post(
7035
6945
  f"{self.endpoint}/api/spaces/{repo_id}/sleeptime",
@@ -7275,12 +7185,9 @@ class HfApi:
7275
7185
  Returns:
7276
7186
  [`SpaceRuntime`]: Runtime information about a Space including Space stage and hardware.
7277
7187
 
7278
- <Tip>
7279
-
7280
- It is not possible to decrease persistent storage after its granted. To do so, you must delete it
7281
- via [`delete_space_storage`].
7282
-
7283
- </Tip>
7188
+ > [!TIP]
7189
+ > It is not possible to decrease persistent storage after its granted. To do so, you must delete it
7190
+ > via [`delete_space_storage`].
7284
7191
  """
7285
7192
  payload: dict[str, SpaceStorage] = {"tier": storage}
7286
7193
  r = get_session().post(
@@ -7644,12 +7551,9 @@ class HfApi:
7644
7551
  Returns:
7645
7552
  [`InferenceEndpoint`]: information about the new Inference Endpoint.
7646
7553
 
7647
- <Tip warning={true}>
7648
-
7649
- `create_inference_endpoint_from_catalog` is experimental. Its API is subject to change in the future. Please provide feedback
7650
- if you have any suggestions or requests.
7651
-
7652
- </Tip>
7554
+ > [!WARNING]
7555
+ > `create_inference_endpoint_from_catalog` is experimental. Its API is subject to change in the future. Please provide feedback
7556
+ > if you have any suggestions or requests.
7653
7557
  """
7654
7558
  token = token or self.token or get_token()
7655
7559
  payload: dict = {
@@ -7686,13 +7590,10 @@ class HfApi:
7686
7590
  https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
7687
7591
 
7688
7592
  Returns:
7689
- list[`str`]: A list of model IDs available in the catalog.
7690
- <Tip warning={true}>
7691
-
7692
- `list_inference_catalog` is experimental. Its API is subject to change in the future. Please provide feedback
7693
- if you have any suggestions or requests.
7694
-
7695
- </Tip>
7593
+ List[`str`]: A list of model IDs available in the catalog.
7594
+ > [!WARNING]
7595
+ > `list_inference_catalog` is experimental. Its API is subject to change in the future. Please provide feedback
7596
+ > if you have any suggestions or requests.
7696
7597
  """
7697
7598
  response = get_session().get(
7698
7599
  f"{constants.INFERENCE_CATALOG_ENDPOINT}/repo-list",
@@ -8055,12 +7956,9 @@ class HfApi:
8055
7956
  ) -> Iterable[Collection]:
8056
7957
  """List collections on the Huggingface Hub, given some filters.
8057
7958
 
8058
- <Tip warning={true}>
8059
-
8060
- When listing collections, the item list per collection is truncated to 4 items maximum. To retrieve all items
8061
- from a collection, you must use [`get_collection`].
8062
-
8063
- </Tip>
7959
+ > [!WARNING]
7960
+ > When listing collections, the item list per collection is truncated to 4 items maximum. To retrieve all items
7961
+ > from a collection, you must use [`get_collection`].
8064
7962
 
8065
7963
  Args:
8066
7964
  owner (`list[str]` or `str`, *optional*):
@@ -8300,11 +8198,8 @@ class HfApi:
8300
8198
  >>> collection = delete_collection("username/useless-collection-64f9a55bb3115b4f513ec026", missing_ok=True)
8301
8199
  ```
8302
8200
 
8303
- <Tip warning={true}>
8304
-
8305
- This is a non-revertible action. A deleted collection cannot be restored.
8306
-
8307
- </Tip>
8201
+ > [!WARNING]
8202
+ > This is a non-revertible action. A deleted collection cannot be restored.
8308
8203
  """
8309
8204
  r = get_session().delete(
8310
8205
  f"{self.endpoint}/api/collections/{collection_slug}", headers=self._build_hf_headers(token=token)
@@ -8967,6 +8862,7 @@ class HfApi:
8967
8862
  >>> print(webhook)
8968
8863
  WebhookInfo(
8969
8864
  id="654bbbc16f2ec14d77f109cc",
8865
+ job=None,
8970
8866
  watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
8971
8867
  url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
8972
8868
  secret="my-secret",
@@ -8986,7 +8882,8 @@ class HfApi:
8986
8882
 
8987
8883
  webhook = WebhookInfo(
8988
8884
  id=webhook_data["id"],
8989
- url=webhook_data["url"],
8885
+ url=webhook_data.get("url"),
8886
+ job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None,
8990
8887
  watched=watched_items,
8991
8888
  domains=webhook_data["domains"],
8992
8889
  secret=webhook_data.get("secret"),
@@ -9036,7 +8933,8 @@ class HfApi:
9036
8933
  return [
9037
8934
  WebhookInfo(
9038
8935
  id=webhook["id"],
9039
- url=webhook["url"],
8936
+ url=webhook.get("url"),
8937
+ job=JobSpec(**webhook["job"]) if webhook.get("job") else None,
9040
8938
  watched=[WebhookWatchedItem(type=item["type"], name=item["name"]) for item in webhook["watched"]],
9041
8939
  domains=webhook["domains"],
9042
8940
  secret=webhook.get("secret"),
@@ -9049,7 +8947,8 @@ class HfApi:
9049
8947
  def create_webhook(
9050
8948
  self,
9051
8949
  *,
9052
- url: str,
8950
+ url: Optional[str] = None,
8951
+ job_id: Optional[str] = None,
9053
8952
  watched: list[Union[dict, WebhookWatchedItem]],
9054
8953
  domains: Optional[list[constants.WEBHOOK_DOMAIN_T]] = None,
9055
8954
  secret: Optional[str] = None,
@@ -9057,9 +8956,15 @@ class HfApi:
9057
8956
  ) -> WebhookInfo:
9058
8957
  """Create a new webhook.
9059
8958
 
8959
+ The webhook can either send a payload to a URL, or trigger a Job to run on Hugging Face infrastructure.
8960
+ This function should be called with one of `url` or `job_id`, but not both.
8961
+
9060
8962
  Args:
9061
8963
  url (`str`):
9062
8964
  URL to send the payload to.
8965
+ job_id (`str`):
8966
+ ID of the source Job to trigger with the webhook payload in the environment variable WEBHOOK_PAYLOAD.
8967
+ Additional environment variables are available for convenience: WEBHOOK_REPO_ID, WEBHOOK_REPO_TYPE and WEBHOOK_SECRET.
9063
8968
  watched (`list[WebhookWatchedItem]`):
9064
8969
  List of [`WebhookWatchedItem`] to be watched by the webhook. It can be users, orgs, models, datasets or spaces.
9065
8970
  Watched items can also be provided as plain dictionaries.
@@ -9077,6 +8982,8 @@ class HfApi:
9077
8982
  Info about the newly created webhook.
9078
8983
 
9079
8984
  Example:
8985
+
8986
+ Create a webhook that sends a payload to a URL
9080
8987
  ```python
9081
8988
  >>> from huggingface_hub import create_webhook
9082
8989
  >>> payload = create_webhook(
@@ -9089,6 +8996,43 @@ class HfApi:
9089
8996
  WebhookInfo(
9090
8997
  id="654bbbc16f2ec14d77f109cc",
9091
8998
  url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
8999
+ job=None,
9000
+ watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
9001
+ domains=["repo", "discussion"],
9002
+ secret="my-secret",
9003
+ disabled=False,
9004
+ )
9005
+ ```
9006
+
9007
+ Run a Job and then create a webhook that triggers this Job
9008
+ ```python
9009
+ >>> from huggingface_hub import create_webhook, run_job
9010
+ >>> job = run_job(
9011
+ ... image="ubuntu",
9012
+ ... command=["bash", "-c", r"echo An event occured in $WEBHOOK_REPO_ID: $WEBHOOK_PAYLOAD"],
9013
+ ... )
9014
+ >>> payload = create_webhook(
9015
+ ... watched=[{"type": "user", "name": "julien-c"}, {"type": "org", "name": "HuggingFaceH4"}],
9016
+ ... job_id=job.id,
9017
+ ... domains=["repo", "discussion"],
9018
+ ... secret="my-secret",
9019
+ ... )
9020
+ >>> print(payload)
9021
+ WebhookInfo(
9022
+ id="654bbbc16f2ec14d77f109cc",
9023
+ url=None,
9024
+ job=JobSpec(
9025
+ docker_image='ubuntu',
9026
+ space_id=None,
9027
+ command=['bash', '-c', 'echo An event occured in $WEBHOOK_REPO_ID: $WEBHOOK_PAYLOAD'],
9028
+ arguments=[],
9029
+ environment={},
9030
+ secrets=[],
9031
+ flavor='cpu-basic',
9032
+ timeout=None,
9033
+ tags=None,
9034
+ arch=None
9035
+ ),
9092
9036
  watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
9093
9037
  domains=["repo", "discussion"],
9094
9038
  secret="my-secret",
@@ -9098,9 +9042,19 @@ class HfApi:
9098
9042
  """
9099
9043
  watched_dicts = [asdict(item) if isinstance(item, WebhookWatchedItem) else item for item in watched]
9100
9044
 
9045
+ post_webhooks_json = {"watched": watched_dicts, "domains": domains, "secret": secret}
9046
+ if url is not None and job_id is not None:
9047
+ raise ValueError("Set `url` or `job_id` but not both.")
9048
+ elif url is not None:
9049
+ post_webhooks_json["url"] = url
9050
+ elif job_id is not None:
9051
+ post_webhooks_json["jobSourceId"] = job_id
9052
+ else:
9053
+ raise ValueError("Missing argument for webhook: `url` or `job_id`.")
9054
+
9101
9055
  response = get_session().post(
9102
9056
  f"{constants.ENDPOINT}/api/settings/webhooks",
9103
- json={"watched": watched_dicts, "url": url, "domains": domains, "secret": secret},
9057
+ json=post_webhooks_json,
9104
9058
  headers=self._build_hf_headers(token=token),
9105
9059
  )
9106
9060
  hf_raise_for_status(response)
@@ -9109,7 +9063,8 @@ class HfApi:
9109
9063
 
9110
9064
  webhook = WebhookInfo(
9111
9065
  id=webhook_data["id"],
9112
- url=webhook_data["url"],
9066
+ url=webhook_data.get("url"),
9067
+ job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None,
9113
9068
  watched=watched_items,
9114
9069
  domains=webhook_data["domains"],
9115
9070
  secret=webhook_data.get("secret"),
@@ -9165,6 +9120,7 @@ class HfApi:
9165
9120
  >>> print(updated_payload)
9166
9121
  WebhookInfo(
9167
9122
  id="654bbbc16f2ec14d77f109cc",
9123
+ job=None,
9168
9124
  url="https://new.webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
9169
9125
  watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
9170
9126
  domains=["repo"],
@@ -9188,7 +9144,8 @@ class HfApi:
9188
9144
 
9189
9145
  webhook = WebhookInfo(
9190
9146
  id=webhook_data["id"],
9191
- url=webhook_data["url"],
9147
+ url=webhook_data.get("url"),
9148
+ job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None,
9192
9149
  watched=watched_items,
9193
9150
  domains=webhook_data["domains"],
9194
9151
  secret=webhook_data.get("secret"),
@@ -9220,6 +9177,7 @@ class HfApi:
9220
9177
  >>> enabled_webhook
9221
9178
  WebhookInfo(
9222
9179
  id="654bbbc16f2ec14d77f109cc",
9180
+ job=None,
9223
9181
  url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
9224
9182
  watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
9225
9183
  domains=["repo", "discussion"],
@@ -9239,7 +9197,8 @@ class HfApi:
9239
9197
 
9240
9198
  webhook = WebhookInfo(
9241
9199
  id=webhook_data["id"],
9242
- url=webhook_data["url"],
9200
+ url=webhook_data.get("url"),
9201
+ job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None,
9243
9202
  watched=watched_items,
9244
9203
  domains=webhook_data["domains"],
9245
9204
  secret=webhook_data.get("secret"),
@@ -9272,6 +9231,7 @@ class HfApi:
9272
9231
  WebhookInfo(
9273
9232
  id="654bbbc16f2ec14d77f109cc",
9274
9233
  url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
9234
+ jon=None,
9275
9235
  watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
9276
9236
  domains=["repo", "discussion"],
9277
9237
  secret="my-secret",
@@ -9290,7 +9250,8 @@ class HfApi:
9290
9250
 
9291
9251
  webhook = WebhookInfo(
9292
9252
  id=webhook_data["id"],
9293
- url=webhook_data["url"],
9253
+ url=webhook_data.get("url"),
9254
+ job=JobSpec(**webhook_data["job"]) if webhook_data.get("job") else None,
9294
9255
  watched=watched_items,
9295
9256
  domains=webhook_data["domains"],
9296
9257
  secret=webhook_data.get("secret"),