Skip to content

Commit

Permalink
use file download subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
adal-chiriliuc-reef committed Apr 25, 2024
1 parent bc60f7a commit e7ff9f6
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 53 deletions.
40 changes: 22 additions & 18 deletions b2/_internal/console_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -1881,7 +1881,7 @@ def get_local_output_filepath(
return pathlib.Path(output_filepath_str)


class DownloadFileBase(
class FileDownloadBase(
ThreadsMixin,
MaxDownloadStreamsMixin,
DownloadCommand,
Expand Down Expand Up @@ -1928,23 +1928,6 @@ def _run(self, args):
return 0


class DownloadFile(B2URIFileArgMixin, DownloadFileBase):
__doc__ = DownloadFileBase.__doc__

def get_b2_uri_from_arg(self, args: argparse.Namespace) -> B2URIBase:
return args.B2_URI


class DownloadFileById(CmdReplacedByMixin, B2URIFileIDArgMixin, DownloadFileBase):
__doc__ = DownloadFileBase.__doc__
replaced_by_cmd = DownloadFile


class DownloadFileByName(CmdReplacedByMixin, B2URIBucketNFilenameArgMixin, DownloadFileBase):
__doc__ = DownloadFileBase.__doc__
replaced_by_cmd = DownloadFile


class FileCatBase(B2URIFileArgMixin, DownloadCommand):
"""
Download content of a file-like object identified by B2 URI directly to stdout.
Expand Down Expand Up @@ -4929,6 +4912,12 @@ class FileUpload(FileUploadBase):
COMMAND_NAME = 'upload'


@File.subcommands_registry.register
class FileDownload(B2URIFileArgMixin, FileDownloadBase):
__doc__ = FileDownloadBase.__doc__
COMMAND_NAME = 'download'


class FileInfo2(CmdReplacedByMixin, B2URIFileArgMixin, FileInfoBase):
__doc__ = FileInfoBase.__doc__
replaced_by_cmd = (File, FileInfo)
Expand Down Expand Up @@ -4966,6 +4955,21 @@ class UploadFile(CmdReplacedByMixin, FileUploadBase):
replaced_by_cmd = (File, FileUpload)


class DownloadFile(CmdReplacedByMixin, B2URIFileArgMixin, FileDownloadBase):
__doc__ = FileDownloadBase.__doc__
replaced_by_cmd = (File, FileDownload)


class DownloadFileById(CmdReplacedByMixin, B2URIFileIDArgMixin, FileDownloadBase):
__doc__ = FileDownloadBase.__doc__
replaced_by_cmd = (File, FileDownload)


class DownloadFileByName(CmdReplacedByMixin, B2URIBucketNFilenameArgMixin, FileDownloadBase):
__doc__ = FileDownloadBase.__doc__
replaced_by_cmd = (File, FileDownload)


class ConsoleTool:
"""
Implements the commands available in the B2 command-line tool
Expand Down
2 changes: 1 addition & 1 deletion test/integration/test_autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def test_autocomplete_b2__download_file__b2uri(
"""Test that autocomplete suggests bucket names and file names."""
if is_running_on_docker:
pytest.skip('Not supported on Docker')
shell.send(f'{cli_version} download_file \t\t')
shell.send(f'{cli_version} file download \t\t')
shell.expect_exact("b2://", timeout=TIMEOUT)
shell.send('b2://\t\t')
shell.expect_exact(bucket_name, timeout=TIMEOUT)
Expand Down
42 changes: 27 additions & 15 deletions test/integration/test_b2_command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,15 +282,15 @@ def test_download(b2_tool, bucket_name, sample_filepath, uploaded_sample_file, t
output_a = tmp_path / 'a'
b2_tool.should_succeed(
[
'download-file', '--quiet', f"b2://{bucket_name}/{uploaded_sample_file['fileName']}",
'file', 'download', '--quiet', f"b2://{bucket_name}/{uploaded_sample_file['fileName']}",
str(output_a)
]
)
assert output_a.read_text() == sample_filepath.read_text()

output_b = tmp_path / 'b'
b2_tool.should_succeed(
['download-file', '--quiet', f"b2id://{uploaded_sample_file['fileId']}",
['file', 'download', '--quiet', f"b2id://{uploaded_sample_file['fileId']}",
str(output_b)]
)
assert output_b.read_text() == sample_filepath.read_text()
Expand Down Expand Up @@ -346,7 +346,9 @@ def test_basic(b2_tool, bucket_name, sample_file, tmp_path, b2_uri_args):
['rm', '--recursive', '--with-wildcard', *b2_uri_args(bucket_name, 'rm1')]
)

b2_tool.should_succeed(['download-file', '--quiet', f'b2://{bucket_name}/b/1', tmp_path / 'a'])
b2_tool.should_succeed(
['file', 'download', '--quiet', f'b2://{bucket_name}/b/1', tmp_path / 'a']
)

b2_tool.should_succeed(['hide-file', bucket_name, 'c'])

Expand Down Expand Up @@ -1457,11 +1459,11 @@ def test_sse_b2(b2_tool, bucket_name, sample_file, tmp_path, b2_uri_args):
b2_tool.should_succeed(['file', 'upload', '--quiet', bucket_name, sample_file, 'not_encrypted'])

b2_tool.should_succeed(
['download-file', '--quiet', f'b2://{bucket_name}/encrypted', tmp_path / 'encrypted']
['file', 'download', '--quiet', f'b2://{bucket_name}/encrypted', tmp_path / 'encrypted']
)
b2_tool.should_succeed(
[
'download-file', '--quiet', f'b2://{bucket_name}/not_encrypted',
'file', 'download', '--quiet', f'b2://{bucket_name}/not_encrypted',
tmp_path / 'not_encrypted'
]
)
Expand Down Expand Up @@ -1561,21 +1563,24 @@ def test_sse_c(b2_tool, bucket_name, is_running_on_docker, sample_file, tmp_path
should_equal(sse_c_key_id, file_version_info['fileInfo'][SSE_C_KEY_ID_FILE_INFO_KEY_NAME])

b2_tool.should_fail(
['download-file', '--quiet', f'b2://{bucket_name}/uploaded_encrypted', 'gonna_fail_anyway'],
[
'file', 'download', '--quiet', f'b2://{bucket_name}/uploaded_encrypted',
'gonna_fail_anyway'
],
expected_pattern='ERROR: The object was stored using a form of Server Side Encryption. The '
r'correct parameters must be provided to retrieve the object. \(bad_request\)'
)
b2_tool.should_fail(
[
'download-file', '--quiet', '--source-server-side-encryption', 'SSE-C',
'file', 'download', '--quiet', '--source-server-side-encryption', 'SSE-C',
f'b2://{bucket_name}/uploaded_encrypted', 'gonna_fail_anyway'
],
expected_pattern='ValueError: Using SSE-C requires providing an encryption key via '
'B2_SOURCE_SSE_C_KEY_B64 env var'
)
b2_tool.should_fail(
[
'download-file', '--quiet', '--source-server-side-encryption', 'SSE-C',
'file', 'download', '--quiet', '--source-server-side-encryption', 'SSE-C',
f'b2://{bucket_name}/uploaded_encrypted', 'gonna_fail_anyway'
],
expected_pattern='ERROR: Wrong or no SSE-C key provided when reading a file.',
Expand All @@ -1584,7 +1589,8 @@ def test_sse_c(b2_tool, bucket_name, is_running_on_docker, sample_file, tmp_path
with contextlib.nullcontext(tmp_path) as dir_path:
b2_tool.should_succeed(
[
'download-file',
'file',
'download',
'--no-progress',
'--quiet',
'--source-server-side-encryption',
Expand All @@ -1597,7 +1603,8 @@ def test_sse_c(b2_tool, bucket_name, is_running_on_docker, sample_file, tmp_path
assert read_file(dir_path / 'a') == read_file(sample_file)
b2_tool.should_succeed(
[
'download-file',
'file',
'download',
'--no-progress',
'--quiet',
'--source-server-side-encryption',
Expand Down Expand Up @@ -3061,10 +3068,13 @@ def test_download_file_stdout(
b2_tool, bucket_name, sample_filepath, tmp_path, uploaded_sample_file
):
assert b2_tool.should_succeed(
['download-file', '--quiet', f"b2://{bucket_name}/{uploaded_sample_file['fileName']}", '-'],
[
'file', 'download', '--quiet', f"b2://{bucket_name}/{uploaded_sample_file['fileName']}",
'-'
],
) == sample_filepath.read_text()
assert b2_tool.should_succeed(
['download-file', '--quiet', f"b2id://{uploaded_sample_file['fileId']}", '-'],
['file', 'download', '--quiet', f"b2id://{uploaded_sample_file['fileId']}", '-'],
) == sample_filepath.read_text()


Expand All @@ -3079,7 +3089,8 @@ def test_download_file_to_directory(
sample_file_content = sample_filepath.read_text()
b2_tool.should_succeed(
[
'download-file',
'file',
'download',
'--quiet',
f"b2://{bucket_name}/{uploaded_sample_file['fileName']}",
str(target_directory),
Expand All @@ -3091,7 +3102,8 @@ def test_download_file_to_directory(

b2_tool.should_succeed(
[
'download-file',
'file',
'download',
'--quiet',
f"b2id://{uploaded_sample_file['fileId']}",
str(target_directory),
Expand Down Expand Up @@ -3169,7 +3181,7 @@ def assert_expected(file_info, expected=expected_file_info):
assert_expected(copied_version['fileInfo'])

download_output = b2_tool.should_succeed(
['download-file', f"b2id://{file_version['fileId']}", tmp_path / 'downloaded_file']
['file', 'download', f"b2id://{file_version['fileId']}", tmp_path / 'downloaded_file']
)
assert re.search(r'CacheControl: *max-age=3600', download_output)
assert re.search(r'ContentDisposition: *attachment', download_output)
Expand Down
2 changes: 1 addition & 1 deletion test/unit/_cli/test_autocomplete_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def test_complete_with_file_uri_suggestions(
tracker=autocomplete_cache.VersionTracker(),
store=autocomplete_cache.HomeCachePickleStore(tmp_path),
)
with autocomplete_runner(f'b2 download-file b2://{bucket}/'):
with autocomplete_runner(f'b2 file download b2://{bucket}/'):
exit, argcomplete_output = argcomplete_result()
assert exit == 0
assert file_name in argcomplete_output
Expand Down
18 changes: 8 additions & 10 deletions test/unit/console_tool/test_download_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_download_file_by_uri__flag_support(b2_cli, uploaded_file, tmp_path, fla
output_path = tmp_path / 'output.txt'

b2_cli.run(
['download-file', flag, 'b2id://9999',
['file', 'download', flag, 'b2id://9999',
str(output_path)],
expected_stdout=expected_stdout.format(output_path=pathlib.Path(output_path).resolve())
)
Expand All @@ -55,7 +55,7 @@ def test_download_file_by_uri__b2_uri_support(b2_cli, uploaded_file, tmp_path, b
output_path = tmp_path / 'output.txt'

b2_cli.run(
['download-file', b2_uri, str(output_path)],
['file', 'download', b2_uri, str(output_path)],
expected_stdout=EXPECTED_STDOUT_DOWNLOAD.format(
output_path=pathlib.Path(output_path).resolve()
)
Expand All @@ -82,7 +82,7 @@ def test_download_file_by_name(b2_cli, local_file, uploaded_file, tmp_path, flag
output_path=pathlib.Path(output_path).resolve()
),
expected_stderr=
'WARNING: `download-file-by-name` command is deprecated. Use `download-file` instead.\n',
'WARNING: `download-file-by-name` command is deprecated. Use `file download` instead.\n',
)
assert output_path.read_text() == uploaded_file['content']

Expand All @@ -101,7 +101,7 @@ def test_download_file_by_id(b2_cli, uploaded_file, tmp_path, flag, expected_std
['download-file-by-id', flag, '9999', str(output_path)],
expected_stdout=expected_stdout.format(output_path=pathlib.Path(output_path).resolve()),
expected_stderr=
'WARNING: `download-file-by-id` command is deprecated. Use `download-file` instead.\n',
'WARNING: `download-file-by-id` command is deprecated. Use `file download` instead.\n',
)
assert output_path.read_text() == uploaded_file['content']

Expand Down Expand Up @@ -131,7 +131,7 @@ def reader():
output_path=pathlib.Path(output_path).resolve()
),
expected_stderr=
'WARNING: `download-file-by-name` command is deprecated. Use `download-file` instead.\n',
'WARNING: `download-file-by-name` command is deprecated. Use `file download` instead.\n',
)
reader_future.result(timeout=1)
assert output_string == uploaded_file['content']
Expand All @@ -151,18 +151,17 @@ def uploaded_stdout_txt(b2_cli, bucket, local_file, tmp_path):
def test_download_file_by_name__to_stdout_by_alias(
b2_cli, bucket, uploaded_stdout_txt, tmp_path, capfd
):
"""Test download_file_by_name stdout alias support"""
"""Test download-file-by-name stdout alias support"""
b2_cli.run(
['download-file-by-name', '--no-progress', bucket, uploaded_stdout_txt['fileName'], '-'],
expected_stderr=
'WARNING: `download-file-by-name` command is deprecated. Use `download-file` instead.\n',
'WARNING: `download-file-by-name` command is deprecated. Use `file download` instead.\n',
)
assert capfd.readouterr().out == uploaded_stdout_txt['content']
assert not pathlib.Path('-').exists()


def test_cat__b2_uri(b2_cli, bucket, uploaded_stdout_txt, tmp_path, capfd):
"""Test download_file_by_name stdout alias support"""
b2_cli.run(
['file', 'cat', '--no-progress', f"b2://{bucket}/{uploaded_stdout_txt['fileName']}"],
)
Expand All @@ -189,7 +188,6 @@ def test_cat__b2_uri__not_a_file(b2_cli, bucket, capfd):


def test_cat__b2id_uri(b2_cli, bucket, uploaded_stdout_txt, tmp_path, capfd):
"""Test download_file_by_name stdout alias support"""
b2_cli.run(['file', 'cat', '--no-progress', "b2id://9999"],)
assert capfd.readouterr().out == uploaded_stdout_txt['content']

Expand All @@ -200,7 +198,7 @@ def test__download_file__threads(b2_cli, local_file, uploaded_file, tmp_path):

b2_cli.run(
[
'download-file', '--no-progress', '--threads',
'file', 'download', '--no-progress', '--threads',
str(num_threads), 'b2://my-bucket/file1.txt',
str(output_path)
]
Expand Down
4 changes: 2 additions & 2 deletions test/unit/console_tool/test_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
# --help shouldn't show deprecated commands
(
"--help",
[" b2 download-file ", "-h", "--help-all"],
[" download-file-by-name ", "(DEPRECATED)"],
[" b2 file ", "-h", "--help-all"],
[" b2 download-file-by-name ", "(DEPRECATED)"],
),
# --help-all should show deprecated commands, but marked as deprecated
(
Expand Down
14 changes: 8 additions & 6 deletions test/unit/test_console_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ def test_files_encrypted(self):
)

self._run_command(
['download-file', '--no-progress', 'b2://my-bucket/file1.txt', local_download1],
['file', 'download', '--no-progress', 'b2://my-bucket/file1.txt', local_download1],
expected_stdout, '', 0
)
self.assertEqual(b'hello world', self._read_file(local_download1))
Expand All @@ -1249,8 +1249,8 @@ def test_files_encrypted(self):
output_path=pathlib.Path(local_download2).resolve()
)
self._run_command(
['download-file', '--no-progress', 'b2id://9999', local_download2], expected_stdout,
'', 0
['file', 'download', '--no-progress', 'b2id://9999', local_download2],
expected_stdout, '', 0
)
self.assertEqual(b'hello world', self._read_file(local_download2))

Expand Down Expand Up @@ -1353,7 +1353,8 @@ def _test_download_to_directory(self, download_by: str):

b2uri = f'b2://my-bucket/{source_filename}' if download_by == 'name' else 'b2id://9999'
command = [
'download-file',
'file',
'download',
'--no-progress',
b2uri,
]
Expand Down Expand Up @@ -1471,7 +1472,7 @@ def test_copy_file_by_id(self):

local_download1 = os.path.join(temp_dir, 'file1_copy.txt')
self._run_command(
['download-file', '-q', 'b2://my-bucket/file1_copy.txt', local_download1]
['file', 'download', '-q', 'b2://my-bucket/file1_copy.txt', local_download1]
)
self.assertEqual(b'lo wo', self._read_file(local_download1))

Expand Down Expand Up @@ -1732,7 +1733,8 @@ def test_upload_incremental(self):
downloaded_path = pathlib.Path(temp_dir) / 'out.txt'
self._run_command(
[
'download-file',
'file',
'download',
'-q',
'b2://my-bucket/test.txt',
str(downloaded_path),
Expand Down

0 comments on commit e7ff9f6

Please sign in to comment.