Files
modelscope/tests/cli/test_download_cmd.py
Xingjun.Wang 680c3638e0 [Feat & Refactor] Refactor hub and CLI modules (#1732)
* refactor(hub): shim layer delegating to modelscope-hub

- Replace hub/api.py (4674→250 lines) with shim inheriting LegacyHubApi
- Replace hub/snapshot_download.py, callback.py with thin shims
- Partial shim hub/file_download.py (retain http_get_file)
- Shim hub/constants.py and errors.py with legacy aliases
- Shim hub/git.py, repository.py, cache_manager.py, upload_*.py
- Migrate CLI entry to modelscope_hub.cli.main:run_cmd
- Adapt 6 CLI commands as modelscope_hub.cli_plugins
- Delete redundant CLI files (download/upload/login/create/etc)
- Add modelscope-hub>=0.2.0 dependency, Python>=3.10
- Add __getattr__ proxy for forward-compatible method access
- Propagate timeout/max_retries to internal LegacyClient
- Bridge MODELSCOPE_CREDENTIALS_PATH env var to HubConfig

* fix lint: isort/yapf formatting + exclude hub/api.py from hooks

* set modelscope-hub>=0.0.5

* remove unused code

* refactor(hub): standardize token naming — git_token vs token

Disambiguate git token and SDK/API token naming across the hub layer:
- ModelScopeConfig: get_token/save_token → get_git_token/save_git_token
  (old names kept as deprecated aliases with DeprecationWarning)
- GitCommandWrapper: rename token params to git_token in clone/push/config
- Repository/DatasetRepository: auth_token → git_token (deprecated compat kept)
- data_loader.py: update caller to use get_git_token()

SDK token references (HubApi(token=...), get_cookies(access_token=...),
commit_scheduler.token) remain unchanged as they correctly use `token` naming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* remove(msdatasets): remove all Virgo-related implementation

Remove the entire Virgo dataset subsystem which is no longer needed:
- Remove VirgoDataset class and VirgoDownloader
- Remove VirgoAuthConfig and VirgoDatasetConfig
- Remove Hubs.virgo enum value
- Remove fetch_virgo_meta from DataMetaManager
- Remove download_virgo_files from DatasetContextConfig
- Remove test_virgo_dataset.py test file
- Clean up unused imports (pandas, MaxComputeUtil, valid_url, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(hub): add OSS dataset operations and meta-file download to HubApi

Add methods that msdatasets depends on but don't belong in modelscope_hub:
- _legacy_request: internal helper combining legacy HTTP transport with
  application-level envelope validation (Code/Data/Message)
- list_oss_dataset_objects: list OSS storage objects for a dataset
- delete_oss_dataset_object / delete_oss_dataset_dir: delete OSS objects
- fetch_meta_files_from_url: download and cache meta CSV/JSONL files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix imports issue

* fix: address PR review feedback

- cli/plugins.py: change --yes and --all flags to action='store_true'
- hub/git.py: replace os.linesep with .splitlines() for cross-platform safety
- hub/__init__.py: use is_file() with fallback for robust credentials path detection

* fix lint

* update ms hub version

* fix(ci): add PyPI official as fallback index for pip

Aliyun mirror may lag behind PyPI for newly published packages,
causing dependency resolution failures (e.g. modelscope-hub>=0.0.6).
Add pypi.org/simple as extra-index-url so new versions are immediately
available while keeping the Aliyun mirror as the primary source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix UTs

* remove unused UTs

* fix ut

* update modelscope-hub installation for source code

* fix UT

* fix uts

* fix ut

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-09 22:23:14 +08:00

156 lines
5.8 KiB
Python

import os
import os.path as osp
import shutil
import subprocess
import tempfile
import unittest
import uuid
from modelscope.hub.api import HubApi
from modelscope.hub.constants import Licenses, ModelVisibility
from modelscope.hub.repository import Repository
from modelscope.utils.logger import get_logger
from modelscope.utils.test_utils import (TEST_ACCESS_TOKEN1,
TEST_MODEL_CHINESE_NAME,
TEST_MODEL_ORG, test_level)
logger = get_logger()
DEFAULT_GIT_PATH = 'git'
download_model_file_name = 'test.bin'
class DownloadCMDTest(unittest.TestCase):
def setUp(self):
print(('Testing %s.%s' % (type(self).__name__, self._testMethodName)))
self.tmp_dir = tempfile.TemporaryDirectory().name
if not os.path.exists(self.tmp_dir):
os.makedirs(self.tmp_dir)
self.api = HubApi()
self.api.login(TEST_ACCESS_TOKEN1)
self.model_name = 'op-%s' % (uuid.uuid4().hex)
self.model_id = '%s/%s' % (TEST_MODEL_ORG, self.model_name)
self.revision = 'v0.1_test_revision'
self.api.create_model(
model_id=self.model_id,
visibility=ModelVisibility.PUBLIC,
license=Licenses.APACHE_V2,
chinese_name=TEST_MODEL_CHINESE_NAME,
)
self.prepare_case()
def prepare_case(self):
temporary_dir = tempfile.mkdtemp()
self.model_dir = os.path.join(temporary_dir, self.model_name)
repo = Repository(self.model_dir, clone_from=self.model_id)
os.system("echo 'testtest'>%s"
% os.path.join(self.model_dir, download_model_file_name))
repo.push('add model')
repo.tag_and_push(self.revision, 'Test revision')
def tearDown(self):
shutil.rmtree(self.tmp_dir)
try:
self.api.delete_model(model_id=self.model_id)
except Exception as e:
logger.warning(f'Error deleting model {self.model_id}: {e}')
super().tearDown()
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download(self):
cmd = f'python -m modelscope.cli.cli download --model {self.model_id}'
stat, output = subprocess.getstatusoutput(cmd)
self.assertEqual(stat, 0)
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download_with_position_arg(self):
cmd = f'python -m modelscope.cli.cli download {self.model_id}'
stat, output = subprocess.getstatusoutput(cmd)
self.assertEqual(stat, 0)
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download_file(self):
cmd = f'python -m modelscope.cli.cli download --model {self.model_id} {download_model_file_name}'
stat, output = subprocess.getstatusoutput(cmd)
self.assertEqual(stat, 0)
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download_with_cache(self):
cmd = f'python -m modelscope.cli.cli download --model {self.model_id} --cache_dir {self.tmp_dir}'
stat, output = subprocess.getstatusoutput(cmd)
if stat != 0:
print(output)
self.assertEqual(stat, 0)
found = any(download_model_file_name in files
for _, _, files in os.walk(self.tmp_dir))
self.assertTrue(
found,
f'{download_model_file_name} not found under {self.tmp_dir}')
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download_with_revision(self):
cmd = f'python -m modelscope.cli.cli download --model {self.model_id} --revision {self.revision}'
stat, output = subprocess.getstatusoutput(cmd)
if stat != 0:
print(output)
self.assertEqual(stat, 0)
class DownloadCMDTokenTest(unittest.TestCase):
def setUp(self):
print(('Testing %s.%s' % (type(self).__name__, self._testMethodName)))
self.api = HubApi()
# Create private model repo
self.model_id = '%s/%s' % (TEST_MODEL_ORG, 'test_model_with_token')
self.api.create_repo(
repo_id=self.model_id,
repo_type='model',
visibility='private',
license=Licenses.APACHE_V2,
chinese_name=TEST_MODEL_CHINESE_NAME,
exist_ok=True,
)
# Create private dataset repo
self.dataset_id = '%s/%s' % (TEST_MODEL_ORG, 'test_dataset_with_token')
self.api.create_repo(
repo_id=self.dataset_id,
repo_type='dataset',
visibility='private',
license=Licenses.APACHE_V2,
exist_ok=True,
)
def tearDown(self):
try:
self.api.delete_model(model_id=self.model_id)
except Exception as e:
logger.warning(f'Error deleting model {self.model_id}: {e}')
try:
self.api.delete_dataset(dataset_id=self.dataset_id)
except Exception as e:
logger.warning(f'Error deleting dataset {self.dataset_id}: {e}')
super().tearDown()
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download_model_with_token(self):
cmd = f'python -m modelscope.cli.cli download --model {self.model_id} --token {TEST_ACCESS_TOKEN1}'
stat, output = subprocess.getstatusoutput(cmd)
print(output)
self.assertEqual(stat, 0)
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_download_dataset_with_token(self):
cmd = f'python -m modelscope.cli.cli download --dataset {self.dataset_id} --token {TEST_ACCESS_TOKEN1}'
stat, output = subprocess.getstatusoutput(cmd)
print(output)
self.assertEqual(stat, 0)
if __name__ == '__main__':
unittest.main()