Add create repo cli (#1445)

This commit is contained in:
Xingjun.Wang
2025-08-05 21:42:41 +08:00
committed by GitHub
parent 51e28f5a49
commit ee05e12d75
4 changed files with 168 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import argparse
import logging
from modelscope.cli.clearcache import ClearCacheCMD
from modelscope.cli.create import CreateCMD
from modelscope.cli.download import DownloadCMD
from modelscope.cli.llamafile import LlamafileCMD
from modelscope.cli.login import LoginCMD
@@ -27,6 +28,7 @@ def run_cmd():
'--token', default=None, help='Specify ModelScope SDK token.')
subparsers = parser.add_subparsers(help='modelscope commands helpers')
CreateCMD.define_args(subparsers)
DownloadCMD.define_args(subparsers)
UploadCMD.define_args(subparsers)
ClearCacheCMD.define_args(subparsers)

100
modelscope/cli/create.py Normal file
View File

@@ -0,0 +1,100 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from argparse import ArgumentParser, _SubParsersAction
from modelscope.cli.base import CLICommand
from modelscope.hub.api import HubApi
from modelscope.hub.constants import Licenses, Visibility
from modelscope.utils.constant import REPO_TYPE_MODEL, REPO_TYPE_SUPPORT
def subparser_func(args):
""" Function which will be called for a specific sub parser.
"""
return CreateCMD(args)
class CreateCMD(CLICommand):
"""
Command for creating a new repository, supporting both model and dataset.
"""
name = 'create'
def __init__(self, args: _SubParsersAction):
self.args = args
@staticmethod
def define_args(parsers: _SubParsersAction):
parser: ArgumentParser = parsers.add_parser(CreateCMD.name)
parser.add_argument(
'repo_id',
type=str,
help='The ID of the repo to create (e.g. `username/repo-name`)')
parser.add_argument(
'--token',
type=str,
default=None,
help=
'A User Access Token generated from https://modelscope.cn/my/myaccesstoken to authenticate the user. '
'If not provided, the CLI will use the local credentials if available.'
)
parser.add_argument(
'--repo_type',
choices=REPO_TYPE_SUPPORT,
default=REPO_TYPE_MODEL,
help=
'Type of the repo to create (e.g. `dataset`, `model`). Default to `model`.',
)
parser.add_argument(
'--visibility',
choices=[
Visibility.PUBLIC, Visibility.INTERNAL, Visibility.PRIVATE
],
default=Visibility.PUBLIC,
help='Visibility of the repo to create. Default to `public`.',
)
parser.add_argument(
'--chinese_name',
type=str,
default=None,
help='Optional, Chinese name of the repo. Default to `None`.',
)
parser.add_argument(
'--license',
type=str,
choices=Licenses.to_list(),
default=Licenses.APACHE_V2,
help=
'Optional, License of the repo. Default to `Apache License 2.0`.',
)
parser.add_argument(
'--endpoint',
type=str,
default=None,
help='Optional, The modelscope server address. Default to None.',
)
parser.set_defaults(func=subparser_func)
def execute(self):
# Check token and login
# The cookies will be reused if the user has logged in before.
api = HubApi(endpoint=self.args.endpoint)
# Create repo
api.create_repo(
repo_id=self.args.repo_id,
token=self.args.token,
visibility=self.args.visibility,
repo_type=self.args.repo_type,
chinese_name=self.args.chinese_name,
license=self.args.license,
exist_ok=True,
create_default_config=True,
endpoint=self.args.endpoint,
)
print(f'Successfully created the repo: {self.args.repo_id}.')

View File

@@ -77,6 +77,19 @@ class Licenses(object):
ECL_V2 = 'ECL-2.0'
MIT = 'MIT'
@classmethod
def to_list(cls):
return [
cls.APACHE_V2,
cls.GPL_V2,
cls.GPL_V3,
cls.LGPL_V2_1,
cls.LGPL_V3,
cls.AFL_V3,
cls.ECL_V2,
cls.MIT,
]
class ModelVisibility(object):
PRIVATE = 1

View File

@@ -0,0 +1,53 @@
import subprocess
import unittest
import uuid
from modelscope.hub.api import HubApi
from modelscope.hub.constants import Licenses
from modelscope.utils.test_utils import (TEST_ACCESS_TOKEN1,
TEST_MODEL_CHINESE_NAME,
TEST_MODEL_ORG, test_level)
class CreateCMDTest(unittest.TestCase):
"""
Repository creation tests for the ModelScope CLI.
Usage:
modelscope create <repo_id> --token <token> --repo_type <model/dataset> --visibility <public/internal/private> --chinese_name <chinese_name> --license <license> # noqa: E501
"""
def setUp(self):
print(f'Running test {type(self).__name__}.{self._testMethodName}')
tmp_suffix: str = uuid.uuid4().hex[:4]
self.repo_id: str = f'{TEST_MODEL_ORG}/test_create_model_{tmp_suffix}'
self.repo_type: str = 'model'
self.visibility: str = 'private'
self.chinese_name: str = f'{TEST_MODEL_CHINESE_NAME}_{tmp_suffix}'
self.license: str = Licenses.MIT
self.token: str = TEST_ACCESS_TOKEN1
def tearDown(self):
api = HubApi()
api.login(self.token)
try:
api.delete_model(model_id=self.repo_id)
except Exception as e:
print(f'Error deleting model {self.repo_id}: {e}')
print(f'Test {type(self).__name__}.{self._testMethodName} finished')
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_create_repo_cmd(self):
cmd: str = f'python -m modelscope.cli.cli create {self.repo_id} --token {self.token} --repo_type {self.repo_type} --visibility {self.visibility} --chinese_name {self.chinese_name} --license {self.license}' # noqa: E501
stat, output = subprocess.getstatusoutput(cmd)
self.assertEqual(
stat, 0, msg=f'Command failed: {cmd}\nOutput: {output}')
if __name__ == '__main__':
unittest.main()