qbraid-cli 0.9.0__py3-none-any.whl → 0.9.1__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.9.0'
16
- __version_tuple__ = version_tuple = (0, 9, 0)
15
+ __version__ = version = '0.9.1'
16
+ __version_tuple__ = version_tuple = (0, 9, 1)
@@ -0,0 +1,11 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ Module defining the qbraid chat namespace
6
+
7
+ """
8
+
9
+ from .app import chat_app
10
+
11
+ __all__ = ["chat_app"]
qbraid_cli/chat/app.py ADDED
@@ -0,0 +1,96 @@
1
+ # Copyright (c) 2024, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ Module defining commands in the 'qbraid chat' namespace.
6
+
7
+ """
8
+ from enum import Enum
9
+
10
+ import typer
11
+ from rich.console import Console
12
+ from rich.table import Table
13
+
14
+ from qbraid_cli.handlers import handle_error, run_progress_task
15
+
16
+ chat_app = typer.Typer(
17
+ help="Interact with qBraid AI chat service.", pretty_exceptions_show_locals=False
18
+ )
19
+
20
+
21
+ class ChatFormat(str, Enum):
22
+ """Format of the response from the chat service."""
23
+
24
+ text = "text" # pylint: disable=invalid-name
25
+ code = "code" # pylint: disable=invalid-name
26
+
27
+
28
+ @chat_app.command("send")
29
+ def chat_send(
30
+ prompt: str = typer.Argument(..., help="The prompt to send to the chat service."),
31
+ model: str = typer.Option(None, "--model", "-m", help="The model to use for the chat service."),
32
+ response_format: ChatFormat = typer.Option(
33
+ ChatFormat.text, "--format", "-f", help="The format of the response."
34
+ ),
35
+ stream: bool = typer.Option(False, "--stream", "-s", help="Stream the response."),
36
+ ):
37
+ """
38
+ Interact with qBraid AI chat service.
39
+
40
+ """
41
+ # pylint: disable-next=import-outside-toplevel
42
+ from qbraid_core.services.chat import ChatClient, ChatServiceRequestError
43
+
44
+ client = ChatClient()
45
+
46
+ if response_format == ChatFormat.code:
47
+ prompt += " Return only raw code. Do not include any text outside of code blocks."
48
+
49
+ if stream:
50
+ try:
51
+ for chunk in client.chat_stream(prompt, model, response_format):
52
+ print(chunk, end="")
53
+ except ChatServiceRequestError as err:
54
+ handle_error(message=str(err), include_traceback=False)
55
+ else:
56
+ content = run_progress_task(
57
+ client.chat,
58
+ prompt,
59
+ model,
60
+ response_format,
61
+ description="Connecting to chat service...",
62
+ include_error_traceback=False,
63
+ )
64
+ print(content)
65
+
66
+
67
+ @chat_app.command(name="models")
68
+ def chat_models():
69
+ """List available chat models."""
70
+ # pylint: disable-next=import-outside-toplevel
71
+ from qbraid_core.services.chat import ChatClient
72
+
73
+ client = ChatClient()
74
+
75
+ models = run_progress_task(
76
+ client.get_models,
77
+ description="Connecting to chat service...",
78
+ include_error_traceback=False,
79
+ )
80
+
81
+ console = Console()
82
+ table = Table(title="Available Chat Models\n", show_lines=True, title_justify="left")
83
+
84
+ table.add_column("Model", style="cyan", no_wrap=True)
85
+ table.add_column("Pricing [not bold](1k tokens ~750 words)", style="magenta")
86
+ table.add_column("Description", style="green")
87
+
88
+ for model in models:
89
+ table.add_row(
90
+ model["model"],
91
+ f"{model['pricing']['input']} credits / 1M input tokens\n"
92
+ f"{model['pricing']['output']} credits / 1M output tokens",
93
+ model["description"],
94
+ )
95
+
96
+ console.print(table)
qbraid_cli/handlers.py CHANGED
@@ -15,7 +15,7 @@ from typing import Any, Callable, Optional, Union
15
15
 
16
16
  import typer
17
17
  from rich.console import Console
18
- from rich.progress import Progress, SpinnerColumn, TextColumn
18
+ from rich.progress import Progress, SpinnerColumn, TaskID, TextColumn
19
19
 
20
20
  from .exceptions import DEFAULT_ERROR_MESSAGE, QbraidException
21
21
 
@@ -25,6 +25,14 @@ def _should_display_progress():
25
25
  return os.getenv("QBRAID_CLI_SHOW_PROGRESS", "true").lower() in ["true", "1", "t", "y", "yes"]
26
26
 
27
27
 
28
+ def _update_completed_task(
29
+ progress: Progress, task_id: TaskID, success: bool = True, sleep_time: float = 0.15
30
+ ):
31
+ status = "Done" if success else "Failed"
32
+ progress.update(task_id, completed=100, status=status)
33
+ sleep(sleep_time)
34
+
35
+
28
36
  def handle_error(
29
37
  error_type: Optional[str] = None, message: Optional[str] = None, include_traceback: bool = True
30
38
  ) -> None:
@@ -86,6 +94,7 @@ def run_progress_task(
86
94
  *args,
87
95
  description: Optional[str] = None,
88
96
  error_message: Optional[str] = None,
97
+ include_error_traceback: bool = True,
89
98
  **kwargs,
90
99
  ) -> Any:
91
100
  """
@@ -103,6 +112,8 @@ def run_progress_task(
103
112
  error_message (optional, str): Custom error message to display if the operation.
104
113
  fails. Defaults to None, in which case the
105
114
  exception's message is used.
115
+ include_error_traceback (bool): Whether to include the traceback in the error message.
116
+ Defaults to True.
106
117
  **kwargs: Arbitrary keyword arguments for the operation.
107
118
 
108
119
  Returns:
@@ -116,7 +127,7 @@ def run_progress_task(
116
127
  return operation(*args, **kwargs)
117
128
  except Exception as err: # pylint: disable=broad-exception-caught
118
129
  custom_message = error_message if error_message else str(err)
119
- return handle_error(message=custom_message)
130
+ return handle_error(message=custom_message, include_traceback=include_error_traceback)
120
131
 
121
132
  console = Console()
122
133
  with Progress(
@@ -129,13 +140,12 @@ def run_progress_task(
129
140
  task = progress.add_task(description, status="In Progress", total=None)
130
141
  try:
131
142
  result = operation(*args, **kwargs)
132
- progress.update(task, completed=100, status="Done")
133
- sleep(0.15)
143
+ _update_completed_task(progress, task, success=True)
134
144
  return result
135
145
  except Exception as err: # pylint: disable=broad-exception-caught
136
- progress.update(task, completed=100, status="Failed")
146
+ _update_completed_task(progress, task, success=False)
137
147
  custom_message = error_message if error_message else str(err)
138
- return handle_error(message=custom_message)
148
+ return handle_error(message=custom_message, include_traceback=include_error_traceback)
139
149
  finally:
140
150
  progress.remove_task(task)
141
151
 
qbraid_cli/main.py CHANGED
@@ -11,6 +11,7 @@ import typer
11
11
 
12
12
  from qbraid_cli.account.app import account_app
13
13
  from qbraid_cli.admin.app import admin_app
14
+ from qbraid_cli.chat.app import chat_app
14
15
  from qbraid_cli.configure.app import configure_app
15
16
  from qbraid_cli.devices.app import devices_app
16
17
  from qbraid_cli.jobs.app import jobs_app
@@ -27,6 +28,7 @@ except ImportError:
27
28
  app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})
28
29
 
29
30
  app.add_typer(admin_app, name="admin")
31
+ app.add_typer(chat_app, name="chat")
30
32
  app.add_typer(configure_app, name="configure")
31
33
  app.add_typer(account_app, name="account")
32
34
  app.add_typer(devices_app, name="devices")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qbraid-cli
3
- Version: 0.9.0
3
+ Version: 0.9.1
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
@@ -29,16 +29,16 @@ Description-Content-Type: text/markdown
29
29
  License-File: LICENSE
30
30
  Requires-Dist: typer>=0.12.1
31
31
  Requires-Dist: rich>=10.11.0
32
- Requires-Dist: qbraid-core>=0.1.29
32
+ Requires-Dist: qbraid-core>=0.1.30
33
+ Provides-Extra: jobs
34
+ Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
35
+ Provides-Extra: envs
36
+ Requires-Dist: qbraid-core[environments]; extra == "envs"
33
37
  Provides-Extra: dev
34
38
  Requires-Dist: isort; extra == "dev"
35
39
  Requires-Dist: black; extra == "dev"
36
40
  Requires-Dist: pytest; extra == "dev"
37
41
  Requires-Dist: pytest-cov; extra == "dev"
38
- Provides-Extra: envs
39
- Requires-Dist: qbraid-core[environments]; extra == "envs"
40
- Provides-Extra: jobs
41
- Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
42
42
 
43
43
  <img width="full" alt="qbraid_cli" src="https://qbraid-static.s3.amazonaws.com/logos/qbraid-cli-banner.png">
44
44
 
@@ -1,8 +1,8 @@
1
1
  qbraid_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- qbraid_cli/_version.py,sha256=dEuABWaRk7ju3R5JrWbpUVQ4xq7RBpvl2clGJceWAS4,411
2
+ qbraid_cli/_version.py,sha256=_P6tBRUyis5e8UBMut-5M8NVccs2HwAQXTxErAP99SI,411
3
3
  qbraid_cli/exceptions.py,sha256=KjlhYJhSHMVazaNiBjD_Ur06w4sekP8zRsFzBdyIpno,672
4
- qbraid_cli/handlers.py,sha256=gcEnKFobM-imO8IaPwsSqx_p_whwPW6rqrNZRT0t61M,7137
5
- qbraid_cli/main.py,sha256=s8tAr5KI653G7-yKdFJeq0I9qTrVV83H8B5Se8VZaKI,2761
4
+ qbraid_cli/handlers.py,sha256=B9H1Qw6yx8izrqp9OGR2TgSJa_mxA8KLXUkX8LB7Feg,7650
5
+ qbraid_cli/main.py,sha256=Xhqbkfi9MtxulrIbEDnBK_gpfHluBGa5YluCIkJuoLg,2839
6
6
  qbraid_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  qbraid_cli/account/__init__.py,sha256=smlpUcVkM3QEbJG0norGM7i71XBJlUGQYByswTfPnmg,181
8
8
  qbraid_cli/account/app.py,sha256=ggvft1Q4d5IIv0lf3adbIkcz0nIYiEriJu91SPyo5_4,1821
@@ -10,6 +10,8 @@ qbraid_cli/admin/__init__.py,sha256=qcWD5mQEUCtr49mrUpZmk7eGDe0L_Gtc8RwZmzIXSwo,
10
10
  qbraid_cli/admin/app.py,sha256=NGisg2aouk8qK2oFogwblFTBK0vvTiL_zJYjeanC4x0,1576
11
11
  qbraid_cli/admin/headers.py,sha256=WqpRYp81CQcF5-Afumo_qQrf-5XCfbndBJ6I7vOADKE,7133
12
12
  qbraid_cli/admin/validation.py,sha256=U_8RFWBwRUNPe6LdjNpl-Yz8Br57PLWMoPbpR-jBS-M,979
13
+ qbraid_cli/chat/__init__.py,sha256=0He19OpSsEoyCGxZLMTWey1fKAAls5mHTCFlO5-gl2Y,172
14
+ qbraid_cli/chat/app.py,sha256=QQqwCi3dk-_i5XTe8labQFPN5xttFKoLf7oWIrhlmyQ,2913
13
15
  qbraid_cli/configure/__init__.py,sha256=YaJ74Ztz2vl3eYp8_jVBucWkXscxz7EZEIzr70OfuOM,187
14
16
  qbraid_cli/configure/actions.py,sha256=-BduRmnxvf8JMNonb6VWFtdlHlcHPOPz3Bj5g8kfmBU,3197
15
17
  qbraid_cli/configure/app.py,sha256=1uRe2lkUA4TtYb5b4mbD4LH-cKCbsZGT3Wfk7fpNzX0,2414
@@ -30,9 +32,9 @@ qbraid_cli/kernels/app.py,sha256=Sl57U1JXDKWoeMQDSXJRHlKzDYSdKIbV7tSytZXo5PM,292
30
32
  qbraid_cli/pip/__init__.py,sha256=tJtU0rxn-ODogNh5Y4pp_BgDQXMN-3JY1QGj0OZHwjQ,169
31
33
  qbraid_cli/pip/app.py,sha256=wzvjX5NL37XIFtZ5KvTZ-nj9xwFKt8QLYZ_vGvk3tXo,1440
32
34
  qbraid_cli/pip/hooks.py,sha256=jkIeev3cOd-cmaoJSdSqbmhTYCs6z1we84FMqa3ZoZw,2124
33
- qbraid_cli-0.9.0.dist-info/LICENSE,sha256=P1gi-ofB8lmkRt_mxDoJpcgQq9Ckq9WhRAS1oYk-G1s,2506
34
- qbraid_cli-0.9.0.dist-info/METADATA,sha256=tQ1CMKiU9fLu-2R5Vpwo8ZJCSlZvG8JrXEtPnTciE1E,6785
35
- qbraid_cli-0.9.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
36
- qbraid_cli-0.9.0.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
37
- qbraid_cli-0.9.0.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
38
- qbraid_cli-0.9.0.dist-info/RECORD,,
35
+ qbraid_cli-0.9.1.dist-info/LICENSE,sha256=P1gi-ofB8lmkRt_mxDoJpcgQq9Ckq9WhRAS1oYk-G1s,2506
36
+ qbraid_cli-0.9.1.dist-info/METADATA,sha256=L2lfHPXbMA5GIsg3b94GxeooGVA502ZsJknonMNJBg0,6785
37
+ qbraid_cli-0.9.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
38
+ qbraid_cli-0.9.1.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
39
+ qbraid_cli-0.9.1.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
40
+ qbraid_cli-0.9.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5