upload.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # Copyright (c) Alibaba, Inc. and its affiliates.
  2. import os
  3. from argparse import ArgumentParser, _SubParsersAction
  4. from modelscope.cli.base import CLICommand
  5. from modelscope.hub.api import HubApi
  6. from modelscope.hub.utils.utils import convert_patterns, get_endpoint
  7. from modelscope.utils.constant import REPO_TYPE_MODEL, REPO_TYPE_SUPPORT
  8. def subparser_func(args):
  9. """ Function which will be called for a specific sub parser.
  10. """
  11. return UploadCMD(args)
  12. class UploadCMD(CLICommand):
  13. name = 'upload'
  14. def __init__(self, args: _SubParsersAction):
  15. self.args = args
  16. @staticmethod
  17. def define_args(parsers: _SubParsersAction):
  18. parser: ArgumentParser = parsers.add_parser(UploadCMD.name)
  19. parser.add_argument(
  20. 'repo_id',
  21. type=str,
  22. help='The ID of the repo to upload to (e.g. `username/repo-name`)')
  23. parser.add_argument(
  24. 'local_path',
  25. type=str,
  26. nargs='?',
  27. default=None,
  28. help='Optional, '
  29. 'Local path to the file or folder to upload. Defaults to current directory.'
  30. )
  31. parser.add_argument(
  32. 'path_in_repo',
  33. type=str,
  34. nargs='?',
  35. default=None,
  36. help='Optional, '
  37. 'Path of the file or folder in the repo. Defaults to the relative path of the file or folder.'
  38. )
  39. parser.add_argument(
  40. '--repo-type',
  41. choices=REPO_TYPE_SUPPORT,
  42. default=REPO_TYPE_MODEL,
  43. help=
  44. 'Type of the repo to upload to (e.g. `dataset`, `model`). Defaults to be `model`.',
  45. )
  46. parser.add_argument(
  47. '--include',
  48. nargs='*',
  49. type=str,
  50. help='Glob patterns to match files to upload.')
  51. parser.add_argument(
  52. '--exclude',
  53. nargs='*',
  54. type=str,
  55. help='Glob patterns to exclude from files to upload.')
  56. parser.add_argument(
  57. '--commit-message',
  58. type=str,
  59. default=None,
  60. help='The message of commit. Default to be `None`.')
  61. parser.add_argument(
  62. '--commit-description',
  63. type=str,
  64. default=None,
  65. help=
  66. 'The description of the generated commit. Default to be `None`.')
  67. parser.add_argument(
  68. '--token',
  69. type=str,
  70. default=None,
  71. help=
  72. 'A User Access Token generated from https://modelscope.cn/my/myaccesstoken'
  73. )
  74. parser.add_argument(
  75. '--max-workers',
  76. type=int,
  77. default=min(8,
  78. os.cpu_count() + 4),
  79. help='The number of workers to use for uploading files.')
  80. parser.add_argument(
  81. '--endpoint',
  82. type=str,
  83. default=get_endpoint(),
  84. help='Endpoint for ModelScope service.')
  85. parser.set_defaults(func=subparser_func)
  86. def execute(self):
  87. assert self.args.repo_id, '`repo_id` is required'
  88. assert self.args.repo_id.count(
  89. '/') == 1, 'repo_id should be in format of username/repo-name'
  90. repo_name: str = self.args.repo_id.split('/')[-1]
  91. self.repo_id = self.args.repo_id
  92. # Check path_in_repo
  93. if self.args.local_path is None and os.path.isfile(repo_name):
  94. # Case 1: modelscope upload owner_name/test_repo
  95. self.local_path = repo_name
  96. self.path_in_repo = repo_name
  97. elif self.args.local_path is None and os.path.isdir(repo_name):
  98. # Case 2: modelscope upload owner_name/test_repo (run command line in the `repo_name` dir)
  99. # => upload all files in current directory to remote root path
  100. self.local_path = repo_name
  101. self.path_in_repo = '.'
  102. elif self.args.local_path is None:
  103. # Case 3: user provided only a repo_id that does not match a local file or folder
  104. # => the user must explicitly provide a local_path => raise exception
  105. raise ValueError(
  106. f"'{repo_name}' is not a local file or folder. Please set `local_path` explicitly."
  107. )
  108. elif self.args.path_in_repo is None and os.path.isfile(
  109. self.args.local_path):
  110. # Case 4: modelscope upload owner_name/test_repo /path/to/your_file.csv
  111. # => upload it to remote root path with same name
  112. self.local_path = self.args.local_path
  113. self.path_in_repo = os.path.basename(self.args.local_path)
  114. elif self.args.path_in_repo is None:
  115. # Case 5: modelscope upload owner_name/test_repo /path/to/your_folder
  116. # => upload all files in current directory to remote root path
  117. self.local_path = self.args.local_path
  118. self.path_in_repo = ''
  119. else:
  120. # Finally, if both paths are explicit
  121. self.local_path = self.args.local_path
  122. self.path_in_repo = self.args.path_in_repo
  123. api = HubApi(endpoint=self.args.endpoint)
  124. if os.path.isfile(self.local_path):
  125. api.upload_file(
  126. path_or_fileobj=self.local_path,
  127. path_in_repo=self.path_in_repo,
  128. repo_id=self.repo_id,
  129. repo_type=self.args.repo_type,
  130. commit_message=self.args.commit_message,
  131. commit_description=self.args.commit_description,
  132. token=self.args.token,
  133. )
  134. elif os.path.isdir(self.local_path):
  135. api.upload_folder(
  136. repo_id=self.repo_id,
  137. folder_path=self.local_path,
  138. path_in_repo=self.path_in_repo,
  139. commit_message=self.args.commit_message,
  140. commit_description=self.args.commit_description,
  141. repo_type=self.args.repo_type,
  142. allow_patterns=convert_patterns(self.args.include),
  143. ignore_patterns=convert_patterns(self.args.exclude),
  144. max_workers=self.args.max_workers,
  145. token=self.args.token,
  146. )
  147. else:
  148. raise ValueError(f'{self.local_path} is not a valid local path')
  149. print(f'Finished uploading to {self.repo_id}')