qbraid-cli 0.8.0.dev1__py3-none-any.whl → 0.8.0.dev3__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/envs/app.py CHANGED
@@ -1,150 +1,27 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module defining commands in the 'qbraid envs' namespace.
3
6
 
4
7
  """
5
8
 
6
- import json
7
- import keyword
8
- import re
9
9
  import shutil
10
10
  import subprocess
11
11
  import sys
12
12
  from pathlib import Path
13
- from typing import Any, Dict, List, Optional, Tuple
13
+ from typing import Any, Dict, Optional, Tuple
14
14
 
15
15
  import typer
16
16
  from rich.console import Console
17
17
 
18
+ from qbraid_cli.envs.data_handling import installed_envs_data, request_delete_env, validate_env_name
18
19
  from qbraid_cli.handlers import QbraidException, run_progress_task
19
20
 
20
- app = typer.Typer(help="Manage qBraid environments.")
21
-
22
-
23
- def is_valid_env_name(env_name: str) -> bool: # pylint: disable=too-many-return-statements
24
- """
25
- Validates a Python virtual environment name against best practices.
26
-
27
- This function checks if the given environment name is valid based on certain
28
- criteria, including length, use of special characters, reserved names, and
29
- operating system-specific restrictions.
30
-
31
- Args:
32
- env_name (str): The name of the Python virtual environment to validate.
33
-
34
- Returns:
35
- bool: True if the name is valid, False otherwise.
36
-
37
- Raises:
38
- ValueError: If the environment name is not a string or is empty.
39
- """
40
- # Basic checks for empty names or purely whitespace names
41
- if not env_name or env_name.isspace():
42
- return False
43
-
44
- # Check for invalid characters, including shell metacharacters and spaces
45
- if re.search(r'[<>:"/\\|?*\s&;()$[\]#~!{}]', env_name):
46
- return False
47
-
48
- if env_name.startswith("tmp"):
49
- return False
50
-
51
- # Reserved names for Windows (example list, can be expanded)
52
- reserved_names = [
53
- "CON",
54
- "PRN",
55
- "AUX",
56
- "NUL",
57
- "COM1",
58
- "COM2",
59
- "COM3",
60
- "COM4",
61
- "COM5",
62
- "COM6",
63
- "COM7",
64
- "COM8",
65
- "COM9",
66
- "LPT1",
67
- "LPT2",
68
- "LPT3",
69
- "LPT4",
70
- "LPT5",
71
- "LPT6",
72
- "LPT7",
73
- "LPT8",
74
- "LPT9",
75
- ]
76
- if env_name.upper() in reserved_names:
77
- return False
78
-
79
- if len(env_name) > 20:
80
- return False
81
-
82
- # Check against Python reserved words
83
- if keyword.iskeyword(env_name):
84
- return False
85
-
86
- # Check if it starts with a number, which is not a good practice
87
- if env_name[0].isdigit():
88
- return False
89
-
90
- return True
91
-
92
-
93
- def validate_env_name(value: str) -> str:
94
- """Validate environment name."""
95
- if not is_valid_env_name(value):
96
- raise typer.BadParameter(
97
- f"Invalid environment name '{value}'. " "Please use a valid Python environment name."
98
- )
99
- return value
100
-
101
-
102
- def installed_envs_data() -> Tuple[Dict[str, Path], Dict[str, str]]:
103
- """Gather paths and aliases for all installed qBraid environments."""
104
- from qbraid.api.system import get_qbraid_envs_paths, is_valid_slug
105
-
106
- installed = {}
107
- aliases = {}
108
-
109
- qbraid_env_paths: List[Path] = get_qbraid_envs_paths()
110
-
111
- for env_path in qbraid_env_paths:
112
- for entry in env_path.iterdir():
113
- if entry.is_dir() and is_valid_slug(entry.name):
114
- installed[entry.name] = entry
21
+ envs_app = typer.Typer(help="Manage qBraid environments.")
115
22
 
116
- if entry.name == "qbraid_000000":
117
- aliases["default"] = entry.name
118
- continue
119
23
 
120
- state_json_path = entry / "state.json"
121
- if state_json_path.exists():
122
- try:
123
- with open(state_json_path, "r", encoding="utf-8") as f:
124
- data = json.load(f)
125
- aliases[data.get("name", entry.name[:-7])] = entry.name
126
- # pylint: disable-next=broad-exception-caught
127
- except (json.JSONDecodeError, Exception):
128
- aliases[entry.name[:-7]] = entry.name
129
- else:
130
- aliases[entry.name[:-7]] = entry.name
131
-
132
- return installed, aliases
133
-
134
-
135
- def request_delete_env(slug: str) -> str:
136
- """Send request to delete environment given slug."""
137
- from qbraid.api import QbraidSession, RequestsApiError
138
-
139
- session = QbraidSession()
140
-
141
- try:
142
- session.delete(f"/environments/{slug}")
143
- except RequestsApiError as err:
144
- raise QbraidException("Delete environment request failed") from err
145
-
146
-
147
- @app.command(name="create")
24
+ @envs_app.command(name="create")
148
25
  def envs_create( # pylint: disable=too-many-statements
149
26
  name: str = typer.Option(
150
27
  ..., "--name", "-n", help="Name of the environment to create", callback=validate_env_name
@@ -152,13 +29,16 @@ def envs_create( # pylint: disable=too-many-statements
152
29
  description: Optional[str] = typer.Option(
153
30
  None, "--description", "-d", help="Short description of the environment"
154
31
  ),
32
+ auto_confirm: bool = typer.Option(
33
+ False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
34
+ ),
155
35
  ) -> None:
156
36
  """Create a new qBraid environment."""
157
37
  from .create import create_qbraid_env_assets, create_venv
158
38
 
159
39
  def request_new_env(req_body: Dict[str, str]) -> Dict[str, Any]:
160
40
  """Send request to create new environment and return the slug."""
161
- from qbraid.api import QbraidSession, RequestsApiError
41
+ from qbraid_core import QbraidSession, RequestsApiError
162
42
 
163
43
  session = QbraidSession()
164
44
 
@@ -176,9 +56,9 @@ def envs_create( # pylint: disable=too-many-statements
176
56
 
177
57
  def gather_local_data() -> Tuple[Path, str]:
178
58
  """Gather environment data and return the slug."""
179
- from qbraid.api.system import get_qbraid_envs_paths
59
+ from qbraid_core.services.environments import get_default_envs_paths
180
60
 
181
- env_path = get_qbraid_envs_paths()[0]
61
+ env_path = get_default_envs_paths()[0]
182
62
 
183
63
  result = subprocess.run(
184
64
  [sys.executable, "--version"],
@@ -237,7 +117,7 @@ def envs_create( # pylint: disable=too-many-statements
237
117
  typer.echo(f" location: {slug_path}")
238
118
  typer.echo(f" version: {python_version}\n")
239
119
 
240
- user_confirmation = typer.confirm("Proceed", default=True)
120
+ user_confirmation = auto_confirm or typer.confirm("Proceed", default=True)
241
121
  typer.echo("")
242
122
  if not user_confirmation:
243
123
  request_delete_env(slug)
@@ -276,9 +156,12 @@ def envs_create( # pylint: disable=too-many-statements
276
156
  typer.echo("# $ deactivate")
277
157
 
278
158
 
279
- @app.command(name="remove")
159
+ @envs_app.command(name="remove")
280
160
  def envs_remove(
281
- name: str = typer.Option(..., "-n", "--name", help="Name of the environment to remove")
161
+ name: str = typer.Option(..., "-n", "--name", help="Name of the environment to remove"),
162
+ auto_confirm: bool = typer.Option(
163
+ False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
164
+ ),
282
165
  ) -> None:
283
166
  """Delete a qBraid environment."""
284
167
 
@@ -304,8 +187,7 @@ def envs_remove(
304
187
  "Are you sure you want to continue?"
305
188
  )
306
189
 
307
- # Ask for user confirmation
308
- if typer.confirm(confirmation_message, abort=True):
190
+ if auto_confirm or typer.confirm(confirmation_message, abort=True):
309
191
  typer.echo("")
310
192
  run_progress_task(
311
193
  request_delete_env,
@@ -321,25 +203,24 @@ def envs_remove(
321
203
  error_message="Failed to delete qBraid environment",
322
204
  )
323
205
  typer.echo(f"\nEnvironment '{name}' successfully removed.")
324
- # console = Console()
325
- # console.print(
326
- # f"\n[bold green]Successfully deleted qBraid environment: "
327
- # f"[/bold green][bold magenta]{name}[/bold magenta]\n"
328
- # )
329
206
 
330
207
 
331
- @app.command(name="list")
208
+ @envs_app.command(name="list")
332
209
  def envs_list():
333
210
  """List installed qBraid environments."""
334
211
  installed, aliases = installed_envs_data()
335
212
 
213
+ console = Console()
214
+
336
215
  if len(installed) == 0:
337
- print("No qBraid environments installed.")
338
- print("\nUse 'qbraid envs create' to create a new environment.")
216
+ console.print(
217
+ "No qBraid environments installed.\n\n"
218
+ + "Use 'qbraid envs create' to create a new environment.",
219
+ style="yellow",
220
+ )
339
221
  return
340
222
 
341
223
  alias_path_pairs = [(alias, installed[slug_name]) for alias, slug_name in aliases.items()]
342
-
343
224
  sorted_alias_path_pairs = sorted(
344
225
  alias_path_pairs,
345
226
  key=lambda x: (x[0] != "default", str(x[1]).startswith(str(Path.home())), x[0]),
@@ -348,21 +229,23 @@ def envs_list():
348
229
  current_env_path = Path(sys.executable).parent.parent.parent
349
230
 
350
231
  max_alias_length = (
351
- max(len(alias) for alias, _ in sorted_alias_path_pairs) if sorted_alias_path_pairs else 0
352
- )
353
- max_path_length = (
354
- max(len(str(path)) for _, path in sorted_alias_path_pairs) if sorted_alias_path_pairs else 0
232
+ max(len(str(alias)) for alias, envpath in sorted_alias_path_pairs)
233
+ if sorted_alias_path_pairs
234
+ else 0
355
235
  )
356
236
 
357
237
  print("# qbraid environments:")
358
238
  print("#")
359
239
  print("")
240
+
360
241
  for alias, path in sorted_alias_path_pairs:
361
- mark = "* " if path == current_env_path else " "
362
- print(f"{alias.ljust(max_alias_length + 7)}{mark}{str(path).ljust(max_path_length)}")
242
+ mark = "*" if path == current_env_path else " "
243
+ # Format each line with spacing based on the longest alias for alignment
244
+ line = f"{alias.ljust(max_alias_length+3)}{mark} {path}" # fix the most optimal spacing
245
+ console.print(line)
363
246
 
364
247
 
365
- @app.command(name="activate")
248
+ @envs_app.command(name="activate")
366
249
  def envs_activate(
367
250
  name: str = typer.Argument(..., help="Name of the environment. Values from 'qbraid envs list'.")
368
251
  ):
@@ -384,4 +267,4 @@ def envs_activate(
384
267
 
385
268
 
386
269
  if __name__ == "__main__":
387
- app()
270
+ envs_app()
qbraid_cli/envs/create.py CHANGED
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module supporting 'qbraid envs create' command.
3
6
 
@@ -0,0 +1,140 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ Module for handling data related to qBraid environments.
6
+
7
+ """
8
+
9
+ import json
10
+ import keyword
11
+ import re
12
+ from pathlib import Path
13
+ from typing import Dict, List, Tuple
14
+
15
+ import typer
16
+
17
+ from qbraid_cli.handlers import QbraidException
18
+
19
+
20
+ def is_valid_env_name(env_name: str) -> bool: # pylint: disable=too-many-return-statements
21
+ """
22
+ Validates a Python virtual environment name against best practices.
23
+
24
+ This function checks if the given environment name is valid based on certain
25
+ criteria, including length, use of special characters, reserved names, and
26
+ operating system-specific restrictions.
27
+
28
+ Args:
29
+ env_name (str): The name of the Python virtual environment to validate.
30
+
31
+ Returns:
32
+ bool: True if the name is valid, False otherwise.
33
+
34
+ Raises:
35
+ ValueError: If the environment name is not a string or is empty.
36
+ """
37
+ # Basic checks for empty names or purely whitespace names
38
+ if not env_name or env_name.isspace():
39
+ return False
40
+
41
+ # Check for invalid characters, including shell metacharacters and spaces
42
+ if re.search(r'[<>:"/\\|?*\s&;()$[\]#~!{}]', env_name):
43
+ return False
44
+
45
+ if env_name.startswith("tmp"):
46
+ return False
47
+
48
+ # Reserved names for Windows (example list, can be expanded)
49
+ reserved_names = [
50
+ "CON",
51
+ "PRN",
52
+ "AUX",
53
+ "NUL",
54
+ "COM1",
55
+ "COM2",
56
+ "COM3",
57
+ "COM4",
58
+ "COM5",
59
+ "COM6",
60
+ "COM7",
61
+ "COM8",
62
+ "COM9",
63
+ "LPT1",
64
+ "LPT2",
65
+ "LPT3",
66
+ "LPT4",
67
+ "LPT5",
68
+ "LPT6",
69
+ "LPT7",
70
+ "LPT8",
71
+ "LPT9",
72
+ ]
73
+ if env_name.upper() in reserved_names:
74
+ return False
75
+
76
+ if len(env_name) > 20:
77
+ return False
78
+
79
+ # Check against Python reserved words
80
+ if keyword.iskeyword(env_name):
81
+ return False
82
+
83
+ # Check if it starts with a number, which is not a good practice
84
+ if env_name[0].isdigit():
85
+ return False
86
+
87
+ return True
88
+
89
+
90
+ def validate_env_name(value: str) -> str:
91
+ """Validate environment name."""
92
+ if not is_valid_env_name(value):
93
+ raise typer.BadParameter(
94
+ f"Invalid environment name '{value}'. " "Please use a valid Python environment name."
95
+ )
96
+ return value
97
+
98
+
99
+ def installed_envs_data() -> Tuple[Dict[str, Path], Dict[str, str]]:
100
+ """Gather paths and aliases for all installed qBraid environments."""
101
+ from qbraid_core.services.environments.paths import get_default_envs_paths, is_valid_slug
102
+
103
+ installed = {}
104
+ aliases = {}
105
+
106
+ qbraid_env_paths: List[Path] = get_default_envs_paths()
107
+
108
+ for env_path in qbraid_env_paths:
109
+ for entry in env_path.iterdir():
110
+ if entry.is_dir() and is_valid_slug(entry.name):
111
+ installed[entry.name] = entry
112
+
113
+ if entry.name == "qbraid_000000":
114
+ aliases["default"] = entry.name
115
+ continue
116
+
117
+ state_json_path = entry / "state.json"
118
+ if state_json_path.exists():
119
+ try:
120
+ with open(state_json_path, "r", encoding="utf-8") as f:
121
+ data = json.load(f)
122
+ aliases[data.get("name", entry.name[:-7])] = entry.name
123
+ # pylint: disable-next=broad-exception-caught
124
+ except (json.JSONDecodeError, Exception):
125
+ aliases[entry.name[:-7]] = entry.name
126
+ else:
127
+ aliases[entry.name[:-7]] = entry.name
128
+ return installed, aliases
129
+
130
+
131
+ def request_delete_env(slug: str) -> str:
132
+ """Send request to delete environment given slug."""
133
+ from qbraid_core import QbraidSession, RequestsApiError
134
+
135
+ session = QbraidSession()
136
+
137
+ try:
138
+ session.delete(f"/environments/{slug}")
139
+ except RequestsApiError as err:
140
+ raise QbraidException("Delete environment request failed") from err
qbraid_cli/exceptions.py CHANGED
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module defining custom exceptions for the qBraid CLI.
3
6
 
qbraid_cli/handlers.py CHANGED
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module providing application support utilities, including abstractions for error handling
3
6
  and executing operations with progress tracking within the qBraid CLI.
@@ -1,6 +1,9 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
1
4
  """
2
5
  Module defining the qbraid jobs namespace
3
6
 
4
7
  """
5
8
 
6
- from .app import app
9
+ from .app import jobs_app
qbraid_cli/jobs/app.py CHANGED
@@ -1,119 +1,65 @@
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
8
 
6
9
  import sys
7
- from typing import Callable, Dict, Optional, Tuple
10
+ from typing import Any, Callable, Dict, Tuple
8
11
 
9
12
  import typer
10
13
  from rich.console import Console
11
14
 
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
-
23
-
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
- )
49
-
50
-
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()
15
+ from qbraid_cli.handlers import handle_error, run_progress_task
16
+ from qbraid_cli.jobs.toggle_braket import disable_braket, enable_braket
17
+ from qbraid_cli.jobs.validation import handle_jobs_state, run_progress_get_state, validate_library
74
18
 
75
- action_callback() # Perform the specific enable/disable action
19
+ jobs_app = typer.Typer(help="Manage qBraid quantum jobs.")
76
20
 
77
21
 
78
- @app.command(name="enable")
22
+ @jobs_app.command(name="enable")
79
23
  def jobs_enable(
80
24
  library: str = typer.Argument(
81
25
  ..., help="Software library with quantum jobs support.", callback=validate_library
82
- )
26
+ ),
27
+ auto_confirm: bool = typer.Option(
28
+ False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
29
+ ),
83
30
  ) -> None:
84
31
  """Enable qBraid Quantum Jobs."""
85
32
 
86
33
  def enable_action():
87
34
  if library == "braket":
88
- from .toggle_braket import enable_braket
89
-
90
- enable_braket()
35
+ enable_braket(auto_confirm=auto_confirm)
91
36
  else:
92
37
  raise RuntimeError(f"Unsupported device library: '{library}'.")
93
38
 
94
39
  handle_jobs_state(library, "enable", enable_action)
95
40
 
96
41
 
97
- @app.command(name="disable")
42
+ @jobs_app.command(name="disable")
98
43
  def jobs_disable(
99
44
  library: str = typer.Argument(
100
45
  ..., help="Software library with quantum jobs support.", callback=validate_library
101
- )
46
+ ),
47
+ auto_confirm: bool = typer.Option(
48
+ False, "--yes", "-y", help="Automatically answer 'yes' to all prompts"
49
+ ),
102
50
  ) -> None:
103
51
  """Disable qBraid Quantum Jobs."""
104
52
 
105
53
  def disable_action():
106
54
  if library == "braket":
107
- from .toggle_braket import disable_braket
108
-
109
- disable_braket()
55
+ disable_braket(auto_confirm=auto_confirm)
110
56
  else:
111
57
  raise RuntimeError(f"Unsupported device library: '{library}'.")
112
58
 
113
59
  handle_jobs_state(library, "disable", disable_action)
114
60
 
115
61
 
116
- @app.command(name="state")
62
+ @jobs_app.command(name="state")
117
63
  def jobs_state(
118
64
  library: str = typer.Argument(
119
65
  default=None,
@@ -142,7 +88,7 @@ def jobs_state(
142
88
  console.print(f"{lib:<{padding-1}}", state_str, end="\n")
143
89
 
144
90
 
145
- @app.command(name="list")
91
+ @jobs_app.command(name="list")
146
92
  def jobs_list(
147
93
  limit: int = typer.Option(
148
94
  10, "--limit", "-l", help="Limit the maximum number of results returned"
@@ -150,20 +96,55 @@ def jobs_list(
150
96
  ) -> None:
151
97
  """List qBraid Quantum Jobs."""
152
98
 
153
- def import_jobs() -> Tuple[Callable, Exception]:
154
- from qbraid import get_jobs
155
- from qbraid.exceptions import QbraidError
99
+ def import_jobs() -> Tuple[Any, Callable]:
100
+ from qbraid_core.services.quantum import QuantumClient, process_job_data
101
+
102
+ client = QuantumClient()
156
103
 
157
- return get_jobs, QbraidError
104
+ return client, process_job_data
158
105
 
159
- result: Tuple[Callable, Exception] = run_progress_task(import_jobs)
160
- get_jobs, QbraidError = result
106
+ result: Tuple[Any, Callable] = run_progress_task(import_jobs)
107
+ client, process_job_data = result
108
+ # https://github.com/qBraid/api/issues/644
109
+ # raw_data = client.search_jobs(query={"numResults": limit})
110
+ raw_data = client.search_jobs(query={})
111
+ job_data, msg = process_job_data(raw_data)
112
+ job_data = job_data[:limit]
161
113
 
114
+ longest_job_id = max(len(item[0]) for item in job_data)
115
+ spacing = longest_job_id + 5
162
116
  try:
163
- get_jobs(filters={"numResults": limit})
164
- except QbraidError:
117
+ console = Console()
118
+ header_1 = "Job ID"
119
+ header_2 = "Submitted"
120
+ header_3 = "Status"
121
+ console.print(f"\n[bold]{header_1.ljust(spacing)}{header_2.ljust(36)}{header_3}[/bold]")
122
+ for job_id, submitted, status in job_data:
123
+ if status == "COMPLETED":
124
+ status_color = "green"
125
+ elif status in ["FAILED", "CANCELLED"]:
126
+ status_color = "red"
127
+ elif status in [
128
+ "INITIALIZING",
129
+ "INITIALIZED",
130
+ "CREATED",
131
+ "QUEUED",
132
+ "VALIDATING",
133
+ "RUNNING",
134
+ ]:
135
+ status_color = "blue"
136
+ else:
137
+ status_color = "grey"
138
+ console.print(
139
+ f"{job_id.ljust(spacing)}{submitted.ljust(35)}",
140
+ f"[{status_color}]{status}[/{status_color}]",
141
+ )
142
+
143
+ console.print(f"\n{msg}", style="italic", justify="left")
144
+
145
+ except Exception: # pylint: disable=broad-exception-caught
165
146
  handle_error(message="Failed to fetch quantum jobs.")
166
147
 
167
148
 
168
149
  if __name__ == "__main__":
169
- app()
150
+ jobs_app()