hfutils 0.3.9__tar.gz → 0.4.1__tar.gz

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.
Files changed (75) hide show
  1. {hfutils-0.3.9/hfutils.egg-info → hfutils-0.4.1}/PKG-INFO +2 -1
  2. {hfutils-0.3.9 → hfutils-0.4.1}/README.md +1 -0
  3. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/config/meta.py +1 -1
  4. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/cli.py +4 -0
  5. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/download.py +6 -2
  6. hfutils-0.4.1/hfutils/entry/ils.py +288 -0
  7. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/ls.py +8 -61
  8. hfutils-0.4.1/hfutils/entry/tree.py +239 -0
  9. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/__init__.py +3 -0
  10. hfutils-0.4.1/hfutils/utils/archive.py +157 -0
  11. hfutils-0.4.1/hfutils/utils/data.py +87 -0
  12. hfutils-0.4.1/hfutils/utils/model.py +140 -0
  13. hfutils-0.4.1/hfutils/utils/type_.py +121 -0
  14. {hfutils-0.3.9 → hfutils-0.4.1/hfutils.egg-info}/PKG-INFO +2 -1
  15. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils.egg-info/SOURCES.txt +6 -0
  16. {hfutils-0.3.9 → hfutils-0.4.1}/LICENSE +0 -0
  17. {hfutils-0.3.9 → hfutils-0.4.1}/MANIFEST.in +0 -0
  18. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/__init__.py +0 -0
  19. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/__main__.py +0 -0
  20. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/archive/__init__.py +0 -0
  21. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/archive/base.py +0 -0
  22. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/archive/rar.py +0 -0
  23. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/archive/sevenz.py +0 -0
  24. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/archive/tar.py +0 -0
  25. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/archive/zip.py +0 -0
  26. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/cache/__init__.py +0 -0
  27. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/cache/delete.py +0 -0
  28. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/config/__init__.py +0 -0
  29. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/__init__.py +0 -0
  30. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/base.py +0 -0
  31. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/clone.py +0 -0
  32. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/dispatch.py +0 -0
  33. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/index.py +0 -0
  34. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/ls_repo.py +0 -0
  35. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/rollback.py +0 -0
  36. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/upload.py +0 -0
  37. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/entry/whoami.py +0 -0
  38. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/index/__init__.py +0 -0
  39. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/index/fetch.py +0 -0
  40. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/index/hash.py +0 -0
  41. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/index/local_fetch.py +0 -0
  42. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/index/make.py +0 -0
  43. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/index/validate.py +0 -0
  44. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/operate/__init__.py +0 -0
  45. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/operate/base.py +0 -0
  46. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/operate/download.py +0 -0
  47. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/operate/upload.py +0 -0
  48. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/operate/validate.py +0 -0
  49. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/repository/__init__.py +0 -0
  50. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/repository/base.py +0 -0
  51. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/repository/clone.py +0 -0
  52. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/repository/rollback.py +0 -0
  53. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/binary.py +0 -0
  54. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/download.py +0 -0
  55. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/irregular_repo.json +0 -0
  56. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/logging.py +0 -0
  57. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/number.py +0 -0
  58. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/path.py +0 -0
  59. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/session.py +0 -0
  60. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/temp.py +0 -0
  61. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/tqdm_.py +0 -0
  62. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils/utils/walk.py +0 -0
  63. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils.egg-info/dependency_links.txt +0 -0
  64. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils.egg-info/entry_points.txt +0 -0
  65. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils.egg-info/requires.txt +0 -0
  66. {hfutils-0.3.9 → hfutils-0.4.1}/hfutils.egg-info/top_level.txt +0 -0
  67. {hfutils-0.3.9 → hfutils-0.4.1}/requirements-7z.txt +0 -0
  68. {hfutils-0.3.9 → hfutils-0.4.1}/requirements-build.txt +0 -0
  69. {hfutils-0.3.9 → hfutils-0.4.1}/requirements-doc.txt +0 -0
  70. {hfutils-0.3.9 → hfutils-0.4.1}/requirements-rar.txt +0 -0
  71. {hfutils-0.3.9 → hfutils-0.4.1}/requirements-test.txt +0 -0
  72. {hfutils-0.3.9 → hfutils-0.4.1}/requirements-transfer.txt +0 -0
  73. {hfutils-0.3.9 → hfutils-0.4.1}/requirements.txt +0 -0
  74. {hfutils-0.3.9 → hfutils-0.4.1}/setup.cfg +0 -0
  75. {hfutils-0.3.9 → hfutils-0.4.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hfutils
3
- Version: 0.3.9
3
+ Version: 0.4.1
4
4
  Summary: Useful utilities for huggingface
5
5
  Home-page: https://github.com/deepghs/hfutils
6
6
  Author: narugo1992
@@ -88,6 +88,7 @@ Requires-Dist: py7zr; extra == "7z"
88
88
  [![Package Release](https://github.com/deepghs/hfutils/workflows/Package%20Release/badge.svg)](https://github.com/deepghs/hfutils/actions?query=workflow%3A%22Package+Release%22)
89
89
  [![codecov](https://codecov.io/gh/deepghs/hfutils/branch/main/graph/badge.svg?token=XJVDP4EFAT)](https://codecov.io/gh/deepghs/hfutils)
90
90
 
91
+ [![Discord](https://img.shields.io/discord/1157587327879745558?style=social&logo=discord&link=https%3A%2F%2Fdiscord.gg%2FTwdHJ42N72)](https://discord.gg/TwdHJ42N72)
91
92
  ![GitHub Org's stars](https://img.shields.io/github/stars/deepghs)
92
93
  [![GitHub stars](https://img.shields.io/github/stars/deepghs/hfutils)](https://github.com/deepghs/hfutils/stargazers)
93
94
  [![GitHub forks](https://img.shields.io/github/forks/deepghs/hfutils)](https://github.com/deepghs/hfutils/network)
@@ -9,6 +9,7 @@
9
9
  [![Package Release](https://github.com/deepghs/hfutils/workflows/Package%20Release/badge.svg)](https://github.com/deepghs/hfutils/actions?query=workflow%3A%22Package+Release%22)
10
10
  [![codecov](https://codecov.io/gh/deepghs/hfutils/branch/main/graph/badge.svg?token=XJVDP4EFAT)](https://codecov.io/gh/deepghs/hfutils)
11
11
 
12
+ [![Discord](https://img.shields.io/discord/1157587327879745558?style=social&logo=discord&link=https%3A%2F%2Fdiscord.gg%2FTwdHJ42N72)](https://discord.gg/TwdHJ42N72)
12
13
  ![GitHub Org's stars](https://img.shields.io/github/stars/deepghs)
13
14
  [![GitHub stars](https://img.shields.io/github/stars/deepghs/hfutils)](https://github.com/deepghs/hfutils/stargazers)
14
15
  [![GitHub forks](https://img.shields.io/github/forks/deepghs/hfutils)](https://github.com/deepghs/hfutils/network)
@@ -7,7 +7,7 @@ Overview:
7
7
  __TITLE__ = 'hfutils'
8
8
 
9
9
  #: Version of this project.
10
- __VERSION__ = '0.3.9'
10
+ __VERSION__ = '0.4.1'
11
11
 
12
12
  #: Short description of the project, will be included in ``setup.py``.
13
13
  __DESCRIPTION__ = 'Useful utilities for huggingface'
@@ -1,10 +1,12 @@
1
1
  from .clone import _add_clone_subcommand
2
2
  from .dispatch import hfutilcli
3
3
  from .download import _add_download_subcommand
4
+ from .ils import _add_ils_subcommand
4
5
  from .index import _add_index_subcommand
5
6
  from .ls import _add_ls_subcommand
6
7
  from .ls_repo import _add_ls_repo_subcommand
7
8
  from .rollback import _add_rollback_subcommand
9
+ from .tree import _add_tree_subcommand
8
10
  from .upload import _add_upload_subcommand
9
11
  from .whoami import _add_whoami_subcommand
10
12
 
@@ -17,6 +19,8 @@ _DECORATORS = [
17
19
  _add_index_subcommand,
18
20
  _add_rollback_subcommand,
19
21
  _add_clone_subcommand,
22
+ _add_tree_subcommand,
23
+ _add_ils_subcommand,
20
24
  ]
21
25
 
22
26
  cli = hfutilcli
@@ -7,7 +7,7 @@ from huggingface_hub import configure_http_backend
7
7
 
8
8
  from .base import CONTEXT_SETTINGS, command_wrap, ClickErrorException
9
9
  from ..operate import download_file_to_file, download_archive_as_directory, download_directory_as_directory
10
- from ..operate.base import REPO_TYPES, RepoTypeTyping
10
+ from ..operate.base import REPO_TYPES, RepoTypeTyping, _IGNORE_PATTERN_UNSET
11
11
  from ..utils import get_requests_session
12
12
 
13
13
 
@@ -55,12 +55,15 @@ def _add_download_subcommand(cli: click.Group) -> click.Group:
55
55
  help='Just check the file size when validating the downloaded files.', show_default=True)
56
56
  @click.option('--tmpdir', 'tmpdir', type=str, default=None,
57
57
  help='Use custom temporary Directory.', show_default=True)
58
+ @click.option('--all', 'show_all', is_flag=True, type=bool, default=False,
59
+ help='Show all files, including hidden files.', show_default=True)
58
60
  @command_wrap()
59
61
  def download(
60
62
  repo_id: str, repo_type: RepoTypeTyping,
61
63
  file_in_repo: Optional[str], archive_in_repo: Optional[str], dir_in_repo: Optional[str],
62
64
  output_path: str, revision: str, max_workers: int,
63
- password: Optional[str], wildcard: Optional[str], soft_mode_when_check: bool, tmpdir: Optional[str]
65
+ password: Optional[str], wildcard: Optional[str], soft_mode_when_check: bool, tmpdir: Optional[str],
66
+ show_all: bool = False,
64
67
  ):
65
68
  """
66
69
  Download data from HuggingFace repositories.
@@ -135,6 +138,7 @@ def _add_download_subcommand(cli: click.Group) -> click.Group:
135
138
  silent=False,
136
139
  max_workers=max_workers,
137
140
  soft_mode_when_check=soft_mode_when_check,
141
+ ignore_patterns=_IGNORE_PATTERN_UNSET if not show_all else [],
138
142
  )
139
143
 
140
144
  else:
@@ -0,0 +1,288 @@
1
+ """
2
+ This module provides functionality for listing files from a HuggingFace repository's index tar file.
3
+
4
+ It includes a command-line interface (CLI) for interacting with HuggingFace repositories,
5
+ specifically for listing and displaying information about files within a repository's
6
+ index tar file. The module offers various options for sorting, filtering, and displaying
7
+ detailed information about the files and the repository itself.
8
+
9
+ Key features:
10
+
11
+ 1. List files from a HuggingFace repository's index tar file
12
+ 2. Display detailed file information
13
+ 3. Show repository and index file statistics
14
+ 4. Sort files by different criteria (offset, name, size)
15
+ 5. Validate the index file's status (up-to-date or outdated)
16
+
17
+ This module is part of a larger system for interacting with HuggingFace repositories
18
+ and provides a user-friendly interface for exploring the contents of index tar files.
19
+ """
20
+
21
+ import os.path
22
+ import statistics
23
+ import warnings
24
+ from typing import Optional, Literal
25
+
26
+ import click
27
+ from hbutils.scale import size_to_bytes_str
28
+ from hbutils.string import plural_word, titleize
29
+ from huggingface_hub import configure_http_backend
30
+
31
+ from .base import CONTEXT_SETTINGS
32
+ from ..index import hf_tar_get_index, hf_tar_validate
33
+ from ..operate.base import REPO_TYPES
34
+ from ..utils import get_requests_session, get_file_type, FileItemType
35
+ from ..utils.path import RepoTypeTyping, hf_normpath
36
+
37
+ _FT_NAME_MAP = {
38
+ FileItemType.IMAGE: 'image',
39
+ FileItemType.ARCHIVE: 'archive/compressed',
40
+ FileItemType.MODEL: 'model',
41
+ FileItemType.DATA: 'data',
42
+ FileItemType.FILE: 'other',
43
+ }
44
+
45
+
46
+ def _add_ils_subcommand(cli: click.Group) -> click.Group:
47
+ """
48
+ Add the 'ils' subcommand to the given click Group.
49
+
50
+ This function defines and adds the 'ils' (Index List) subcommand to the provided
51
+ click Group. The 'ils' command allows users to list files from a HuggingFace
52
+ repository's index tar file and display various information about the repository
53
+ and its contents.
54
+
55
+ :param cli: The click Group to which the 'ils' subcommand will be added.
56
+ :type cli: click.Group
57
+
58
+ :return: The modified click Group with the 'ils' subcommand added.
59
+ :rtype: click.Group
60
+
61
+ Usage:
62
+ This function is typically called when setting up the CLI for the application.
63
+ It adds the 'ils' command with various options for customizing the output.
64
+
65
+ Example:
66
+ cli = click.Group()
67
+ cli = _add_ils_subcommand(cli)
68
+ """
69
+
70
+ @cli.command('ils', help='List files from HuggingFace repository\'s index tar file.\n\n'
71
+ 'Set environment $HF_TOKEN to use your own access token.',
72
+ context_settings=CONTEXT_SETTINGS)
73
+ @click.option('-r', '--repository', 'repo_id', type=str, required=True,
74
+ help='Repository to download from.')
75
+ @click.option('--idx_repository', 'idx_repo_id', type=str, default=None,
76
+ help='Index repository to download from.', show_default=True)
77
+ @click.option('-t', '--type', 'repo_type', type=click.Choice(REPO_TYPES), default='dataset',
78
+ help='Type of the HuggingFace repository.', show_default=True)
79
+ @click.option('-R', '--revision', 'revision', type=str, default='main',
80
+ help='Revision of repository.', show_default=True)
81
+ @click.option('-a', '--archive_file', 'archive_file', type=str, required=True,
82
+ help='Archive file in repository.', show_default=True)
83
+ @click.option('-i', '--idx_file', 'idx_file', type=str, default=None,
84
+ help='', show_default=True)
85
+ @click.option('-l', '--list', 'show_detailed', is_flag=True, type=bool, default=False,
86
+ help='Show detailed file information.', show_default=True)
87
+ @click.option('-s', '--sort_by', 'sort_by', type=click.Choice(['offset', 'name', 'size']), default='offset',
88
+ help='Sort order of files.', show_default=True)
89
+ @click.option('-o', '--order_by', 'order_by', type=click.Choice(['asc', 'desc']), default='asc',
90
+ help='Order of the mentioned sorting.', show_default=True)
91
+ @click.option('-I', '--information', 'show_information', type=bool, is_flag=True, default=False,
92
+ help='Show information of index file.', show_default=True)
93
+ def ls(repo_id: str, idx_repo_id: Optional[str], repo_type: RepoTypeTyping, revision: str,
94
+ show_detailed: bool, show_information: bool,
95
+ sort_by: Literal['offset', 'name', 'size'], order_by: Literal['asc', 'desc'],
96
+ archive_file: str, idx_file: Optional[str] = None):
97
+ """
98
+ List files from a HuggingFace repository's index tar file.
99
+
100
+ This function retrieves and displays information about files in a HuggingFace
101
+ repository's index tar file. It can show detailed file information, repository
102
+ statistics, and allows for sorting and filtering of the file list.
103
+
104
+ :param repo_id: The ID of the HuggingFace repository.
105
+ :type repo_id: str
106
+ :param idx_repo_id: The ID of the index repository (if different from repo_id).
107
+ :type idx_repo_id: Optional[str]
108
+ :param repo_type: The type of the HuggingFace repository (e.g., 'dataset', 'model').
109
+ :type repo_type: RepoTypeTyping
110
+ :param revision: The revision of the repository to use.
111
+ :type revision: str
112
+ :param show_detailed: Flag to show detailed file information.
113
+ :type show_detailed: bool
114
+ :param show_information: Flag to show general information about the index file.
115
+ :type show_information: bool
116
+ :param sort_by: Criterion to sort the files by ('offset', 'name', or 'size').
117
+ :type sort_by: Literal['offset', 'name', 'size']
118
+ :param order_by: Order of sorting ('asc' or 'desc').
119
+ :type order_by: Literal['asc', 'desc']
120
+ :param archive_file: The name of the archive file in the repository.
121
+ :type archive_file: str
122
+ :param idx_file: The name of the index file (if different from default).
123
+ :type idx_file: Optional[str]
124
+
125
+ :return: None
126
+
127
+ This function performs the following steps:
128
+
129
+ 1. Configures the HTTP backend for HuggingFace Hub.
130
+ 2. Retrieves the index information for the specified repository and archive.
131
+ 3. If show_information is True, displays general statistics about the repository and files.
132
+ 4. If not showing information, lists the files according to the specified sorting and filtering options.
133
+
134
+ The function uses click styles to format the output for better readability in the terminal.
135
+ """
136
+ configure_http_backend(get_requests_session)
137
+
138
+ idx_info = hf_tar_get_index(
139
+ repo_id=repo_id,
140
+ repo_type=repo_type,
141
+ revision=revision,
142
+ archive_in_repo=archive_file,
143
+
144
+ idx_repo_id=idx_repo_id or repo_id,
145
+ idx_repo_type=repo_type,
146
+ idx_revision=revision,
147
+ idx_file_in_repo=idx_file,
148
+ )
149
+ if show_information:
150
+ print('Repo ID: ' + click.style(repo_id, underline=True, fg='blue'))
151
+ if idx_repo_id:
152
+ print('Index Repo ID: ' + click.style(idx_repo_id, underline=True, fg='blue'))
153
+ print('Repo Type: ' + click.style(repo_type, underline=True, fg='blue'))
154
+ print('Revision: ' + click.style(revision, underline=True, fg='blue'))
155
+ print('Archive File: ' + click.style(archive_file, underline=True, fg='blue'))
156
+ if idx_file:
157
+ print('Index File: ' + click.style(idx_file, underline=True, fg='blue'))
158
+ print()
159
+
160
+ print('File Size: ' + click.style(size_to_bytes_str(idx_info['filesize'], precision=3), fg='blue')
161
+ + ' (' + click.style(plural_word(idx_info['filesize'], "Byte"), underline=True) + ')')
162
+ print('Native Hash: ' + click.style(idx_info['hash'], underline=True))
163
+ print('LFS Hash: ' + click.style(idx_info['hash_lfs'], underline=True))
164
+ print('Files: ' + click.style(plural_word(len(idx_info['files']), 'file'), underline=True, fg='blue'))
165
+ if idx_info['files']:
166
+ d_files = {}
167
+ for file in idx_info['files'].keys():
168
+ type_ = get_file_type(file)
169
+ d_files[type_] = d_files.get(type_, 0) + 1
170
+ for type_, type_name in _FT_NAME_MAP.items():
171
+ if d_files.get(type_, 0) > 0:
172
+ print(f' {titleize(type_name)} Files: '
173
+ + click.style(plural_word(d_files[type_], "file"), underline=True))
174
+ pass
175
+
176
+ d_exts = {}
177
+ for file in idx_info['files'].keys():
178
+ _, ext = os.path.splitext(file)
179
+ d_exts[ext] = d_exts.get(ext, 0) + 1
180
+ print('File Extensions:')
181
+ for ext, count in sorted(d_exts.items(), key=lambda x: (-x[1], x[0])):
182
+ print(f' {ext or "<none>"} : ' + click.style(plural_word(count, "file"), underline=True))
183
+
184
+ # Convert to numpy array for easier calculations
185
+ file_sizes = [file_info['size'] for file, file_info in idx_info['files'].items()]
186
+
187
+ # Basic statistics
188
+ total_size = sum(file_sizes)
189
+ mean_size = statistics.mean(file_sizes)
190
+ median_size = statistics.median(file_sizes)
191
+ min_size = min(file_sizes)
192
+ max_size = max(file_sizes)
193
+
194
+ # Quartiles
195
+ sorted_sizes = sorted(file_sizes)
196
+ n = len(sorted_sizes)
197
+ q1 = sorted_sizes[n // 4]
198
+ q3 = sorted_sizes[(3 * n) // 4]
199
+ iqr = q3 - q1
200
+ std_dev = statistics.stdev(file_sizes)
201
+
202
+ with warnings.catch_warnings():
203
+ warnings.simplefilter("ignore", UserWarning)
204
+ print(f"Total Size: " +
205
+ click.style(size_to_bytes_str(total_size, precision=3), underline=True, fg='blue'))
206
+ print(f" Average File Size: " +
207
+ click.style(size_to_bytes_str(mean_size, precision=3), underline=True, fg='blue'))
208
+ print(f" Median File Size: " +
209
+ click.style(size_to_bytes_str(median_size, precision=3), underline=True, fg='blue'))
210
+ print(f" Smallest File Size: " +
211
+ click.style(size_to_bytes_str(min_size, precision=3), underline=True))
212
+ print(f" Largest File Size: " +
213
+ click.style(size_to_bytes_str(max_size, precision=3), underline=True))
214
+ print(f" Standard Deviation: " +
215
+ click.style(size_to_bytes_str(std_dev, precision=3), underline=True))
216
+ print("Quartiles:")
217
+ print(f" Q1 (25th Percentile): {size_to_bytes_str(q1, precision=3)}")
218
+ print(f" Q2 (50th Percentile, Median): {size_to_bytes_str(median_size, precision=3)}")
219
+ print(f" Q3 (75th Percentile): {size_to_bytes_str(q3, precision=3)}")
220
+ print(f" Interquartile Range (IQR): {size_to_bytes_str(iqr, precision=3)}")
221
+ print()
222
+
223
+ is_ready = hf_tar_validate(
224
+ repo_id=repo_id,
225
+ repo_type=repo_type,
226
+ revision=revision,
227
+ archive_in_repo=archive_file,
228
+
229
+ idx_repo_id=idx_repo_id or repo_id,
230
+ idx_repo_type=repo_type,
231
+ idx_revision=revision,
232
+ idx_file_in_repo=idx_file,
233
+ )
234
+
235
+ print('Status: ' + (
236
+ click.style('Up-To-Date', fg='green', underline=True) if is_ready else
237
+ click.style('Outdated', fg='yellow', underline=True)
238
+ ))
239
+ if not is_ready:
240
+ print('Index file is recommended to get refreshed.')
241
+
242
+ else:
243
+ rows = []
244
+ for file, file_info in sorted(idx_info['files'].items(), key=lambda x: (x[1]['offset'], x[0])):
245
+ rows.append({
246
+ 'file': hf_normpath(file),
247
+ 'offset': file_info['offset'],
248
+ 'size': file_info['size'],
249
+
250
+ 't_file': str(file),
251
+ 't_offset': str(file_info['offset']),
252
+ 't_size': plural_word(file_info['size'], "Byte"),
253
+ 't_size_text': size_to_bytes_str(file_info['size'], precision=3),
254
+ 't_sha256': file_info['sha256'],
255
+ })
256
+ if sort_by == 'offset':
257
+ rows = sorted(rows, key=lambda x: (x['offset'], x['file']), reverse=(order_by != 'asc'))
258
+ elif sort_by == 'name':
259
+ rows = sorted(rows, key=lambda x: (x['file'], x['offset']), reverse=(order_by != 'asc'))
260
+ elif sort_by == 'size':
261
+ rows = sorted(rows, key=lambda x: (x['size'], x['offset'], x['file']), reverse=(order_by != 'asc'))
262
+ else:
263
+ raise ValueError(f'Unknown sort_by {sort_by!r}.') # pragma: no cover
264
+
265
+ if len(rows):
266
+ if show_detailed:
267
+ max_t_file_len = max(len(row['t_file']) for row in rows)
268
+ max_t_offset_len = max(len(row['t_offset']) for row in rows)
269
+ max_t_size_text_len = max(len(row['t_size_text']) for row in rows)
270
+ max_t_sha256_len = max(len(row['t_sha256']) for row in rows)
271
+
272
+ for row in rows:
273
+ print(' ' * (max_t_offset_len - len(row['t_offset'])) + row['t_offset'], end=' | ')
274
+ fc = get_file_type(row['t_file'])
275
+ print(' ' * (max_t_file_len - len(row['t_file']))
276
+ + click.style(row['t_file'], fg=fc.render_color), end=' ')
277
+ print(' ' * (max_t_size_text_len - len(row['t_size_text']))
278
+ + click.style(row['t_size_text'], underline=True), end=' ')
279
+ print(' ' * (max_t_sha256_len - len(row['t_sha256']))
280
+ + click.style(row['t_sha256']))
281
+
282
+ else:
283
+ for row in rows:
284
+ file = row['file']
285
+ fc = get_file_type(file)
286
+ print(click.style(file, fg=fc.render_color))
287
+
288
+ return cli
@@ -1,6 +1,5 @@
1
- import mimetypes
2
1
  import os.path
3
- from enum import Enum, unique
2
+ import os.path
4
3
  from typing import Union, List
5
4
 
6
5
  import click
@@ -10,46 +9,7 @@ from huggingface_hub.hf_api import RepoFolder, RepoFile
10
9
 
11
10
  from .base import CONTEXT_SETTINGS
12
11
  from ..operate.base import REPO_TYPES, get_hf_client
13
- from ..utils import get_requests_session
14
-
15
- mimetypes.add_type('image/webp', '.webp')
16
-
17
-
18
- @unique
19
- class ListItemType(Enum):
20
- """
21
- Enum class representing different types of list items.
22
- """
23
-
24
- FILE = 0x1
25
- FOLDER = 0x2
26
- IMAGE = 0x3
27
- ARCHIVE = 0x4
28
- MODEL = 0x5
29
- DATA = 0x6
30
-
31
- @property
32
- def render_color(self):
33
- """
34
- Get the render color based on the item type.
35
-
36
- :return: The render color for the item type.
37
- :rtype: str
38
- """
39
- if self == self.FILE:
40
- return None
41
- elif self == self.FOLDER:
42
- return 'blue'
43
- elif self == self.IMAGE:
44
- return 'magenta'
45
- elif self == self.ARCHIVE:
46
- return 'red'
47
- elif self == self.MODEL:
48
- return 'green'
49
- elif self == self.DATA:
50
- return 'yellow'
51
- else:
52
- raise ValueError(f'Unknown type - {self!r}') # pragma: no cover
12
+ from ..utils import get_requests_session, FileItemType, get_file_type
53
13
 
54
14
 
55
15
  class ListItem:
@@ -66,22 +26,9 @@ class ListItem:
66
26
  self.item = item
67
27
  self.base_dir = base_dir
68
28
  if isinstance(item, RepoFolder):
69
- self.type = ListItemType.FOLDER
29
+ self.type = FileItemType.FOLDER
70
30
  else:
71
- mimetype, _ = mimetypes.guess_type(item.path)
72
- _, ext = os.path.splitext(item.path)
73
- self.type = ListItemType.FILE
74
- if ext in {'.ckpt', '.pt', '.safetensors', '.onnx', '.model', '.h5', '.mlmodel',
75
- '.ftz', '.pb', '.pth', '.tflite'}:
76
- self.type = ListItemType.MODEL
77
- elif ext in {'.json', '.csv', '.tsv', '.arrow', '.bin', '.msgpack', '.npy', '.npz',
78
- '.parquet', '.pickle', '.pkl', '.wasm'}:
79
- self.type = ListItemType.DATA
80
- elif mimetype:
81
- if 'image' in mimetype:
82
- self.type = ListItemType.IMAGE
83
- elif mimetype.split('/', maxsplit=1)[-1] in {'zip', 'rar', 'x-tar', 'x-7z-compressed'}:
84
- self.type = ListItemType.ARCHIVE
31
+ self.type = get_file_type(item.path)
85
32
 
86
33
 
87
34
  def _add_ls_subcommand(cli: click.Group) -> click.Group:
@@ -154,7 +101,7 @@ def _add_ls_subcommand(cli: click.Group) -> click.Group:
154
101
  max_size_length = 0
155
102
  max_commit_info_length = 0
156
103
  for item in items:
157
- if item.type == ListItemType.FOLDER:
104
+ if item.type == FileItemType.FOLDER:
158
105
  size_text = '-'
159
106
  else:
160
107
  size_text = str(item.item.size)
@@ -164,8 +111,8 @@ def _add_ls_subcommand(cli: click.Group) -> click.Group:
164
111
  max_commit_info_length = max(max_commit_info_length, len(commit_text))
165
112
 
166
113
  for item in items:
167
- print('d' if item.type == ListItemType.FOLDER else '-', end='')
168
- print('L' if item.type != ListItemType.FOLDER and item.item.lfs else '-', end='')
114
+ print('d' if item.type == FileItemType.FOLDER else '-', end='')
115
+ print('L' if item.type != FileItemType.FOLDER and item.item.lfs else '-', end='')
169
116
 
170
117
  commit_text = (item.item.last_commit.title or '').splitlines(keepends=False)[0]
171
118
  print(
@@ -174,7 +121,7 @@ def _add_ls_subcommand(cli: click.Group) -> click.Group:
174
121
  end=''
175
122
  )
176
123
 
177
- if item.type == ListItemType.FOLDER:
124
+ if item.type == FileItemType.FOLDER:
178
125
  size_text = '-'
179
126
  else:
180
127
  size_text = str(item.item.size)