qbraid-cli 0.9.2__tar.gz → 0.9.4__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.
Potentially problematic release.
This version of qbraid-cli might be problematic. Click here for more details.
- {qbraid_cli-0.9.2/qbraid_cli.egg-info → qbraid_cli-0.9.4}/PKG-INFO +2 -2
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/index.rst +3 -2
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/pyproject.toml +2 -2
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/_version.py +2 -2
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/envs/app.py +46 -6
- qbraid_cli-0.9.4/qbraid_cli/files/__init__.py +11 -0
- qbraid_cli-0.9.4/qbraid_cli/files/app.py +118 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/main.py +2 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4/qbraid_cli.egg-info}/PKG-INFO +2 -2
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli.egg-info/SOURCES.txt +8 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli.egg-info/requires.txt +1 -1
- qbraid_cli-0.9.4/tests/envs/test_envs_create_from_yaml.py +108 -0
- qbraid_cli-0.9.4/tests/files/test_files_commands.py +109 -0
- qbraid_cli-0.9.4/tests/kernels/__init__.py +0 -0
- qbraid_cli-0.9.4/tests/resources/envs/correct.yaml +16 -0
- qbraid_cli-0.9.4/tests/resources/envs/icon.png +0 -0
- qbraid_cli-0.9.4/tests/resources/envs/incorrect.yaml +4 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tools/split_md.py +2 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.env.example +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/bump-version.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/docs-pr.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/docs.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/format.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/main.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/pre-release.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/publish.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.github/workflows/tag-on-merge.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.gitignore +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/.readthedocs.yml +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/CONTRIBUTING.md +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/LICENSE +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/MANIFEST.IN +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/Makefile +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/README.md +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/Makefile +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/_static/favicon.ico +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/_static/logo.png +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/_static/style/custom.css +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/_static/style/s4defs-roles.css +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/conf.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/make.bat +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/docs/requirements.txt +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/account/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/account/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/admin/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/admin/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/admin/headers.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/admin/validation.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/chat/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/chat/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/configure/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/configure/actions.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/configure/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/devices/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/devices/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/devices/validation.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/envs/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/envs/activate.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/envs/create.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/envs/data_handling.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/exceptions.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/handlers.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/jobs/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/jobs/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/jobs/toggle_braket.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/jobs/validation.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/kernels/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/kernels/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/pip/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/pip/app.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/pip/hooks.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli/py.typed +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli.egg-info/dependency_links.txt +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli.egg-info/entry_points.txt +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/qbraid_cli.egg-info/top_level.txt +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/setup.cfg +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/account/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/account/test_account_credits.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/admin/test_headers.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/configure/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/configure/test_configure_prompt_for_config.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/configure/test_configure_set.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/configure/test_configure_validate_input.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/conftest.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/devices/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/devices/test_devices_list.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/devices/test_devices_validations.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/test_envs_activate.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/test_envs_activate_find_shell_rc.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/test_envs_activate_print_command.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/test_envs_activate_pyenv.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/test_envs_list.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/envs/test_envs_remove.py +0 -0
- {qbraid_cli-0.9.2/tests/jobs → qbraid_cli-0.9.4/tests/files}/__init__.py +0 -0
- {qbraid_cli-0.9.2/tests/kernels → qbraid_cli-0.9.4/tests/jobs}/__init__.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_disable.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_enable.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_list.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_state.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_toggle_braket_confirm.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_toggle_braket_disable.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_toggle_braket_enable.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_toggle_braket_get_data.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_validate_get_state.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_validate_handle_state.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/jobs/test_jobs_validate_library.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tests/kernels/test_kernels_list.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tools/bump_version.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tools/create_dev_build.sh +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tools/install_wheel_extras.sh +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tools/split_rst.py +0 -0
- {qbraid_cli-0.9.2 → qbraid_cli-0.9.4}/tools/stamp_pre_release.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qbraid-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
4
4
|
Summary: Command Line Interface for interacting with all parts of the qBraid platform.
|
|
5
5
|
Author-email: qBraid Development Team <contact@qbraid.com>
|
|
6
6
|
License: Proprietary
|
|
@@ -30,7 +30,7 @@ License-File: LICENSE
|
|
|
30
30
|
Requires-Dist: typer>=0.12.1
|
|
31
31
|
Requires-Dist: rich>=10.11.0
|
|
32
32
|
Requires-Dist: click
|
|
33
|
-
Requires-Dist: qbraid-core>=0.1.
|
|
33
|
+
Requires-Dist: qbraid-core>=0.1.33
|
|
34
34
|
Provides-Extra: jobs
|
|
35
35
|
Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
|
|
36
36
|
Provides-Extra: envs
|
|
@@ -6,7 +6,7 @@ Documentation
|
|
|
6
6
|
<br />
|
|
7
7
|
|
|
8
8
|
<h1 style="text-align: center">
|
|
9
|
-
<img src="
|
|
9
|
+
<img src="_static/logo.png" alt="qbraid logo" style="width:50px;height:50px;">
|
|
10
10
|
<span> qBraid</span>
|
|
11
11
|
<span style="color:#808080"> | CLI</span>
|
|
12
12
|
</h1>
|
|
@@ -121,4 +121,5 @@ by disabling quantum jobs:
|
|
|
121
121
|
tree/qbraid_jobs
|
|
122
122
|
tree/qbraid_kernels
|
|
123
123
|
tree/qbraid_pip
|
|
124
|
-
tree/qbraid_chat
|
|
124
|
+
tree/qbraid_chat
|
|
125
|
+
tree/qbraid_files
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qbraid-cli"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.4"
|
|
8
8
|
description = "Command Line Interface for interacting with all parts of the qBraid platform."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "qBraid Development Team", email = "contact@qbraid.com" }]
|
|
@@ -31,7 +31,7 @@ dependencies = [
|
|
|
31
31
|
"typer>=0.12.1",
|
|
32
32
|
"rich>=10.11.0",
|
|
33
33
|
"click",
|
|
34
|
-
"qbraid-core>=0.1.
|
|
34
|
+
"qbraid-core>=0.1.33",
|
|
35
35
|
]
|
|
36
36
|
requires-python = ">= 3.9"
|
|
37
37
|
|
|
@@ -12,5 +12,5 @@ __version__: str
|
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
|
13
13
|
version_tuple: VERSION_TUPLE
|
|
14
14
|
|
|
15
|
-
__version__ = version = '0.1.dev1+
|
|
16
|
-
__version_tuple__ = version_tuple = (0, 1, 'dev1', '
|
|
15
|
+
__version__ = version = '0.1.dev1+gc0cd415'
|
|
16
|
+
__version_tuple__ = version_tuple = (0, 1, 'dev1', 'gc0cd415')
|
|
@@ -13,12 +13,13 @@ from pathlib import Path
|
|
|
13
13
|
from typing import TYPE_CHECKING, Optional
|
|
14
14
|
|
|
15
15
|
import typer
|
|
16
|
+
from qbraid_core.services.environments.schema import EnvironmentConfig
|
|
16
17
|
from rich.console import Console
|
|
17
18
|
|
|
18
19
|
from qbraid_cli.envs.create import create_qbraid_env_assets, create_venv
|
|
19
20
|
from qbraid_cli.envs.data_handling import get_envs_data as installed_envs_data
|
|
20
21
|
from qbraid_cli.envs.data_handling import validate_env_name
|
|
21
|
-
from qbraid_cli.handlers import QbraidException, run_progress_task
|
|
22
|
+
from qbraid_cli.handlers import QbraidException, handle_error, run_progress_task
|
|
22
23
|
|
|
23
24
|
if TYPE_CHECKING:
|
|
24
25
|
from qbraid_core.services.environments.client import EnvironmentManagerClient as EMC
|
|
@@ -28,18 +29,51 @@ envs_app = typer.Typer(help="Manage qBraid environments.", no_args_is_help=True)
|
|
|
28
29
|
|
|
29
30
|
@envs_app.command(name="create")
|
|
30
31
|
def envs_create( # pylint: disable=too-many-statements
|
|
31
|
-
name: str = typer.Option(
|
|
32
|
-
..., "--name", "-n", help="Name of the environment to create", callback=validate_env_name
|
|
33
|
-
),
|
|
32
|
+
name: str = typer.Option(None, "--name", "-n", help="Name of the environment to create"),
|
|
34
33
|
description: Optional[str] = typer.Option(
|
|
35
34
|
None, "--description", "-d", help="Short description of the environment"
|
|
36
35
|
),
|
|
36
|
+
file_path: str = typer.Option(
|
|
37
|
+
None, "--file", "-f", help="Path to a .yml file containing the environment details"
|
|
38
|
+
),
|
|
37
39
|
auto_confirm: bool = typer.Option(
|
|
38
40
|
False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
|
|
39
41
|
),
|
|
40
42
|
) -> None:
|
|
41
43
|
"""Create a new qBraid environment."""
|
|
42
44
|
env_description = description or ""
|
|
45
|
+
if name:
|
|
46
|
+
if not validate_env_name(name):
|
|
47
|
+
handle_error(
|
|
48
|
+
error_type="ValueError",
|
|
49
|
+
include_traceback=False,
|
|
50
|
+
message=f"Invalid environment name '{name}'. ",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
env_details_in_cli = name is not None and env_description != ""
|
|
54
|
+
custom_env_data = None
|
|
55
|
+
if env_details_in_cli and file_path:
|
|
56
|
+
handle_error(
|
|
57
|
+
error_type="ArgumentConflictError",
|
|
58
|
+
include_traceback=False,
|
|
59
|
+
message="Cannot use --file with --name or --description while creating an environment",
|
|
60
|
+
)
|
|
61
|
+
elif not env_details_in_cli and not file_path:
|
|
62
|
+
handle_error(
|
|
63
|
+
error_type="MalformedCommandError",
|
|
64
|
+
include_traceback=False,
|
|
65
|
+
message="Must provide either --name and --description or --file "
|
|
66
|
+
"while creating an environment",
|
|
67
|
+
)
|
|
68
|
+
else:
|
|
69
|
+
try:
|
|
70
|
+
if file_path:
|
|
71
|
+
custom_env_data: EnvironmentConfig = EnvironmentConfig.from_yaml(file_path)
|
|
72
|
+
except ValueError as err:
|
|
73
|
+
handle_error(error_type="YamlValidationError", message=str(err))
|
|
74
|
+
|
|
75
|
+
if not name:
|
|
76
|
+
name = custom_env_data.name
|
|
43
77
|
|
|
44
78
|
def create_environment(*args, **kwargs) -> "tuple[dict, EMC]":
|
|
45
79
|
"""Create a qBraid environment."""
|
|
@@ -65,10 +99,15 @@ def envs_create( # pylint: disable=too-many-statements
|
|
|
65
99
|
|
|
66
100
|
return env_path, python_version
|
|
67
101
|
|
|
102
|
+
if not custom_env_data:
|
|
103
|
+
custom_env_data = EnvironmentConfig(
|
|
104
|
+
name=name,
|
|
105
|
+
description=env_description,
|
|
106
|
+
)
|
|
107
|
+
|
|
68
108
|
environment, emc = run_progress_task(
|
|
69
109
|
create_environment,
|
|
70
|
-
|
|
71
|
-
env_description,
|
|
110
|
+
custom_env_data,
|
|
72
111
|
description="Validating request...",
|
|
73
112
|
error_message="Failed to create qBraid environment",
|
|
74
113
|
)
|
|
@@ -78,6 +117,7 @@ def envs_create( # pylint: disable=too-many-statements
|
|
|
78
117
|
description="Solving environment...",
|
|
79
118
|
error_message="Failed to create qBraid environment",
|
|
80
119
|
)
|
|
120
|
+
|
|
81
121
|
slug = environment.get("slug")
|
|
82
122
|
display_name = environment.get("displayName")
|
|
83
123
|
prompt = environment.get("prompt")
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Copyright (c) 2024, qBraid Development Team
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Module defining commands in the 'qbraid files' namespace.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import rich
|
|
13
|
+
import typer
|
|
14
|
+
|
|
15
|
+
from qbraid_cli.handlers import run_progress_task
|
|
16
|
+
|
|
17
|
+
files_app = typer.Typer(help="Manage qBraid cloud storage files.", no_args_is_help=True)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@files_app.command(name="upload")
|
|
21
|
+
def files_upload(
|
|
22
|
+
filepath: Path = typer.Argument(
|
|
23
|
+
...,
|
|
24
|
+
exists=True,
|
|
25
|
+
dir_okay=False,
|
|
26
|
+
resolve_path=True,
|
|
27
|
+
help="Local path to the file to upload.",
|
|
28
|
+
),
|
|
29
|
+
namespace: str = typer.Option(
|
|
30
|
+
"user",
|
|
31
|
+
"--namespace",
|
|
32
|
+
"-n",
|
|
33
|
+
help="Target qBraid namespace for the upload.",
|
|
34
|
+
),
|
|
35
|
+
object_path: str = typer.Option(
|
|
36
|
+
None,
|
|
37
|
+
"--object-path",
|
|
38
|
+
"-p",
|
|
39
|
+
help=("Target object path. " "Defaults to original filename in namespace root."),
|
|
40
|
+
),
|
|
41
|
+
overwrite: bool = typer.Option(
|
|
42
|
+
False,
|
|
43
|
+
"--overwrite",
|
|
44
|
+
"-o",
|
|
45
|
+
help="Overwrite existing file if it already exists in the target location.",
|
|
46
|
+
),
|
|
47
|
+
):
|
|
48
|
+
"""Upload a local file to qBraid storage."""
|
|
49
|
+
|
|
50
|
+
def upload_file() -> dict[str, Any]:
|
|
51
|
+
from qbraid_core.services.files import FileManagerClient
|
|
52
|
+
|
|
53
|
+
client = FileManagerClient()
|
|
54
|
+
data = client.upload_file(
|
|
55
|
+
filepath, namespace=namespace, object_path=object_path, overwrite=overwrite
|
|
56
|
+
)
|
|
57
|
+
return data
|
|
58
|
+
|
|
59
|
+
data: dict = run_progress_task(
|
|
60
|
+
upload_file, description="Uploading file...", include_error_traceback=False
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
rich.print("File uploaded successfully!")
|
|
64
|
+
namespace = data.get("namespace")
|
|
65
|
+
object_path = data.get("objectPath")
|
|
66
|
+
|
|
67
|
+
if namespace and object_path:
|
|
68
|
+
rich.print(f"\nNamespace: '{namespace}'")
|
|
69
|
+
rich.print(f"Object path: '{object_path}'")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@files_app.command(name="download")
|
|
73
|
+
def files_download(
|
|
74
|
+
object_path: str = typer.Argument(
|
|
75
|
+
...,
|
|
76
|
+
help="The folder + filename describing the file to download.",
|
|
77
|
+
),
|
|
78
|
+
namespace: str = typer.Option(
|
|
79
|
+
"user",
|
|
80
|
+
"--namespace",
|
|
81
|
+
"-n",
|
|
82
|
+
help="Source qBraid namespace for the download.",
|
|
83
|
+
),
|
|
84
|
+
save_path: Path = typer.Option(
|
|
85
|
+
Path.cwd(),
|
|
86
|
+
"--save-path",
|
|
87
|
+
"-s",
|
|
88
|
+
resolve_path=True,
|
|
89
|
+
help="Local directory to save the downloaded file.",
|
|
90
|
+
),
|
|
91
|
+
overwrite: bool = typer.Option(
|
|
92
|
+
False,
|
|
93
|
+
"--overwrite",
|
|
94
|
+
"-o",
|
|
95
|
+
help="Overwrite existing file if it already exists in the target location.",
|
|
96
|
+
),
|
|
97
|
+
):
|
|
98
|
+
"""Download a file from qBraid storage."""
|
|
99
|
+
|
|
100
|
+
def download_file() -> Path:
|
|
101
|
+
from qbraid_core.services.files import FileManagerClient
|
|
102
|
+
|
|
103
|
+
client = FileManagerClient()
|
|
104
|
+
file_path = client.download_file(
|
|
105
|
+
object_path, namespace=namespace, save_path=save_path, overwrite=overwrite
|
|
106
|
+
)
|
|
107
|
+
return file_path
|
|
108
|
+
|
|
109
|
+
file_path: Path = run_progress_task(
|
|
110
|
+
download_file, description="Downloading file...", include_error_traceback=False
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
rich.print("File downloaded successfully!")
|
|
114
|
+
rich.print(f"Saved to: '{str(file_path)}'")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
files_app()
|
|
@@ -15,6 +15,7 @@ from qbraid_cli.admin import admin_app
|
|
|
15
15
|
from qbraid_cli.chat import ChatFormat, list_models_callback, prompt_callback
|
|
16
16
|
from qbraid_cli.configure import configure_app
|
|
17
17
|
from qbraid_cli.devices import devices_app
|
|
18
|
+
from qbraid_cli.files import files_app
|
|
18
19
|
from qbraid_cli.jobs import jobs_app
|
|
19
20
|
|
|
20
21
|
try:
|
|
@@ -32,6 +33,7 @@ app.add_typer(admin_app, name="admin")
|
|
|
32
33
|
app.add_typer(configure_app, name="configure")
|
|
33
34
|
app.add_typer(account_app, name="account")
|
|
34
35
|
app.add_typer(devices_app, name="devices")
|
|
36
|
+
app.add_typer(files_app, name="files")
|
|
35
37
|
app.add_typer(jobs_app, name="jobs")
|
|
36
38
|
|
|
37
39
|
if ENVS_COMMANDS is True:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qbraid-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
4
4
|
Summary: Command Line Interface for interacting with all parts of the qBraid platform.
|
|
5
5
|
Author-email: qBraid Development Team <contact@qbraid.com>
|
|
6
6
|
License: Proprietary
|
|
@@ -30,7 +30,7 @@ License-File: LICENSE
|
|
|
30
30
|
Requires-Dist: typer>=0.12.1
|
|
31
31
|
Requires-Dist: rich>=10.11.0
|
|
32
32
|
Requires-Dist: click
|
|
33
|
-
Requires-Dist: qbraid-core>=0.1.
|
|
33
|
+
Requires-Dist: qbraid-core>=0.1.33
|
|
34
34
|
Provides-Extra: jobs
|
|
35
35
|
Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
|
|
36
36
|
Provides-Extra: envs
|
|
@@ -58,6 +58,8 @@ qbraid_cli/envs/activate.py
|
|
|
58
58
|
qbraid_cli/envs/app.py
|
|
59
59
|
qbraid_cli/envs/create.py
|
|
60
60
|
qbraid_cli/envs/data_handling.py
|
|
61
|
+
qbraid_cli/files/__init__.py
|
|
62
|
+
qbraid_cli/files/app.py
|
|
61
63
|
qbraid_cli/jobs/__init__.py
|
|
62
64
|
qbraid_cli/jobs/app.py
|
|
63
65
|
qbraid_cli/jobs/toggle_braket.py
|
|
@@ -84,8 +86,11 @@ tests/envs/test_envs_activate.py
|
|
|
84
86
|
tests/envs/test_envs_activate_find_shell_rc.py
|
|
85
87
|
tests/envs/test_envs_activate_print_command.py
|
|
86
88
|
tests/envs/test_envs_activate_pyenv.py
|
|
89
|
+
tests/envs/test_envs_create_from_yaml.py
|
|
87
90
|
tests/envs/test_envs_list.py
|
|
88
91
|
tests/envs/test_envs_remove.py
|
|
92
|
+
tests/files/__init__.py
|
|
93
|
+
tests/files/test_files_commands.py
|
|
89
94
|
tests/jobs/__init__.py
|
|
90
95
|
tests/jobs/test_jobs_disable.py
|
|
91
96
|
tests/jobs/test_jobs_enable.py
|
|
@@ -100,6 +105,9 @@ tests/jobs/test_jobs_validate_handle_state.py
|
|
|
100
105
|
tests/jobs/test_jobs_validate_library.py
|
|
101
106
|
tests/kernels/__init__.py
|
|
102
107
|
tests/kernels/test_kernels_list.py
|
|
108
|
+
tests/resources/envs/correct.yaml
|
|
109
|
+
tests/resources/envs/icon.png
|
|
110
|
+
tests/resources/envs/incorrect.yaml
|
|
103
111
|
tools/bump_version.py
|
|
104
112
|
tools/create_dev_build.sh
|
|
105
113
|
tools/install_wheel_extras.sh
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Copyright (c) 2024, qBraid Development Team
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Unit tests for the `qbraid_cli.envs.app` module's `activate` command.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from unittest.mock import patch
|
|
10
|
+
|
|
11
|
+
from typer.testing import CliRunner
|
|
12
|
+
|
|
13
|
+
from qbraid_cli.envs.app import envs_app
|
|
14
|
+
|
|
15
|
+
runner = CliRunner(mix_stderr=False)
|
|
16
|
+
|
|
17
|
+
MOCK_API_RETURN_OBJ = {
|
|
18
|
+
"description": "This is a test qBraid environment for demonstration purposes.",
|
|
19
|
+
"logo": "test_s3_url",
|
|
20
|
+
"slug": "test_env_slug",
|
|
21
|
+
"displayName": "test_env",
|
|
22
|
+
"kernelName": "sample_kernel",
|
|
23
|
+
"name": "test_env",
|
|
24
|
+
"packagesInImage": {"numpy>=1.21.1", "openqasm3~=0.5.0", "qiskit", "cirq==1.0.0"},
|
|
25
|
+
"prompt": "sample_prompt",
|
|
26
|
+
"tags": ["test", "qbraid", "environment"],
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_invalid_name_raises_error():
|
|
31
|
+
"""Test that an invalid name raises an error."""
|
|
32
|
+
result = runner.invoke(
|
|
33
|
+
envs_app,
|
|
34
|
+
["create", "--name", "invalid large name for environment", "--description", "test"],
|
|
35
|
+
)
|
|
36
|
+
assert result.exit_code == 2
|
|
37
|
+
assert "Invalid environment name " in result.stderr
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# we mock the usage path of the method NOT its definition path
|
|
41
|
+
@patch("qbraid_cli.envs.app.run_progress_task")
|
|
42
|
+
def test_correct_yaml_parse(mock_run_progress_task):
|
|
43
|
+
"""Test that the correct YAML file is parsed correctly."""
|
|
44
|
+
|
|
45
|
+
mock_run_progress_task.side_effect = [
|
|
46
|
+
(MOCK_API_RETURN_OBJ, None),
|
|
47
|
+
(Path("path/to/test_env"), "3.8"),
|
|
48
|
+
None,
|
|
49
|
+
None,
|
|
50
|
+
]
|
|
51
|
+
yaml_file = "resources/envs/correct.yaml"
|
|
52
|
+
file_path = Path(__file__).resolve().parent.parent / yaml_file
|
|
53
|
+
result = runner.invoke(envs_app, ["create", "--file", file_path])
|
|
54
|
+
assert result.exit_code == 0
|
|
55
|
+
expected_outputs = [
|
|
56
|
+
"Successfully created qBraid environment: test_env",
|
|
57
|
+
"name: test_env",
|
|
58
|
+
"description: This is a test qBraid environment for demonstration purposes.",
|
|
59
|
+
"tags: ['test', 'qbraid', 'environment']",
|
|
60
|
+
"slug: test_env_slug",
|
|
61
|
+
"shellPrompt: sample_prompt",
|
|
62
|
+
"kernelName: sample_kernel",
|
|
63
|
+
f"location: {Path('path/to/test_env/test_env_slug')}",
|
|
64
|
+
"version: 3.8",
|
|
65
|
+
]
|
|
66
|
+
for output in expected_outputs:
|
|
67
|
+
assert output in result.stdout
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_invalid_yaml_file_raises_error():
|
|
71
|
+
"""Test that an invalid YAML file raises an error."""
|
|
72
|
+
yaml_file = "resources/envs/incorrect.yaml"
|
|
73
|
+
file_path = Path(__file__).resolve().parent.parent / yaml_file
|
|
74
|
+
result = runner.invoke(envs_app, ["create", "--file", file_path])
|
|
75
|
+
|
|
76
|
+
assert result.exit_code == 1
|
|
77
|
+
assert "Invalid YAML data" in result.stderr
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_no_name_no_file_raises_error():
|
|
81
|
+
"""Test that providing neither a name nor a file raises an error."""
|
|
82
|
+
result = runner.invoke(envs_app, ["create"])
|
|
83
|
+
assert result.exit_code == 1
|
|
84
|
+
assert (
|
|
85
|
+
"Must provide either --name and --description or --file while creating an environment"
|
|
86
|
+
in result.stderr
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_name_with_file_raises_error():
|
|
91
|
+
"""Test that providing both a name and a file raises an error."""
|
|
92
|
+
result = runner.invoke(
|
|
93
|
+
envs_app,
|
|
94
|
+
[
|
|
95
|
+
"create",
|
|
96
|
+
"--name",
|
|
97
|
+
"test_env",
|
|
98
|
+
"--description",
|
|
99
|
+
"test",
|
|
100
|
+
"--file",
|
|
101
|
+
"resources/envs/correct.yaml",
|
|
102
|
+
],
|
|
103
|
+
)
|
|
104
|
+
assert result.exit_code == 1
|
|
105
|
+
assert (
|
|
106
|
+
"Cannot use --file with --name or --description while creating an environment"
|
|
107
|
+
in result.stderr
|
|
108
|
+
)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Copyright (c) 2024, qBraid Development Team
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
# pylint: disable=redefined-outer-name
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Unit tests for the `qbraid_cli.files.app` module.
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from unittest.mock import patch
|
|
12
|
+
|
|
13
|
+
import pytest
|
|
14
|
+
from typer.testing import CliRunner
|
|
15
|
+
|
|
16
|
+
from qbraid_cli.files.app import files_app
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def runner():
|
|
21
|
+
"""Fixture for invoking CLI commands."""
|
|
22
|
+
return CliRunner()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_files_upload(runner, tmp_path):
|
|
26
|
+
"""Test the `files upload` command."""
|
|
27
|
+
test_file = tmp_path / "test_file.txt"
|
|
28
|
+
test_file.write_text("Test content")
|
|
29
|
+
|
|
30
|
+
with patch("qbraid_core.services.files.FileManagerClient") as mock_client:
|
|
31
|
+
mock_client.return_value.upload_file.return_value = {
|
|
32
|
+
"namespace": "user",
|
|
33
|
+
"objectPath": "test_file.txt",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
result = runner.invoke(files_app, ["upload", str(test_file)])
|
|
37
|
+
|
|
38
|
+
assert result.exit_code == 0
|
|
39
|
+
assert "File uploaded successfully!" in result.stdout
|
|
40
|
+
assert "Namespace: 'user'" in result.stdout
|
|
41
|
+
assert "Object path: 'test_file.txt'" in result.stdout
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_files_upload_with_options(runner, tmp_path):
|
|
45
|
+
"""Test the `files upload` command with options."""
|
|
46
|
+
test_file = tmp_path / "test_file.txt"
|
|
47
|
+
test_file.write_text("Test content")
|
|
48
|
+
|
|
49
|
+
with patch("qbraid_core.services.files.FileManagerClient") as mock_client:
|
|
50
|
+
mock_client.return_value.upload_file.return_value = {
|
|
51
|
+
"namespace": "custom",
|
|
52
|
+
"objectPath": "folder/test_file.txt",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
result = runner.invoke(
|
|
56
|
+
files_app,
|
|
57
|
+
[
|
|
58
|
+
"upload",
|
|
59
|
+
str(test_file),
|
|
60
|
+
"--namespace",
|
|
61
|
+
"custom",
|
|
62
|
+
"--object-path",
|
|
63
|
+
"folder/test_file.txt",
|
|
64
|
+
"--overwrite",
|
|
65
|
+
],
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
assert result.exit_code == 0
|
|
69
|
+
assert "File uploaded successfully!" in result.stdout
|
|
70
|
+
assert "Namespace: 'custom'" in result.stdout
|
|
71
|
+
assert "Object path: 'folder/test_file.txt'" in result.stdout
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_files_download(runner, tmp_path):
|
|
75
|
+
"""Test the `files download` command."""
|
|
76
|
+
with patch("qbraid_core.services.files.FileManagerClient") as mock_client:
|
|
77
|
+
mock_client.return_value.download_file.return_value = tmp_path / "downloaded_file.txt"
|
|
78
|
+
|
|
79
|
+
result = runner.invoke(files_app, ["download", "test_file.txt"])
|
|
80
|
+
|
|
81
|
+
assert result.exit_code == 0
|
|
82
|
+
assert "File downloaded successfully!" in result.stdout
|
|
83
|
+
assert f"Saved to: '{(tmp_path / 'downloaded_file.txt')}'" in result.stdout.replace("\n", "")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_files_download_with_options(runner, tmp_path):
|
|
87
|
+
"""Test the `files download` command with options."""
|
|
88
|
+
save_path = tmp_path / "custom_folder"
|
|
89
|
+
save_path.mkdir()
|
|
90
|
+
|
|
91
|
+
with patch("qbraid_core.services.files.FileManagerClient") as mock_client:
|
|
92
|
+
mock_client.return_value.download_file.return_value = save_path / "downloaded_file.txt"
|
|
93
|
+
|
|
94
|
+
result = runner.invoke(
|
|
95
|
+
files_app,
|
|
96
|
+
[
|
|
97
|
+
"download",
|
|
98
|
+
"folder/test_file.txt",
|
|
99
|
+
"--namespace",
|
|
100
|
+
"custom",
|
|
101
|
+
"--save-path",
|
|
102
|
+
str(save_path),
|
|
103
|
+
"--overwrite",
|
|
104
|
+
],
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
assert result.exit_code == 0
|
|
108
|
+
assert "File downloaded successfully!" in result.stdout
|
|
109
|
+
assert f"Saved to: '{(save_path / 'downloaded_file.txt')}'" in result.stdout.replace("\n", "")
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Sample qBraid environment configuration
|
|
2
|
+
name: "test_env"
|
|
3
|
+
description: "This is a test qBraid environment for demonstration purposes."
|
|
4
|
+
tags:
|
|
5
|
+
- "test"
|
|
6
|
+
- "qbraid"
|
|
7
|
+
- "environment"
|
|
8
|
+
icon: "tests/resources/envs/icon.png"
|
|
9
|
+
python_version: "3.8"
|
|
10
|
+
kernel_name: "sample_kernel"
|
|
11
|
+
shell_prompt: "sample_prompt"
|
|
12
|
+
python_packages:
|
|
13
|
+
numpy: ">=1.21.0"
|
|
14
|
+
openqasm3: "~=0.5.0"
|
|
15
|
+
qiskit: ""
|
|
16
|
+
cirq: "1.0.0"
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|