qbraid-cli 0.8.0.dev1__py3-none-any.whl → 0.8.0.dev4__py3-none-any.whl

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/jobs/app.py CHANGED
@@ -1,119 +1,63 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module defining commands in the 'qbraid jobs' namespace.
3
6
 
4
7
  """
5
-
6
- import sys
7
- from typing import Callable, Dict, Optional, Tuple
8
+ from typing import Any, Callable, Dict, Tuple
8
9
 
9
10
  import typer
10
11
  from rich.console import Console
11
12
 
12
- from qbraid_cli.handlers import handle_error, run_progress_task, validate_item
13
-
14
- app = typer.Typer(help="Manage qBraid quantum jobs.")
15
-
16
- QJOB_LIBS = ["braket"]
17
-
18
-
19
- def validate_library(value: str) -> str:
20
- """Validate quantum jobs library."""
21
- return validate_item(value, QJOB_LIBS, "Library")
22
-
13
+ from qbraid_cli.handlers import handle_error, run_progress_task
14
+ from qbraid_cli.jobs.toggle_braket import disable_braket, enable_braket
15
+ from qbraid_cli.jobs.validation import handle_jobs_state, run_progress_get_state, validate_library
23
16
 
24
- def get_state(library: Optional[str] = None) -> Dict[str, Tuple[bool, bool]]:
25
- """Get the state of qBraid Quantum Jobs for the specified library."""
26
- from qbraid.api.system import qbraid_jobs_state
27
-
28
- state_values = {}
29
-
30
- if library:
31
- libraries_to_check = [library]
32
- else:
33
- libraries_to_check = QJOB_LIBS
34
-
35
- for lib in libraries_to_check:
36
- state_values[lib] = qbraid_jobs_state(lib)
37
-
38
- return state_values
39
-
40
-
41
- def run_progress_get_state(library: Optional[str] = None) -> Dict[str, Tuple[bool, bool]]:
42
- """Run get state function with rich progress UI."""
43
- return run_progress_task(
44
- get_state,
45
- library,
46
- description="Collecting package metadata...",
47
- error_message=f"Failed to collect {library} package metadata.",
48
- )
17
+ jobs_app = typer.Typer(help="Manage qBraid quantum jobs.")
49
18
 
50
19
 
51
- def handle_jobs_state(
52
- library: str,
53
- action: str, # 'enable' or 'disable'
54
- action_callback: Callable[[], None],
55
- ) -> None:
56
- """Handle the common logic for enabling or disabling qBraid Quantum Jobs."""
57
- state_values: Dict[str, Tuple[bool, bool]] = run_progress_get_state(library)
58
- installed, enabled = state_values[library]
59
-
60
- if not installed:
61
- handle_error(message=f"{library} not installed.")
62
- if (enabled and action == "enable") or (not enabled and action == "disable"):
63
- action_color = "green" if enabled else "red"
64
- console = Console()
65
- console.print(
66
- f"\nqBraid quantum jobs already [bold {action_color}]{action}d[/bold {action_color}] "
67
- f"for [magenta]{library}[/magenta]."
68
- )
69
- console.print(
70
- "To check the state of all quantum jobs libraries in this environment, "
71
- "use: `[bold]qbraid jobs state[/bold]`"
72
- )
73
- raise typer.Exit()
74
-
75
- action_callback() # Perform the specific enable/disable action
76
-
77
-
78
- @app.command(name="enable")
20
+ @jobs_app.command(name="enable")
79
21
  def jobs_enable(
80
22
  library: str = typer.Argument(
81
23
  ..., help="Software library with quantum jobs support.", callback=validate_library
82
- )
24
+ ),
25
+ auto_confirm: bool = typer.Option(
26
+ False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
27
+ ),
83
28
  ) -> None:
84
29
  """Enable qBraid Quantum Jobs."""
85
30
 
86
31
  def enable_action():
87
32
  if library == "braket":
88
- from .toggle_braket import enable_braket
89
-
90
- enable_braket()
33
+ enable_braket(auto_confirm=auto_confirm)
91
34
  else:
92
35
  raise RuntimeError(f"Unsupported device library: '{library}'.")
93
36
 
94
37
  handle_jobs_state(library, "enable", enable_action)
95
38
 
96
39
 
97
- @app.command(name="disable")
40
+ @jobs_app.command(name="disable")
98
41
  def jobs_disable(
99
42
  library: str = typer.Argument(
100
43
  ..., help="Software library with quantum jobs support.", callback=validate_library
101
- )
44
+ ),
45
+ auto_confirm: bool = typer.Option(
46
+ False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
47
+ ),
102
48
  ) -> None:
103
49
  """Disable qBraid Quantum Jobs."""
104
50
 
105
51
  def disable_action():
106
52
  if library == "braket":
107
- from .toggle_braket import disable_braket
108
-
109
- disable_braket()
53
+ disable_braket(auto_confirm=auto_confirm)
110
54
  else:
111
55
  raise RuntimeError(f"Unsupported device library: '{library}'.")
112
56
 
113
57
  handle_jobs_state(library, "disable", disable_action)
114
58
 
115
59
 
116
- @app.command(name="state")
60
+ @jobs_app.command(name="state")
117
61
  def jobs_state(
118
62
  library: str = typer.Argument(
119
63
  default=None,
@@ -122,7 +66,8 @@ def jobs_state(
122
66
  )
123
67
  ) -> None:
124
68
  """Display the state of qBraid Quantum Jobs for the current environment."""
125
- state_values: Dict[str, Tuple[bool, bool]] = run_progress_get_state(library)
69
+ result: Tuple[str, Dict[str, Tuple[bool, bool]]] = run_progress_get_state(library)
70
+ python_exe, state_values = result
126
71
  state_values = dict(sorted(state_values.items()))
127
72
 
128
73
  console = Console()
@@ -130,7 +75,7 @@ def jobs_state(
130
75
  max_lib_length = max((len(lib) for lib in state_values.keys()), default=len(header_1))
131
76
  padding = max_lib_length + 9
132
77
 
133
- console.print(f"Executable: {sys.executable}")
78
+ console.print(f"Executable: {python_exe}")
134
79
  console.print(f"\n{header_1:<{padding}}{header_2}", style="bold")
135
80
 
136
81
  for lib, (installed, enabled) in state_values.items():
@@ -142,7 +87,7 @@ def jobs_state(
142
87
  console.print(f"{lib:<{padding-1}}", state_str, end="\n")
143
88
 
144
89
 
145
- @app.command(name="list")
90
+ @jobs_app.command(name="list")
146
91
  def jobs_list(
147
92
  limit: int = typer.Option(
148
93
  10, "--limit", "-l", help="Limit the maximum number of results returned"
@@ -150,20 +95,55 @@ def jobs_list(
150
95
  ) -> None:
151
96
  """List qBraid Quantum Jobs."""
152
97
 
153
- def import_jobs() -> Tuple[Callable, Exception]:
154
- from qbraid import get_jobs
155
- from qbraid.exceptions import QbraidError
98
+ def import_jobs() -> Tuple[Any, Callable]:
99
+ from qbraid_core.services.quantum import QuantumClient, process_job_data
100
+
101
+ client = QuantumClient()
156
102
 
157
- return get_jobs, QbraidError
103
+ return client, process_job_data
158
104
 
159
- result: Tuple[Callable, Exception] = run_progress_task(import_jobs)
160
- get_jobs, QbraidError = result
105
+ result: Tuple[Any, Callable] = run_progress_task(import_jobs)
106
+ client, process_job_data = result
107
+ # https://github.com/qBraid/api/issues/644
108
+ # raw_data = client.search_jobs(query={"numResults": limit})
109
+ raw_data = client.search_jobs(query={})
110
+ job_data, msg = process_job_data(raw_data)
111
+ job_data = job_data[:limit]
161
112
 
113
+ longest_job_id = max(len(item[0]) for item in job_data)
114
+ spacing = longest_job_id + 5
162
115
  try:
163
- get_jobs(filters={"numResults": limit})
164
- except QbraidError:
116
+ console = Console()
117
+ header_1 = "Job ID"
118
+ header_2 = "Submitted"
119
+ header_3 = "Status"
120
+ console.print(f"\n[bold]{header_1.ljust(spacing)}{header_2.ljust(36)}{header_3}[/bold]")
121
+ for job_id, submitted, status in job_data:
122
+ if status == "COMPLETED":
123
+ status_color = "green"
124
+ elif status in ["FAILED", "CANCELLED"]:
125
+ status_color = "red"
126
+ elif status in [
127
+ "INITIALIZING",
128
+ "INITIALIZED",
129
+ "CREATED",
130
+ "QUEUED",
131
+ "VALIDATING",
132
+ "RUNNING",
133
+ ]:
134
+ status_color = "blue"
135
+ else:
136
+ status_color = "grey"
137
+ console.print(
138
+ f"{job_id.ljust(spacing)}{submitted.ljust(35)}",
139
+ f"[{status_color}]{status}[/{status_color}]",
140
+ )
141
+
142
+ console.print(f"\n{msg}", style="italic", justify="left")
143
+
144
+ except Exception: # pylint: disable=broad-exception-caught
165
145
  handle_error(message="Failed to fetch quantum jobs.")
166
146
 
167
147
 
168
148
  if __name__ == "__main__":
169
- app()
149
+ jobs_app()
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module supporting 'qbraid jobs enable/disable braket' and commands.
3
6
 
@@ -6,7 +9,6 @@ Module supporting 'qbraid jobs enable/disable braket' and commands.
6
9
  import logging
7
10
  import os
8
11
  import subprocess
9
- import sys
10
12
  from pathlib import Path
11
13
  from typing import Optional, Tuple
12
14
 
@@ -19,39 +21,38 @@ logging.basicConfig(level=logging.INFO)
19
21
  logger = logging.getLogger(__name__)
20
22
 
21
23
 
22
- def get_package_data(package: str) -> Tuple[str, str, str]:
24
+ def get_package_data(package: str) -> Tuple[str, str, str, str]:
23
25
  """Retrieve package version and location data.
24
26
 
25
27
  Args:
26
28
  package (str): The name of the package to retrieve data for.
27
29
 
28
30
  Returns:
29
- Tuple[str, str, str]: The installed and latest versions of the package, and the
30
- local site-packages path where it is / would be installed.
31
+ Tuple[str, str, str, str]: The installed and latest versions of the package, and the
32
+ local site-packages path where it is / would be installed.
31
33
 
32
34
  Raises:
33
35
  QbraidException: If package version or location data cannot be retrieved.
34
36
 
35
37
  """
36
- from qbraid.api.system import (
38
+ # pylint: disable=import-outside-toplevel
39
+ from qbraid_core.system import (
40
+ QbraidSystemError,
41
+ get_active_python_path,
37
42
  get_active_site_packages_path,
38
43
  get_latest_package_version,
39
44
  get_local_package_version,
40
45
  )
41
- from qbraid.exceptions import QbraidError
42
46
 
43
47
  try:
44
- installed_version = get_local_package_version(package)
48
+ python_pathlib = get_active_python_path()
49
+ site_packages_path = get_active_site_packages_path(python_path=python_pathlib)
50
+ installed_version = get_local_package_version(package, python_path=python_pathlib)
45
51
  latest_version = get_latest_package_version(package)
46
- except QbraidError as err:
47
- raise QbraidException("Failed to retrieve package version information") from err
48
-
49
- try:
50
- site_packages_path = get_active_site_packages_path()
51
- except QbraidError as err:
52
- raise QbraidException("Failed to retrieve site-package location") from err
52
+ except QbraidSystemError as err:
53
+ raise QbraidException("Failed to retrieve required system and/or package metadata") from err
53
54
 
54
- return installed_version, latest_version, site_packages_path
55
+ return installed_version, latest_version, str(site_packages_path), str(python_pathlib)
55
56
 
56
57
 
57
58
  def confirm_updates(
@@ -70,9 +71,6 @@ def confirm_updates(
70
71
  installed_version (optional, str): The installed version of the target package.
71
72
  latest_version (optional, str): The latest version of the target package available on PyPI.
72
73
 
73
- Returns:
74
- None
75
-
76
74
  Raises:
77
75
  ValueError: If an invalid mode is provided.
78
76
  typer.Exit: If the user declines to proceed with enabling or disabling qBraid Quantum Jobs.
@@ -117,8 +115,6 @@ def confirm_updates(
117
115
  typer.echo("\nqBraidSystemExit: Exiting.")
118
116
  raise typer.Exit()
119
117
 
120
- typer.echo("")
121
-
122
118
 
123
119
  def aws_configure_dummy() -> None:
124
120
  """
@@ -154,44 +150,47 @@ def aws_configure_dummy() -> None:
154
150
  handle_error(message="Failed to configure qBraid quantum jobs.")
155
151
 
156
152
 
157
- def enable_braket():
153
+ def enable_braket(auto_confirm: bool = False):
158
154
  """Enable qBraid quantum jobs for Amazon Braket."""
159
- installed_version, latest_version, site_packages_path = run_progress_task(
155
+ installed, latest, path, python_exe = run_progress_task(
160
156
  get_package_data, "boto3", description="Solving environment..."
161
157
  )
162
- confirm_updates("enable", site_packages_path, installed_version, latest_version)
158
+
159
+ if not auto_confirm:
160
+ confirm_updates("enable", path, installed_version=installed, latest_version=latest)
161
+ typer.echo("")
162
+
163
163
  aws_configure_dummy() # TODO: possibly add another confirmation for writing aws config files
164
164
 
165
165
  try:
166
- subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "boto3"])
167
- subprocess.check_call(
168
- [sys.executable, "-m", "pip", "uninstall", "botocore", "-y", "--quiet"]
169
- )
166
+ subprocess.check_call([python_exe, "-m", "pip", "install", "--upgrade", "boto3"])
167
+ subprocess.check_call([python_exe, "-m", "pip", "uninstall", "botocore", "-y", "--quiet"])
170
168
  subprocess.check_call(
171
- [sys.executable, "-m", "pip", "install", "git+https://github.com/qBraid/botocore.git"]
169
+ [python_exe, "-m", "pip", "install", "git+https://github.com/qBraid/botocore.git"]
172
170
  )
173
- except subprocess.CalledProcessError:
171
+ except (subprocess.CalledProcessError, FileNotFoundError):
174
172
  handle_error(message="Failed to enable qBraid quantum jobs.")
175
173
 
176
174
  typer.secho("\nSuccessfully enabled qBraid quantum jobs.", fg=typer.colors.GREEN, bold=True)
177
- typer.secho(
178
- "\nTo disable, run: `qbraid jobs disable braket`\n", fg=typer.colors.GREEN, bold=True
179
- )
175
+ typer.secho("\nTo disable, run: \n\n\t$ qbraid jobs disable braket\n")
180
176
 
181
177
 
182
- def disable_braket():
178
+ def disable_braket(auto_confirm: bool = False):
183
179
  """Disable qBraid quantum jobs for Amazon Braket."""
184
180
  package = "botocore"
185
- installed_version, latest_version, site_packages_path = run_progress_task(
181
+ installed, latest, path, python_exe = run_progress_task(
186
182
  get_package_data, package, description="Solving environment..."
187
183
  )
188
- package = f"{package}~={installed_version}" if installed_version < latest_version else package
189
- confirm_updates("disable", site_packages_path)
184
+ package = f"{package}~={installed}" if installed < latest else package
185
+
186
+ if not auto_confirm:
187
+ confirm_updates("disable", path)
188
+ typer.echo("")
190
189
 
191
190
  try:
192
191
  subprocess.check_call(
193
192
  [
194
- sys.executable,
193
+ python_exe,
195
194
  "-m",
196
195
  "pip",
197
196
  "install",
@@ -200,8 +199,8 @@ def disable_braket():
200
199
  ],
201
200
  stderr=subprocess.DEVNULL,
202
201
  )
203
- except subprocess.CalledProcessError:
202
+ except (subprocess.CalledProcessError, FileNotFoundError):
204
203
  handle_error(message="Failed to disable qBraid quantum jobs.")
205
204
 
206
205
  typer.secho("\nSuccessfully disabled qBraid quantum jobs.", fg=typer.colors.GREEN, bold=True)
207
- typer.secho("\nTo enable, run: `qbraid jobs enable braket`\n", fg=typer.colors.GREEN, bold=True)
206
+ typer.secho("\nTo enable, run: \n\n\t$ qbraid jobs enable braket\n")
@@ -0,0 +1,93 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ Module for validating command arguments for qBraid Quantum Jobs.
6
+
7
+ """
8
+ import sys
9
+ from typing import Any, Callable, Dict, Optional, Tuple
10
+
11
+ import typer
12
+ from rich.console import Console
13
+
14
+ from qbraid_cli.handlers import handle_error, run_progress_task, validate_item
15
+
16
+ LEGACY_ARGS: Dict[str, str] = {
17
+ "amazon_braket": "braket",
18
+ "aws_braket": "braket",
19
+ }
20
+
21
+
22
+ def validate_library(value: str) -> str:
23
+ """Validate quantum jobs library."""
24
+ # pylint:disable-next=import-outside-toplevel
25
+ from qbraid_core.services.quantum.proxy import SUPPORTED_QJOB_LIBS
26
+
27
+ qjobs_libs = list(SUPPORTED_QJOB_LIBS.keys())
28
+
29
+ if value in LEGACY_ARGS:
30
+ old_value = value
31
+ value = LEGACY_ARGS[value]
32
+
33
+ console = Console()
34
+ console.print(
35
+ f"[red]DeprecationWarning:[/red] Argument '{old_value}' "
36
+ f"is deprecated. Use '{value}' instead.\n"
37
+ )
38
+
39
+ return validate_item(value, qjobs_libs, "Library")
40
+
41
+
42
+ def get_state(library: Optional[str] = None) -> Tuple[str, Dict[str, Tuple[bool, bool]]]:
43
+ """Get the state of qBraid Quantum Jobs for the specified library."""
44
+ from qbraid_core.services.quantum import QuantumClient
45
+
46
+ jobs_state = QuantumClient.qbraid_jobs_state(device_lib=library)
47
+
48
+ python_exe: str = jobs_state.get("exe", sys.executable)
49
+ libs_state: Dict[str, Any] = jobs_state.get("libs", {})
50
+
51
+ state_values = {
52
+ lib: (state["supported"], state["enabled"]) for lib, state in libs_state.items()
53
+ }
54
+
55
+ return python_exe, state_values
56
+
57
+
58
+ def run_progress_get_state(
59
+ library: Optional[str] = None,
60
+ ) -> Tuple[str, Dict[str, Tuple[bool, bool]]]:
61
+ """Run get state function with rich progress UI."""
62
+ return run_progress_task(
63
+ get_state,
64
+ library,
65
+ description="Collecting package metadata...",
66
+ error_message=f"Failed to collect {library} package metadata.",
67
+ )
68
+
69
+
70
+ def handle_jobs_state(
71
+ library: str,
72
+ action: str, # 'enable' or 'disable'
73
+ action_callback: Callable[[], None],
74
+ ) -> None:
75
+ """Handle the common logic for enabling or disabling qBraid Quantum Jobs."""
76
+ _, state_values = run_progress_get_state(library)
77
+ installed, enabled = state_values[library]
78
+
79
+ if not installed:
80
+ handle_error(
81
+ message=f"{library} not installed."
82
+ ) # TODO: Provide command to install library?
83
+ if (enabled and action == "enable") or (not enabled and action == "disable"):
84
+ action_color = "green" if enabled else "red"
85
+ console = Console()
86
+ console.print(
87
+ f"\nqBraid quantum jobs already [bold {action_color}]{action}d[/bold {action_color}] "
88
+ f"for [magenta]{library}[/magenta].\n\nCheck the state of all quantum jobs "
89
+ "libraries in this environment with: \n\n\t$ qbraid jobs state\n"
90
+ )
91
+ raise typer.Exit()
92
+
93
+ action_callback() # Perform the specific enable/disable action
@@ -1,6 +1,9 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module defining the qbraid kernels namespace
3
6
 
4
7
  """
5
8
 
6
- from .app import app
9
+ from .app import kernels_app
qbraid_cli/kernels/app.py CHANGED
@@ -1,42 +1,111 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module defining commands in the 'qbraid jobs' namespace.
3
6
 
4
7
  """
8
+ import sys
9
+ from pathlib import Path
5
10
 
6
11
  import typer
12
+ from jupyter_client.kernelspec import KernelSpecManager
13
+ from rich.console import Console
14
+
15
+ from qbraid_cli.envs.data_handling import installed_envs_data
16
+ from qbraid_cli.handlers import handle_error
17
+
18
+ kernels_app = typer.Typer(help="Manage qBraid kernels.")
19
+
20
+
21
+ def _get_kernels_path(environment: str) -> Path:
22
+ """Get the path to the kernels directory for the given environment."""
23
+ slug_to_path, name_to_slug = installed_envs_data()
24
+
25
+ if environment in name_to_slug:
26
+ slug = name_to_slug.get(environment, None)
27
+ else:
28
+ slug = environment
7
29
 
8
- app = typer.Typer(help="Manage qBraid kernels.")
30
+ if slug not in slug_to_path:
31
+ raise ValueError(f"Environment '{environment}' not found.")
9
32
 
33
+ env_path = slug_to_path[slug]
34
+ kernels_path = env_path / "kernels"
35
+ return kernels_path
10
36
 
11
- @app.command(name="list")
37
+
38
+ @kernels_app.command(name="list")
12
39
  def kernels_list():
13
40
  """List all available kernels."""
14
- from jupyter_client.kernelspec import KernelSpecManager
41
+ console = Console()
15
42
 
16
43
  kernel_spec_manager = KernelSpecManager()
17
44
  kernelspecs = kernel_spec_manager.get_all_specs()
18
45
 
19
46
  if len(kernelspecs) == 0:
20
- print("No qBraid kernels active.")
21
- # print("\nUse 'qbraid kernels add' to add a new kernel.")
47
+ console.print("No qBraid kernels are active.")
48
+ console.print("\nUse 'qbraid kernels add' to add a new kernel.")
22
49
  return
23
50
 
24
51
  longest_kernel_name = max(len(kernel_name) for kernel_name in kernelspecs)
25
52
  spacing = longest_kernel_name + 10
26
53
 
27
- print("# qbraid kernels:")
28
- print("#")
29
- print("")
54
+ console.print("# qbraid kernels:\n#\n")
30
55
 
31
56
  # Ensure 'python3' kernel is printed first if it exists
32
- python3_kernel_info = kernelspecs.pop("python3", None)
57
+ default_kernel_name = "python3"
58
+ python3_kernel_info = kernelspecs.pop(default_kernel_name, None)
33
59
  if python3_kernel_info:
34
- print("python3".ljust(spacing) + python3_kernel_info["resource_dir"])
60
+ console.print(f"{default_kernel_name.ljust(spacing)}{python3_kernel_info['resource_dir']}")
35
61
 
36
62
  # Print the rest of the kernels
37
63
  for kernel_name, kernel_info in sorted(kernelspecs.items()):
38
- print(f"{kernel_name.ljust(spacing)}{kernel_info['resource_dir']}")
64
+ console.print(f"{kernel_name.ljust(spacing)}{kernel_info['resource_dir']}")
65
+
66
+
67
+ @kernels_app.command(name="add")
68
+ def kernels_add(
69
+ environment: str = typer.Argument(
70
+ ..., help="Name of environment for which to add ipykernel. Values from 'qbraid envs list'."
71
+ )
72
+ ):
73
+ """Add a kernel."""
74
+
75
+ try:
76
+ kernels_path = _get_kernels_path(environment)
77
+ except ValueError:
78
+ handle_error(message=f"Environment '{environment}' not found.", include_traceback=False)
79
+ return
80
+
81
+ is_local = str(kernels_path).startswith(str(Path.home()))
82
+ resource_path = str(Path.home() / ".local") if is_local else sys.prefix
83
+
84
+ kernel_spec_manager = KernelSpecManager()
85
+
86
+ for kernel in kernels_path.iterdir():
87
+ kernel_spec_manager.install_kernel_spec(source_dir=str(kernel), prefix=resource_path)
88
+
89
+
90
+ @kernels_app.command(name="remove")
91
+ def kernels_remove(
92
+ environment: str = typer.Argument(
93
+ ...,
94
+ help=("Name of environment for which to remove ipykernel. Values from 'qbraid envs list'."),
95
+ )
96
+ ):
97
+ """Remove a kernel."""
98
+ try:
99
+ kernels_path = _get_kernels_path(environment)
100
+ except ValueError:
101
+ handle_error(message=f"Environment '{environment}' not found.", include_traceback=False)
102
+ return
103
+
104
+ kernel_spec_manager = KernelSpecManager()
105
+
106
+ for kernel in kernels_path.iterdir():
107
+ kernel_spec_manager.remove_kernel_spec(kernel.name)
39
108
 
40
109
 
41
110
  if __name__ == "__main__":
42
- app()
111
+ kernels_app()
qbraid_cli/main.py CHANGED
@@ -1,18 +1,22 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Entrypoint for the qBraid CLI.
3
6
 
4
7
  """
5
8
 
6
9
  import typer
10
+ import urllib3
7
11
 
8
- from .configure import app as configure_app
9
- from .credits import app as credits_app
10
- from .devices import app as devices_app
11
- from .envs import app as envs_app
12
- from .jobs import app as jobs_app
13
- from .kernels import app as kernels_app
12
+ from qbraid_cli.configure.app import configure_app
13
+ from qbraid_cli.credits.app import credits_app
14
+ from qbraid_cli.devices.app import devices_app
15
+ from qbraid_cli.envs.app import envs_app
16
+ from qbraid_cli.jobs.app import jobs_app
17
+ from qbraid_cli.kernels.app import kernels_app
14
18
 
15
- app = typer.Typer()
19
+ app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})
16
20
  app.add_typer(configure_app, name="configure")
17
21
  app.add_typer(envs_app, name="envs")
18
22
  app.add_typer(jobs_app, name="jobs")
@@ -20,6 +24,8 @@ app.add_typer(devices_app, name="devices")
20
24
  app.add_typer(kernels_app, name="kernels")
21
25
  app.add_typer(credits_app, name="credits")
22
26
 
27
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
28
+
23
29
 
24
30
  def version_callback(value: bool):
25
31
  """Show the version and exit."""
@@ -50,7 +56,7 @@ def show_banner():
50
56
  typer.echo("")
51
57
  typer.echo("- Use 'qbraid --version' to see the current version.")
52
58
  typer.echo("")
53
- typer.echo("Reference Docs: https://docs.qbraid.com/projects/cli/en/latest/cli/qbraid.html")
59
+ typer.echo("Reference Docs: https://docs.qbraid.com/projects/cli/en/stable/guide/overview.html")
54
60
 
55
61
 
56
62
  @app.callback(invoke_without_command=True)
@@ -59,6 +65,7 @@ def main(
59
65
  version: bool = typer.Option(
60
66
  None,
61
67
  "--version",
68
+ "-v",
62
69
  callback=version_callback,
63
70
  is_eager=True,
64
71
  help="Show the version and exit.",