qbraid-cli 0.8.0.dev7__py3-none-any.whl → 0.8.1a0__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/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.8.0.dev7'
16
- __version_tuple__ = version_tuple = (0, 8, 0, 'dev7')
15
+ __version__ = version = '0.8.1a0'
16
+ __version_tuple__ = version_tuple = (0, 8, 1)
@@ -6,11 +6,13 @@ Script to verify qBraid copyright file headers
6
6
 
7
7
  """
8
8
  import os
9
- import sys
10
9
  from typing import List, Optional
11
10
 
11
+ import typer
12
12
  from rich.console import Console
13
13
 
14
+ from qbraid_cli.handlers import handle_error
15
+
14
16
  # pylint: disable=too-many-branches,too-many-statements
15
17
 
16
18
  DEFAULT_HEADER = """# Copyright (c) 2024, qBraid Development Team
@@ -43,19 +45,17 @@ def check_and_fix_headers(
43
45
  """Script to add or verify qBraid copyright file headers"""
44
46
  try:
45
47
  header = HEADER_TYPES[header_type]
46
- except KeyError as err:
47
- raise ValueError(
48
- f"Invalid header type: {HEADER_TYPES}. Expected one of {list(HEADER_TYPES.keys())}"
49
- ) from err
48
+ except KeyError:
49
+ handle_error(
50
+ error_type="ValueError",
51
+ message=(
52
+ f"Invalid header type: {HEADER_TYPES}. Expected one of {list(HEADER_TYPES.keys())}"
53
+ ),
54
+ )
50
55
 
51
56
  for path in src_paths:
52
57
  if not os.path.exists(path):
53
- sys.stderr.write(
54
- f"Usage: qbraid verify_headers [OPTIONS] SRC ...\n"
55
- f"Try 'qbraid verify_headers --help' for help.\n\n"
56
- f"Error: Invalid value for 'SRC ...': Path '{path}' does not exist.\n"
57
- )
58
- sys.exit(1)
58
+ handle_error(error_type="FileNotFoundError", message=f"Path '{path}' does not exist.")
59
59
 
60
60
  header_2023 = header.replace("2024", "2023")
61
61
 
@@ -139,8 +139,11 @@ def check_and_fix_headers(
139
139
  replace_or_add_header(item, fix)
140
140
  checked += 1
141
141
  else:
142
- failed_headers.append(item)
143
- print(f"File or directory not found: {item}")
142
+ handle_error(error_type="FileNotFoundError", message=f"Path '{item}' does not exist.")
143
+
144
+ if checked == 0:
145
+ console.print("[bold]No Python files present. Nothing to do[/bold] 😴")
146
+ raise typer.Exit(0)
144
147
 
145
148
  if not fix:
146
149
  if failed_headers:
@@ -160,34 +163,31 @@ def check_and_fix_headers(
160
163
 
161
164
  failed_msg = f"[bold][blue]{num_failed}[/blue] file{s1} need{s2} updating{punc}[/bold]"
162
165
  console.print(f"{failed_msg}{passed_msg}")
163
- elif checked == 0:
164
- console.print("[bold]No Python files present. Nothing to do[/bold] 😴")
165
- else:
166
- s_checked = "" if checked == 1 else "s"
167
- console.print("[bold]All done![/bold] 🚀 ")
168
- console.print(f"[blue]{checked}[/blue] file{s_checked} would be left unchanged.")
169
-
166
+ raise typer.Exit(1)
167
+
168
+ s_checked = "" if checked == 1 else "s"
169
+ console.print("[bold]All done![/bold] 🚀 ")
170
+ console.print(f"[blue]{checked}[/blue] file{s_checked} would be left unchanged.")
171
+ raise typer.Exit(0)
172
+
173
+ for file in fixed_headers:
174
+ console.print(f"[bold]fixed {file}[/bold]")
175
+ num_fixed = len(fixed_headers)
176
+ num_ok = checked - num_fixed
177
+ s_fixed = "" if num_fixed == 1 else "s"
178
+ s_ok = "" if num_ok == 1 else "s"
179
+ console.print("\n[bold]All done![/bold] ✨ 🚀 ✨")
180
+ if num_ok > 0:
181
+ punc = ", "
182
+ unchanged_msg = f"[blue]{num_ok}[/blue] file{s_ok} left unchanged."
170
183
  else:
171
- for file in fixed_headers:
172
- console.print(f"[bold]fixed {file}[/bold]")
173
- num_fixed = len(fixed_headers)
174
- num_ok = checked - num_fixed
175
- s_fixed = "" if num_fixed == 1 else "s"
176
- s_ok = "" if num_ok == 1 else "s"
177
- console.print("\n[bold]All done![/bold] ✨ 🚀 ✨")
178
- if num_ok > 0:
179
- punc = ", "
180
- unchanged_msg = f"[blue]{num_ok}[/blue] file{s_ok} left unchanged."
181
- else:
182
- punc = "."
183
- unchanged_msg = ""
184
+ punc = "."
185
+ unchanged_msg = ""
184
186
 
185
- if num_fixed > 0:
186
- fixed_msg = f"[bold][blue]{num_fixed}[/blue] file{s_fixed} fixed{punc}[/bold]"
187
- else:
188
- fixed_msg = ""
187
+ if num_fixed > 0:
188
+ fixed_msg = f"[bold][blue]{num_fixed}[/blue] file{s_fixed} fixed{punc}[/bold]"
189
+ else:
190
+ fixed_msg = ""
189
191
 
190
- if fixed_msg or unchanged_msg:
191
- console.print(f"{fixed_msg}{unchanged_msg}")
192
- else:
193
- console.print("[bold]No Python files present. Nothing to do[/bold] 😴")
192
+ console.print(f"{fixed_msg}{unchanged_msg}")
193
+ raise typer.Exit(0)
qbraid_cli/credits/app.py CHANGED
@@ -24,8 +24,11 @@ def credits_value():
24
24
  return client.user_credits_value()
25
25
 
26
26
  qbraid_credits: float = run_progress_task(get_credits)
27
- credits_text = typer.style(f"{qbraid_credits:.2f}", fg=typer.colors.GREEN, bold=True)
28
- typer.secho(f"\nqBraid credits: {credits_text}")
27
+ typer.secho(
28
+ f"\n{typer.style('qBraid credits remaining:')} "
29
+ f"{typer.style(f'{qbraid_credits:.4f}', fg=typer.colors.MAGENTA, bold=True)}",
30
+ nl=True, # Ensure a newline after output (default is True)
31
+ )
29
32
 
30
33
 
31
34
  if __name__ == "__main__":
qbraid_cli/handlers.py CHANGED
@@ -7,6 +7,7 @@ and executing operations with progress tracking within the qBraid CLI.
7
7
 
8
8
  """
9
9
 
10
+ import os
10
11
  import traceback
11
12
  from pathlib import Path
12
13
  from typing import Any, Callable, List, Optional, Union
@@ -18,6 +19,11 @@ from rich.progress import Progress, SpinnerColumn, TextColumn
18
19
  from .exceptions import DEFAULT_ERROR_MESSAGE, QbraidException
19
20
 
20
21
 
22
+ def _should_display_progress():
23
+ """Whether to display rich progress UI."""
24
+ return os.getenv("QBRAID_CLI_SHOW_PROGRESS", "true").lower() in ["true", "1", "t", "y", "yes"]
25
+
26
+
21
27
  def handle_error(
22
28
  error_type: Optional[str] = None, message: Optional[str] = None, include_traceback: bool = True
23
29
  ) -> None:
@@ -104,6 +110,13 @@ def run_progress_task(
104
110
  Raises:
105
111
  typer.Exit: If the operation fails, after displaying the error message using typer.secho.
106
112
  """
113
+ if not _should_display_progress():
114
+ try:
115
+ return operation(*args, **kwargs)
116
+ except Exception as err: # pylint: disable=broad-exception-caught
117
+ custom_message = error_message if error_message else str(err)
118
+ return handle_error(message=custom_message)
119
+
107
120
  console = Console()
108
121
  with Progress(
109
122
  "[progress.description]{task.description}",
@@ -117,9 +130,9 @@ def run_progress_task(
117
130
  result = operation(*args, **kwargs)
118
131
  progress.update(task, completed=100, status="Done")
119
132
  return result
120
- except Exception as e: # pylint: disable=broad-exception-caught
133
+ except Exception as err: # pylint: disable=broad-exception-caught
121
134
  progress.update(task, completed=100, status="Failed")
122
- custom_message = error_message if error_message else str(e)
135
+ custom_message = error_message if error_message else str(err)
123
136
  return handle_error(message=custom_message)
124
137
 
125
138
 
qbraid_cli/main.py CHANGED
@@ -30,10 +30,11 @@ app.add_typer(kernels_app, name="kernels")
30
30
  def version_callback(value: bool):
31
31
  """Show the version and exit."""
32
32
  if value:
33
- from ._version import __version__
33
+ # pylint: disable-next=import-error
34
+ from ._version import __version__ # type: ignore
34
35
 
35
36
  typer.echo(f"qbraid-cli/{__version__}")
36
- raise typer.Exit()
37
+ raise typer.Exit(0)
37
38
 
38
39
 
39
40
  def show_banner():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qbraid-cli
3
- Version: 0.8.0.dev7
3
+ Version: 0.8.1a0
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
@@ -37,7 +37,7 @@ Requires-Dist: isort ; extra == 'dev'
37
37
  Requires-Dist: pylint ; extra == 'dev'
38
38
  Requires-Dist: pytest ; extra == 'dev'
39
39
  Provides-Extra: docs
40
- Requires-Dist: sphinx ~=7.2.6 ; extra == 'docs'
40
+ Requires-Dist: sphinx <7.4.0,>=7.2.6 ; extra == 'docs'
41
41
  Requires-Dist: sphinx-rtd-theme <2.1,>=1.3 ; extra == 'docs'
42
42
  Requires-Dist: docutils <0.22 ; extra == 'docs'
43
43
  Requires-Dist: toml ; extra == 'docs'
@@ -58,17 +58,37 @@ Requires-Dist: amazon-braket-sdk >=1.48.1 ; extra == 'jobs'
58
58
 
59
59
  Command Line Interface for interacting with all parts of the qBraid platform.
60
60
 
61
- The **qBraid CLI** is a specialized command-line interface tool designed *exclusively* for use within the [qBraid Lab](https://docs.qbraid.com/projects/lab/en/latest/lab/overview.html) platform. It is not intended for local installations or use outside the qBraid Lab environment. This tool ensures seamless integration and optimized performance specifically tailored for qBraid Lab's unique cloud-based quantum computing ecosystem.
61
+ The **qBraid CLI** is a versatile command-line interface tool designed for seamless interaction with qBraid cloud services and quantum software management tools. Initially exclusive to the [qBraid Lab](https://docs.qbraid.com/projects/lab/en/latest/lab/overview.html) platform, the CLI now supports local installations as well. This enhancement broadens access to features like [qBraid Quantum Jobs](https://docs.qbraid.com/projects/lab/en/latest/lab/quantum_jobs.html), enabling direct acess to QPU devices from leading providers like IonQ, Oxford Quantum Circuits, QuEra, and Rigetti, as well as on-demand simulators from AWS, all using qBraid credits, with no additional access keys required.
62
62
 
63
63
  ## Getting Started
64
64
 
65
- To use the qBraid CLI, login to qBraid (or create an account), launch Lab, and then open Terminal. You can also access the CLI directly from within [Notebooks](https://docs.qbraid.com/projects/lab/en/latest/lab/notebooks.html) using the ``!`` operator. See [quantum jobs example](https://github.com/qBraid/qbraid-lab-demo/blob/045c7a8fbdcae66a7e64533dd9fe0e981dc02cf4/qbraid_lab/quantum_jobs/aws_quantum_jobs.ipynb).
65
+ The qBraid-CLI comes pre-installed and pre-configured in qBraid Lab:
66
66
 
67
67
  - [Launch qBraid Lab &rarr;](https://lab.qbraid.com/)
68
68
  - [Make an account &rarr;](https://account.qbraid.com/)
69
69
 
70
70
  For help, see qBraid Lab User Guide: [Getting Started](https://docs.qbraid.com/projects/lab/en/latest/lab/getting_started.html).
71
71
 
72
+ You can also install the qBraid-CLI from PyPI with:
73
+
74
+ ```shell
75
+ pip install qbraid-cli
76
+ ```
77
+
78
+ ## Local configuration
79
+
80
+ After installation, you must configure your account credentials to use the CLI locally:
81
+
82
+ 1. Create a qBraid account or log in to your existing account by visiting
83
+ [account.qbraid.com](https://account.qbraid.com/)
84
+ 2. Copy your API Key token from the left side of
85
+ your [account page](https://account.qbraid.com/):
86
+ 3. Save your API key from step 2 in local configuration file `~/.qbraid/qbraidrc` using:
87
+
88
+ ```shell
89
+ $ qbraid configure
90
+ ```
91
+
72
92
  ## Basic Commands
73
93
 
74
94
  ```shell
@@ -141,3 +161,25 @@ To get the version of the qBraid CLI:
141
161
  ```shell
142
162
  $ qbraid --version
143
163
  ```
164
+
165
+ ## Magic Commands
166
+
167
+ You can also access the CLI directly from within [Notebooks](https://docs.qbraid.com/projects/lab/en/latest/lab/notebooks.html) using IPython [magic commands](https://ipython.readthedocs.io/en/stable/interactive/magics.html). First, configure the qBraid magic commands extension using:
168
+
169
+ ```shell
170
+ $ qbraid configure magic
171
+ ```
172
+
173
+ The above command can also be executed from within a Jupyter notebook using the ``!`` operator. Then, from within a notebook cell, load the qBraid magic IPython extension using:
174
+
175
+ ```python
176
+ In [1]: %load_ext qbraid_magic
177
+ ```
178
+
179
+ Now you can continue to use the qBraid-CLI as normal from within your Jupyter notebook using the magic ``%`` operator, e.g.
180
+
181
+ ```python
182
+ In [2]: %qbraid jobs state
183
+
184
+ In [3]: %qbraid jobs enable braket -y
185
+ ```
@@ -1,17 +1,17 @@
1
1
  qbraid_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- qbraid_cli/_version.py,sha256=LlNqfqEKaHtz__4TUC6OnHia_u-wZZrbjkS5UKENpH0,424
2
+ qbraid_cli/_version.py,sha256=uh6qRUKYp5CUuk-ID8cyEoLnsVpY7iGTUwo68466d6k,413
3
3
  qbraid_cli/exceptions.py,sha256=KjlhYJhSHMVazaNiBjD_Ur06w4sekP8zRsFzBdyIpno,672
4
- qbraid_cli/handlers.py,sha256=i3vdRtdy4bZKg3j6fwfVMz1ddhMgzlc2hhmj-vewxpI,6542
5
- qbraid_cli/main.py,sha256=IRKazFqtFpoiq_xOtqb-IXDKAVs4lacFIRCQCoiGNF4,2503
4
+ qbraid_cli/handlers.py,sha256=glxTEwxax3zKgYl9qsZ2evZXgrWQrseJS_OGyHTMFeA,7040
5
+ qbraid_cli/main.py,sha256=R26PkxijuuCzcW_PVREHb11oNlNN2rWDcRY7BmiDV0Q,2564
6
6
  qbraid_cli/admin/__init__.py,sha256=Suo_L1_yBodCvLM_fpw8gRIhD4mVVOXKObtxeoMaBVo,150
7
7
  qbraid_cli/admin/app.py,sha256=__6lo-iFsbfz-ayD1-AS8X1z_gYhCad1NK17hnrL7HY,1451
8
- qbraid_cli/admin/headers.py,sha256=oE2Ry9221ZV4tgYqFJNHAPilDw72xR3LqG_gBw7BFxM,6667
8
+ qbraid_cli/admin/headers.py,sha256=E6mE3odZL57VfHHZxYtRUkqMKmrmT4zuUoINzI7eJF8,6435
9
9
  qbraid_cli/admin/validation.py,sha256=LkAVXlHtM0MhCa34MIWrfX59wGXMVlZmdVB4-AQ8fBk,1003
10
10
  qbraid_cli/configure/__init__.py,sha256=6GU7vR6JYRGcMsmdrpFbwLO5VSUmnLgwSbtmGWMQND4,158
11
11
  qbraid_cli/configure/actions.py,sha256=3rrWHaCAsogyx0Ll-lcjbSzldD4kPuz1z6VQiWebSWw,3203
12
12
  qbraid_cli/configure/app.py,sha256=1uRe2lkUA4TtYb5b4mbD4LH-cKCbsZGT3Wfk7fpNzX0,2414
13
13
  qbraid_cli/credits/__init__.py,sha256=t-3XAJFAXiu_jI4sgjaIOuNne_AoSYaSEsi-SSRkvPw,154
14
- qbraid_cli/credits/app.py,sha256=iHikmjx8pylMFNzHckuauOg-Nb9pS7xQq_H75ibVJig,774
14
+ qbraid_cli/credits/app.py,sha256=AY3qtveO50KeQ2XREiEVqUcTrESgRuoqt9pt2Z8t4Y0,866
15
15
  qbraid_cli/devices/__init__.py,sha256=_PU3eMQRV4DkPw-oCmfCPh8EbVmgG76ieEKuNsY9Xqc,154
16
16
  qbraid_cli/devices/app.py,sha256=zxSxrEQn7irkJoME4S_CBnRqWeB8cqPaBsIMfpdYFk0,2530
17
17
  qbraid_cli/devices/validation.py,sha256=YhShyUufgrKnx2XjXOXF-PqFJYklJT9CgeqIwKcNam4,809
@@ -26,8 +26,8 @@ qbraid_cli/jobs/toggle_braket.py,sha256=d5C_Di80jWMFlh-77eH8YY9pjMKWXK5abenUDtPl
26
26
  qbraid_cli/jobs/validation.py,sha256=xNbjUggMhUs4wzkuRm4PuFPi_wrElYicUgYXLznHz3U,2983
27
27
  qbraid_cli/kernels/__init__.py,sha256=VhpBota_v7OoiGxrPCqJU4XBVcolf81mbCYGSxXzVhc,154
28
28
  qbraid_cli/kernels/app.py,sha256=ZJWVdKzCDfzGnA1pqp01vDbE7fh8p84jC-y6DDgWlxc,3373
29
- qbraid_cli-0.8.0.dev7.dist-info/METADATA,sha256=2TTf3_aT_Dt7MxkpSCUgwXlKiFfA2UzWWCpieAL8u_c,5919
30
- qbraid_cli-0.8.0.dev7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
31
- qbraid_cli-0.8.0.dev7.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
32
- qbraid_cli-0.8.0.dev7.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
33
- qbraid_cli-0.8.0.dev7.dist-info/RECORD,,
29
+ qbraid_cli-0.8.1a0.dist-info/METADATA,sha256=KVpOOlMih6hukKoS6rXu6ybRv0oN9NWsU2zb5ilxJHE,7170
30
+ qbraid_cli-0.8.1a0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
31
+ qbraid_cli-0.8.1a0.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
32
+ qbraid_cli-0.8.1a0.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
33
+ qbraid_cli-0.8.1a0.dist-info/RECORD,,