qbraid-cli 0.8.5a1__py3-none-any.whl → 0.12.0a0__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.
Files changed (38) hide show
  1. qbraid_cli/_version.py +16 -14
  2. qbraid_cli/account/__init__.py +11 -0
  3. qbraid_cli/account/app.py +67 -0
  4. qbraid_cli/admin/app.py +21 -13
  5. qbraid_cli/admin/headers.py +132 -23
  6. qbraid_cli/admin/validation.py +1 -8
  7. qbraid_cli/chat/__init__.py +11 -0
  8. qbraid_cli/chat/app.py +76 -0
  9. qbraid_cli/configure/actions.py +21 -2
  10. qbraid_cli/configure/app.py +147 -2
  11. qbraid_cli/configure/claude_config.py +215 -0
  12. qbraid_cli/devices/app.py +27 -4
  13. qbraid_cli/envs/activate.py +38 -8
  14. qbraid_cli/envs/app.py +716 -89
  15. qbraid_cli/envs/create.py +3 -2
  16. qbraid_cli/files/__init__.py +11 -0
  17. qbraid_cli/files/app.py +139 -0
  18. qbraid_cli/handlers.py +35 -5
  19. qbraid_cli/jobs/app.py +33 -13
  20. qbraid_cli/jobs/toggle_braket.py +2 -13
  21. qbraid_cli/jobs/validation.py +1 -0
  22. qbraid_cli/kernels/app.py +4 -3
  23. qbraid_cli/main.py +57 -13
  24. qbraid_cli/mcp/__init__.py +10 -0
  25. qbraid_cli/mcp/app.py +126 -0
  26. qbraid_cli/mcp/serve.py +321 -0
  27. qbraid_cli/pip/app.py +2 -2
  28. qbraid_cli/pip/hooks.py +1 -0
  29. {qbraid_cli-0.8.5a1.dist-info → qbraid_cli-0.12.0a0.dist-info}/METADATA +37 -14
  30. qbraid_cli-0.12.0a0.dist-info/RECORD +46 -0
  31. {qbraid_cli-0.8.5a1.dist-info → qbraid_cli-0.12.0a0.dist-info}/WHEEL +1 -1
  32. {qbraid_cli-0.8.5a1.dist-info → qbraid_cli-0.12.0a0.dist-info/licenses}/LICENSE +6 -4
  33. qbraid_cli/admin/buildlogs.py +0 -114
  34. qbraid_cli/credits/__init__.py +0 -11
  35. qbraid_cli/credits/app.py +0 -35
  36. qbraid_cli-0.8.5a1.dist-info/RECORD +0 -39
  37. {qbraid_cli-0.8.5a1.dist-info → qbraid_cli-0.12.0a0.dist-info}/entry_points.txt +0 -0
  38. {qbraid_cli-0.8.5a1.dist-info → qbraid_cli-0.12.0a0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,321 @@
1
+ # Copyright (c) 2025, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ MCP aggregator server implementation.
6
+
7
+ Provides stdio-based MCP server that aggregates multiple qBraid MCP backends.
8
+ """
9
+ import asyncio
10
+ import json
11
+ import logging
12
+ import signal
13
+ import sys
14
+ from typing import Optional
15
+
16
+ import typer
17
+ from qbraid_core.services.mcp import MCPRouter, MCPWebSocketClient, discover_mcp_servers
18
+ from qbraid_core.sessions import QbraidSession
19
+
20
+
21
+ def setup_logging(debug: bool = False) -> None:
22
+ """
23
+ Configure logging for MCP server.
24
+
25
+ Args:
26
+ debug: Enable debug logging
27
+ """
28
+ level = logging.DEBUG if debug else logging.INFO
29
+
30
+ # Log to stderr so stdout remains clean for MCP protocol
31
+ logging.basicConfig(
32
+ level=level,
33
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
34
+ stream=sys.stderr,
35
+ )
36
+
37
+
38
+ class MCPAggregatorServer:
39
+ """
40
+ MCP aggregator server that bridges stdio to multiple WebSocket backends.
41
+
42
+ Architecture:
43
+ Claude Desktop (stdio) <-> THIS SERVER <-> Multiple MCP WebSocket Servers
44
+ """
45
+
46
+ def __init__(
47
+ self,
48
+ session: QbraidSession,
49
+ workspace: str = "lab",
50
+ include_staging: bool = False,
51
+ debug: bool = False,
52
+ ):
53
+ """
54
+ Initialize MCP aggregator server.
55
+
56
+ Args:
57
+ session: Authenticated qBraid session
58
+ workspace: Workspace to connect to
59
+ include_staging: Include staging endpoints
60
+ debug: Enable debug logging
61
+ """
62
+ self.session = session
63
+ self.workspace = workspace
64
+ self.include_staging = include_staging
65
+ self.debug = debug
66
+ self.router: Optional[MCPRouter] = None
67
+ self.logger = logging.getLogger(__name__)
68
+ self._shutdown_event = asyncio.Event()
69
+
70
+ async def initialize_backends(self) -> None:
71
+ """
72
+ Discover and connect to MCP backend servers.
73
+ """
74
+ # Get user info for building WebSocket URLs
75
+ try:
76
+ user_info = self.session.get_user()
77
+ username = user_info.get("email")
78
+ if not username:
79
+ raise ValueError("User email not found in session")
80
+ except Exception as err:
81
+ self.logger.error("Failed to get user info: %s", err)
82
+ typer.secho(
83
+ "Error: Could not authenticate. Please run 'qbraid configure' first.",
84
+ fg=typer.colors.RED,
85
+ err=True,
86
+ )
87
+ raise typer.Exit(1)
88
+
89
+ # Discover available MCP endpoints
90
+ endpoints = discover_mcp_servers(
91
+ workspace=self.workspace,
92
+ include_staging=self.include_staging,
93
+ )
94
+
95
+ if not endpoints:
96
+ typer.secho(
97
+ f"Warning: No MCP endpoints found for workspace '{self.workspace}'",
98
+ fg=typer.colors.YELLOW,
99
+ err=True,
100
+ )
101
+ raise typer.Exit(1)
102
+
103
+ self.logger.info("Discovered %d MCP endpoint(s)", len(endpoints))
104
+
105
+ # Create router
106
+ self.router = MCPRouter(on_message=self._handle_backend_message)
107
+
108
+ # Create WebSocket clients for each endpoint
109
+ for endpoint in endpoints:
110
+ # Use JupyterHub token for lab endpoints, API key for other endpoints
111
+ try:
112
+ if endpoint.name.startswith("lab"):
113
+ try:
114
+ token_data = self.session.get_jupyter_token_data()
115
+ token = token_data.get("token")
116
+ if not token:
117
+ raise ValueError("Token not found in response data")
118
+ except Exception as err:
119
+ self.logger.error(
120
+ "Failed to get Jupyter token for endpoint '%s': %s",
121
+ endpoint.name,
122
+ err,
123
+ )
124
+ typer.secho(
125
+ f"Error: Could not retrieve Jupyter token for '{endpoint.name}'. "
126
+ "Please ensure you are authenticated with qBraid Lab.",
127
+ fg=typer.colors.RED,
128
+ err=True,
129
+ )
130
+ raise typer.Exit(1)
131
+ else:
132
+ token = self.session.api_key
133
+ if not token:
134
+ self.logger.error("No API key available for endpoint '%s'", endpoint.name)
135
+ typer.secho(
136
+ f"Error: No API key available for '{endpoint.name}'. "
137
+ "Please run 'qbraid configure' to set up your credentials.",
138
+ fg=typer.colors.RED,
139
+ err=True,
140
+ )
141
+ raise typer.Exit(1)
142
+
143
+ ws_url = endpoint.build_url(username, token)
144
+ self.logger.info("Configuring backend: %s", endpoint.name)
145
+
146
+ client = MCPWebSocketClient(
147
+ websocket_url=ws_url,
148
+ on_message=self._handle_backend_message,
149
+ name=endpoint.name,
150
+ )
151
+ self.router.add_backend(endpoint.name, client)
152
+ except typer.Exit:
153
+ raise # Re-raise typer.Exit to propagate clean exits
154
+ except Exception as err: # pylint: disable=broad-exception-caught
155
+ self.logger.error("Failed to configure backend '%s': %s", endpoint.name, err)
156
+ typer.secho(
157
+ f"Error: Failed to configure backend '{endpoint.name}': {err}",
158
+ fg=typer.colors.RED,
159
+ err=True,
160
+ )
161
+ raise typer.Exit(1)
162
+
163
+ # Connect to all backends
164
+ self.logger.info("Connecting to backends...")
165
+ await self.router.connect_all()
166
+
167
+ # Check connection status
168
+ connected = self.router.get_connected_backends()
169
+ if not connected:
170
+ typer.secho(
171
+ "Error: Failed to connect to any MCP backends",
172
+ fg=typer.colors.RED,
173
+ err=True,
174
+ )
175
+ raise typer.Exit(1)
176
+
177
+ self.logger.info("Connected to %d backend(s): %s", len(connected), ", ".join(connected))
178
+ typer.secho(
179
+ f"MCP aggregator ready ({len(connected)} backend(s) connected)",
180
+ fg=typer.colors.GREEN,
181
+ err=True,
182
+ )
183
+
184
+ def _handle_backend_message(self, message: dict) -> None:
185
+ """
186
+ Handle messages from backend MCP servers.
187
+
188
+ Forwards messages to stdout for Claude Desktop.
189
+
190
+ Args:
191
+ message: Message dictionary from backend
192
+ """
193
+ try:
194
+ self.logger.info(
195
+ "📥 _handle_backend_message called with message: %s", str(message)[:100]
196
+ )
197
+ # Write message to stdout as JSON
198
+ json_str = json.dumps(message)
199
+ self.logger.info("📤 Writing to stdout: %s", json_str[:100])
200
+ sys.stdout.write(json_str + "\n")
201
+ sys.stdout.flush()
202
+ self.logger.info("✅ Successfully sent to client")
203
+ except Exception as err: # pylint: disable=broad-exception-caught
204
+ self.logger.error("❌ Error forwarding message: %s", err, exc_info=True)
205
+
206
+ async def _stdin_loop(self) -> None:
207
+ """
208
+ Read messages from stdin (Claude Desktop) and route to backends.
209
+ """
210
+ loop = asyncio.get_event_loop()
211
+
212
+ self.logger.info("Starting stdin loop...")
213
+
214
+ try:
215
+ while not self._shutdown_event.is_set():
216
+ # Read line from stdin (non-blocking)
217
+ try:
218
+ line = await loop.run_in_executor(None, sys.stdin.readline)
219
+ if not line:
220
+ # EOF reached (stdin closed)
221
+ self.logger.info("stdin closed, shutting down...")
222
+ break
223
+
224
+ line = line.strip()
225
+ if not line:
226
+ continue
227
+
228
+ self.logger.debug("Received from client: %s...", line[:100])
229
+
230
+ # Parse JSON message
231
+ message = json.loads(line)
232
+
233
+ # Route to appropriate backend
234
+ if self.router:
235
+ await self.router.handle_message(message)
236
+
237
+ except json.JSONDecodeError as err:
238
+ self.logger.error("Invalid JSON from client: %s", err)
239
+ except Exception as err: # pylint: disable=broad-exception-caught
240
+ self.logger.error("Error processing message: %s", err)
241
+
242
+ except asyncio.CancelledError:
243
+ self.logger.info("stdin loop cancelled")
244
+ except Exception as err: # pylint: disable=broad-exception-caught
245
+ self.logger.error("Fatal error in stdin loop: %s", err)
246
+ finally:
247
+ self._shutdown_event.set()
248
+
249
+ async def run(self) -> None:
250
+ """
251
+ Run the MCP aggregator server.
252
+ """
253
+
254
+ # Setup signal handlers for graceful shutdown
255
+ def signal_handler(signum, _frame): # pylint: disable=unused-argument
256
+ self.logger.info("Received signal %d, shutting down...", signum)
257
+ self._shutdown_event.set()
258
+
259
+ signal.signal(signal.SIGINT, signal_handler)
260
+ signal.signal(signal.SIGTERM, signal_handler)
261
+
262
+ # Start backend initialization and stdin loop concurrently
263
+ # This allows the server to respond to Claude's initialize request
264
+ # while backends are still connecting in the background
265
+ try:
266
+ await asyncio.gather(
267
+ self.initialize_backends(),
268
+ self._stdin_loop(),
269
+ )
270
+ finally:
271
+ # Cleanup
272
+ self.logger.info("Shutting down backends...")
273
+ if self.router:
274
+ await self.router.shutdown_all()
275
+ self.logger.info("Shutdown complete")
276
+
277
+
278
+ def serve_mcp(workspace: str, include_staging: bool, debug: bool) -> None:
279
+ """
280
+ Start the qBraid MCP aggregator server.
281
+
282
+ Args:
283
+ workspace: Workspace name (lab, qbook, etc.)
284
+ include_staging: Include staging endpoints
285
+ debug: Enable debug logging
286
+ """
287
+ # Setup logging
288
+ setup_logging(debug=debug)
289
+ logger = logging.getLogger(__name__)
290
+
291
+ logger.info("Starting qBraid MCP aggregator...")
292
+ logger.info("Workspace: %s, Staging: %s, Debug: %s", workspace, include_staging, debug)
293
+
294
+ # Create qBraid session
295
+ try:
296
+ session = QbraidSession()
297
+ except Exception as err:
298
+ typer.secho(
299
+ f"Error creating qBraid session: {err}\n"
300
+ "Please run 'qbraid configure' to set up your credentials.",
301
+ fg=typer.colors.RED,
302
+ err=True,
303
+ )
304
+ raise typer.Exit(1)
305
+
306
+ # Create and run server
307
+ server = MCPAggregatorServer(
308
+ session=session,
309
+ workspace=workspace,
310
+ include_staging=include_staging,
311
+ debug=debug,
312
+ )
313
+
314
+ try:
315
+ asyncio.run(server.run())
316
+ except KeyboardInterrupt:
317
+ logger.info("Interrupted by user")
318
+ except Exception as err:
319
+ logger.error("Fatal error: %s", err, exc_info=debug)
320
+ typer.secho(f"Error: {err}", fg=typer.colors.RED, err=True)
321
+ raise typer.Exit(1)
qbraid_cli/pip/app.py CHANGED
@@ -5,6 +5,7 @@
5
5
  Module defining commands in the 'qbraid pip' namespace.
6
6
 
7
7
  """
8
+
8
9
  import subprocess
9
10
  import sys
10
11
 
@@ -15,8 +16,7 @@ from qbraid_core.system.executables import get_active_python_path
15
16
  from qbraid_cli.handlers import handle_error
16
17
  from qbraid_cli.pip.hooks import get_env_cfg_path, safe_set_include_sys_packages
17
18
 
18
- # disable pretty_exceptions_show_locals to avoid printing sensative information in the traceback
19
- pip_app = typer.Typer(help="Run pip command in active qBraid environment.")
19
+ pip_app = typer.Typer(help="Run pip command in active qBraid environment.", no_args_is_help=True)
20
20
 
21
21
 
22
22
  @pip_app.command(
qbraid_cli/pip/hooks.py CHANGED
@@ -5,6 +5,7 @@
5
5
  Module defining pre- and post-command hooks for the 'qbraid pip' namespace.
6
6
 
7
7
  """
8
+
8
9
  import sys
9
10
  from pathlib import Path
10
11
  from typing import Optional, Union
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: qbraid-cli
3
- Version: 0.8.5a1
3
+ Version: 0.12.0a0
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
- License: Proprietary
6
+ License-Expression: LicenseRef-Proprietary
7
7
  Project-URL: Homepage, https://docs.qbraid.com/cli/user-guide/overview
8
8
  Project-URL: Documentation, https://docs.qbraid.com/cli/api-reference/qbraid
9
9
  Project-URL: Bug Tracker, https://github.com/qBraid/community/issues
@@ -12,7 +12,6 @@ Keywords: qbraid,cli,quantum,cloud
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Natural Language :: English
15
- Classifier: License :: Other/Proprietary License
16
15
  Classifier: Intended Audience :: System Administrators
17
16
  Classifier: Operating System :: Microsoft :: Windows
18
17
  Classifier: Operating System :: POSIX :: Linux
@@ -23,20 +22,28 @@ Classifier: Programming Language :: Python :: 3.9
23
22
  Classifier: Programming Language :: Python :: 3.10
24
23
  Classifier: Programming Language :: Python :: 3.11
25
24
  Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
26
27
  Requires-Python: >=3.9
27
28
  Description-Content-Type: text/markdown
28
29
  License-File: LICENSE
29
30
  Requires-Dist: typer>=0.12.1
30
31
  Requires-Dist: rich>=10.11.0
31
- Requires-Dist: qbraid-core[environments]>=0.1.17
32
+ Requires-Dist: click<=8.1.8
33
+ Requires-Dist: qbraid-core[environments]>=0.2.0a0
34
+ Provides-Extra: jobs
35
+ Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
36
+ Provides-Extra: envs
37
+ Requires-Dist: qbraid-core[environments]==0.2.0a0; extra == "envs"
38
+ Provides-Extra: mcp
39
+ Requires-Dist: qbraid-core[mcp]==0.2.0a0; extra == "mcp"
32
40
  Provides-Extra: dev
33
- Requires-Dist: ruff; extra == "dev"
34
41
  Requires-Dist: isort; extra == "dev"
35
42
  Requires-Dist: black; extra == "dev"
36
43
  Requires-Dist: pytest; extra == "dev"
37
44
  Requires-Dist: pytest-cov; extra == "dev"
38
- Provides-Extra: jobs
39
- Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
45
+ Requires-Dist: pytest-asyncio; extra == "dev"
46
+ Dynamic: license-file
40
47
 
41
48
  <img width="full" alt="qbraid_cli" src="https://qbraid-static.s3.amazonaws.com/logos/qbraid-cli-banner.png">
42
49
 
@@ -49,7 +56,11 @@ Requires-Dist: amazon-braket-sdk>=1.48.1; extra == "jobs"
49
56
 
50
57
  Command Line Interface for interacting with all parts of the qBraid platform.
51
58
 
52
- 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/lab/user-guide/overview) platform, the CLI now supports local installations as well. This enhancement broadens access to features like [qBraid Quantum Jobs](https://docs.qbraid.com/cli/user-guide/quantum-jobs), enabling direct acess to QPU devices from leading providers like IonQ, Oxford Quantum Circuits, QuEra, Rigetti, and IQM, as well as on-demand simulators from qBraid and AWS, all using qBraid [credits](https://docs.qbraid.com/home/pricing), with no additional access keys required.
59
+ 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/lab/user-guide/overview) platform, the CLI now supports local installations as well. This enhancement broadens access to features like [qBraid Quantum Jobs](https://docs.qbraid.com/cli/user-guide/quantum-jobs), enabling direct, pre-configured access to QPUs from IonQ, Oxford Quantum Circuits, QuEra, Rigetti, and IQM, as well as on-demand simulators from qBraid, AWS, IonQ, QuEra, and NEC. See [pricing](https://docs.qbraid.com/home/pricing) for more.
60
+
61
+ *Resources*:
62
+ - [User Guide](https://docs.qbraid.com/cli/user-guide/overview)
63
+ - [API Reference](https://docs.qbraid.com/cli/api-reference/qbraid)
53
64
 
54
65
  ## Getting Started
55
66
 
@@ -66,6 +77,12 @@ You can also install the qBraid-CLI from PyPI with:
66
77
  pip install qbraid-cli
67
78
  ```
68
79
 
80
+ To manage qBraid [environments](https://docs.qbraid.com/lab/user-guide/environments) using the CLI, you must also install the `envs` extra:
81
+
82
+ ```bash
83
+ pip install 'qbraid-cli[envs]'
84
+ ```
85
+
69
86
  ## Local configuration
70
87
 
71
88
  After installation, you must configure your account credentials to use the CLI locally:
@@ -74,12 +91,14 @@ After installation, you must configure your account credentials to use the CLI l
74
91
  [account.qbraid.com](https://account.qbraid.com/)
75
92
  2. Copy your API Key token from the left side of
76
93
  your [account page](https://account.qbraid.com/):
77
- 3. Save your API key from step 2 in local configuration file `~/.qbraid/qbraidrc` using:
94
+ 3. Save your API key from step 2 in local [configuration file](https://docs.qbraid.com/cli/user-guide/config-files) `~/.qbraid/qbraidrc` using:
78
95
 
79
96
  ```bash
80
97
  $ qbraid configure
81
98
  ```
82
99
 
100
+ For more on API keys, see [documentation](https://docs.qbraid.com/home/account#api-keys).
101
+
83
102
  ## Basic Commands
84
103
 
85
104
  ```bash
@@ -139,12 +158,18 @@ Options
139
158
  --help Show this message and exit.
140
159
 
141
160
  Commands
161
+ account Manage qBraid account
162
+ admin CI/CD commands for qBraid maintainers.
142
163
  configure Configure qBraid CLI options.
143
- credits Manage qBraid credits.
164
+ account Manage qBraid account.
165
+ chat Interact with qBraid AI chat service.
144
166
  devices Manage qBraid quantum devices.
145
167
  envs Manage qBraid environments.
168
+ files Manage qBraid cloud storage files.
146
169
  jobs Manage qBraid quantum jobs.
147
170
  kernels Manage qBraid kernels.
171
+ mcp MCP (Model Context Protocol) aggregator commands.
172
+ pip Run pip command in active qBraid environment.
148
173
  ```
149
174
 
150
175
  To get the version of the qBraid CLI:
@@ -170,7 +195,5 @@ In [1]: %load_ext qbraid_magic
170
195
  Now you can continue to use the qBraid-CLI as normal from within your Jupyter notebook using the magic ``%`` operator, e.g.
171
196
 
172
197
  ```python
173
- In [2]: %qbraid jobs state
174
-
175
- In [3]: %qbraid jobs enable braket -y
198
+ In [2]: %qbraid chat -f code -p "Write a Qiskit bell circuit"
176
199
  ```
@@ -0,0 +1,46 @@
1
+ qbraid_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ qbraid_cli/_version.py,sha256=3XwaThsiOWydODTKqEaylQmodo5qZxp3-tSzxEJq1sw,456
3
+ qbraid_cli/exceptions.py,sha256=KjlhYJhSHMVazaNiBjD_Ur06w4sekP8zRsFzBdyIpno,672
4
+ qbraid_cli/handlers.py,sha256=qRxrB37-n9WBYIAf63KLEAPSQ7Hfhb1qRaHgsA2TVH8,8069
5
+ qbraid_cli/main.py,sha256=s0PA-jlebLxrFiI_mPDhioQ8JHTvMOjprFa7vbsmLII,3996
6
+ qbraid_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ qbraid_cli/account/__init__.py,sha256=smlpUcVkM3QEbJG0norGM7i71XBJlUGQYByswTfPnmg,181
8
+ qbraid_cli/account/app.py,sha256=_On93HBaBmyizcxnArpdN6zeoA1lFMNPhya0DvBDTJ4,1956
9
+ qbraid_cli/admin/__init__.py,sha256=qcWD5mQEUCtr49mrUpZmk7eGDe0L_Gtc8RwZmzIXSwo,175
10
+ qbraid_cli/admin/app.py,sha256=i_JeyJYHT6qoJrsTuf_eippp7AG6ZJ_N6-Dsrpv2XHQ,1476
11
+ qbraid_cli/admin/headers.py,sha256=QWAEuOu3rqumngLlOaGTI2R2wqyqmC0gUNpRt_74pd0,10610
12
+ qbraid_cli/admin/validation.py,sha256=fhpttxupCGBk56ExQPuuQm8nMnptLLy_8sj-EjpM8g0,729
13
+ qbraid_cli/chat/__init__.py,sha256=NO41vndEdfr0vDynNcmHFh-nhzWjnWqGm4M9parikck,258
14
+ qbraid_cli/chat/app.py,sha256=-YqCLGDh4ezF149xB3dfuUAQotKAklZwYp0BL3HhA90,2256
15
+ qbraid_cli/configure/__init__.py,sha256=YaJ74Ztz2vl3eYp8_jVBucWkXscxz7EZEIzr70OfuOM,187
16
+ qbraid_cli/configure/actions.py,sha256=Zv-y7iGgj1fwYceMSXrurpK2PyFCIitKXPqCb4H9AZo,3818
17
+ qbraid_cli/configure/app.py,sha256=CxzQmWDpCwpNe4HO7sOxJzbFwJ4dayzD8sjzefQvNNE,7260
18
+ qbraid_cli/configure/claude_config.py,sha256=OJqdEA0wr19F4BnZMAxRBf7rA9FehX12VzC6TQ-rr6c,6457
19
+ qbraid_cli/devices/__init__.py,sha256=hiScO-px6jCL5cJj5Hbty55EUfNejTO4bmqUZuS3aqc,181
20
+ qbraid_cli/devices/app.py,sha256=B-cRdV092C6ACeu3C-5l2P_izpPDxvCzzAKfxO1WkaM,3224
21
+ qbraid_cli/devices/validation.py,sha256=YhShyUufgrKnx2XjXOXF-PqFJYklJT9CgeqIwKcNam4,809
22
+ qbraid_cli/envs/__init__.py,sha256=1-cMvrATsddYxcetPJWxq6bEOqJWMktGdhoZ4qm8euA,172
23
+ qbraid_cli/envs/activate.py,sha256=pYugi2MmEjHKQlky7fVHvB_BpBu7xgOwa1Vrh50DXEo,3251
24
+ qbraid_cli/envs/app.py,sha256=VVLNz_AvlH66RuV1JMB4mDPxXB7VhVg8jEmRKoZz2Ko,33035
25
+ qbraid_cli/envs/create.py,sha256=2isv1eLFKxVutbrkHawMQK67Cz939eLwfhMBtVHiOas,1060
26
+ qbraid_cli/envs/data_handling.py,sha256=Ibnp2yJoUDpivb_sNqi0suYgJZNat_LmM6Ya0Ovez5s,1288
27
+ qbraid_cli/files/__init__.py,sha256=3_yhgFoNcviEtS6B75uJBrfFFUjsrMcccCNEntJ54xU,175
28
+ qbraid_cli/files/app.py,sha256=gNa88cfAmpzYd9VOK7Q-OWJ1LyyHxq88PKhg8Q9w9Mk,3771
29
+ qbraid_cli/jobs/__init__.py,sha256=qVLRHYIzP4XHpx_QWP_vCzd3LsCscCORaEx-Vcbx29U,172
30
+ qbraid_cli/jobs/app.py,sha256=NchePouZkoHWxqV1lwiYuXwrLeP99zITKz5Ezc1pm2I,5383
31
+ qbraid_cli/jobs/toggle_braket.py,sha256=3AEu-Z5q4avduB-fJMyMTVTuyZXuA8m-hnvi325wIv4,7444
32
+ qbraid_cli/jobs/validation.py,sha256=KlkqVH1-vlNCHSayEpxzyXU86_TMN5prGfMFEoyBsFs,2971
33
+ qbraid_cli/kernels/__init__.py,sha256=jORS9vV17s5laQyq8gSVB18EPBImgEIbMZ1wKC094DA,181
34
+ qbraid_cli/kernels/app.py,sha256=n-iyWJHy7_ML6qk4pp-v_rQkGA7WfnZMG8gyiCFGO1c,2948
35
+ qbraid_cli/mcp/__init__.py,sha256=GwW67sQpUViWhTpd6yq-kG8HH87QmCjKO0v2Ys_8Qpw,195
36
+ qbraid_cli/mcp/app.py,sha256=TQnM9LI9OsgbGV6Pkp_Ri7d62dJs5voPKmG1FeweSy0,3463
37
+ qbraid_cli/mcp/serve.py,sha256=4LFXjuv6CQPIuskPxcFXS0qE2igv1vYmLup-u1xhIZ0,11384
38
+ qbraid_cli/pip/__init__.py,sha256=tJtU0rxn-ODogNh5Y4pp_BgDQXMN-3JY1QGj0OZHwjQ,169
39
+ qbraid_cli/pip/app.py,sha256=jkk-djductrDOJIRYfHK_7WDJ12f0zOT3MMkiZp97oM,1365
40
+ qbraid_cli/pip/hooks.py,sha256=jkIeev3cOd-cmaoJSdSqbmhTYCs6z1we84FMqa3ZoZw,2124
41
+ qbraid_cli-0.12.0a0.dist-info/licenses/LICENSE,sha256=3KvWfsaXBCqbZ4qwk5jN9CQXE53tQeaZTySN5a-CCgQ,2753
42
+ qbraid_cli-0.12.0a0.dist-info/METADATA,sha256=9RRo480Itl5YHFjHso2qR_ecYtJThGQTO5OZ9bUbT5Q,7865
43
+ qbraid_cli-0.12.0a0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ qbraid_cli-0.12.0a0.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
45
+ qbraid_cli-0.12.0a0.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
46
+ qbraid_cli-0.12.0a0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (73.0.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,10 +1,10 @@
1
- qBraid Closed-Source Software License
1
+ qBraid Commercial Software License
2
2
 
3
- Copyright (c) 2024, qBraid Development Team
3
+ Copyright (c) 2025, qBraid Development Team
4
4
 
5
5
  All rights reserved.
6
6
 
7
- This license agreement ("License") is between the qBraid Development Team ("Author") and you, the Licensee. By using or distributing the qBraid ("Software"), you agree to the following terms:
7
+ This license agreement ("License") is between the qBraid Development Team ("Author") and you, the Licensee. This software and associated documentation files (the "Software") may only be used by authorized qBraid customers who have agreed to qBraid's Terms of Service and have a valid subscription or license agreement with qBraid. By using or distributing this Software, you agree to the following terms:
8
8
 
9
9
  1. Grant of License.
10
10
 
@@ -24,7 +24,7 @@ This license agreement ("License") is between the qBraid Development Team ("Auth
24
24
 
25
25
  5. Attribution
26
26
 
27
- If the Software is used in a non-private setting, including but not limited to academic work, commercial settings, or published literature, attribution must be given to the "qBraid Jupyter Environment Manager authored by the qBraid Development Team."
27
+ If the Software is used in a non-private setting, including but not limited to academic work, commercial settings, or published literature, attribution must be given to the "qBraid CLI authored by the qBraid Development Team."
28
28
 
29
29
  6. Disclaimer of Warranty.
30
30
 
@@ -39,3 +39,5 @@ This license agreement ("License") is between the qBraid Development Team ("Auth
39
39
  This License is effective until terminated. Your rights under this License will terminate automatically without notice from the Author if you fail to comply with any term(s) of this License.
40
40
 
41
41
  By using the Software, you agree to be bound by the terms of this License. Redistribution of the Software or use of the Software other than as specifically authorized under this License is prohibited and may result in severe civil and criminal penalties.
42
+
43
+ For licensing inquiries, please contact: contact@qbraid.com
@@ -1,114 +0,0 @@
1
- # Copyright (c) 2024, qBraid Development Team
2
- # All rights reserved.
3
-
4
- """
5
- Module defining commands in the 'qbraid admin buildlogs' namespace.
6
-
7
- This module uses the Typer library to create CLI commands for managing Docker builds and logs
8
- in an administrative context.
9
- """
10
-
11
- import json
12
-
13
- import typer
14
- from qbraid_core.exceptions import RequestsApiError
15
- from qbraid_core.services.admin.client import AdminClient
16
- from rich.console import Console
17
-
18
- from qbraid_cli.handlers import handle_error
19
-
20
- buildlogs_app = typer.Typer(
21
- help="Manage qBraid containerized services logs.", pretty_exceptions_show_locals=False
22
- )
23
- console = Console()
24
-
25
-
26
- @buildlogs_app.command(name="get")
27
- def get_docker_build_logs(
28
- build_id: str = typer.Option(None, "--build_id", "-b", help="Name of the build ID")
29
- ) -> None:
30
- """
31
- Fetches and displays Docker build logs for a specified build ID.
32
-
33
- Args:
34
- build_id (str, optional): The unique identifier for the Docker build.
35
-
36
- This function queries the administrative backend to retrieve and display build logs.
37
- If a build ID is provided, it will retrieve and display logs specific to that build ID.
38
- If build ID not provided, fetches all logs.
39
- """
40
- client = AdminClient()
41
-
42
- build_log = client.get_docker_build_logs(build_id)
43
- if build_id and "buildLogs" in build_log and build_log["buildLogs"]:
44
- log_entry = build_log["buildLogs"][0]
45
- console.print(log_entry)
46
- else:
47
- console.print(build_log)
48
-
49
-
50
- @buildlogs_app.command(name="post")
51
- def post_docker_build_log(
52
- data: str = typer.Option(..., "--data", "-d", help="Data to post to Docker logs")
53
- ) -> None:
54
- """
55
- Posts a new Docker build log entry.
56
-
57
- Args:
58
- data (str): JSON string containing the data to be logged.
59
-
60
- This command converts a JSON string into a dictionary and sends it to the backend service
61
- to create a new Docker build log.
62
- """
63
- client = AdminClient()
64
-
65
- try:
66
- data_dict = json.loads(data)
67
- console.print(client.post_docker_build_logs(data_dict))
68
- except RequestsApiError:
69
- handle_error(message="Couldn't post a build_log.")
70
-
71
-
72
- @buildlogs_app.command(name="put")
73
- def put_docker_build_log(
74
- build_id: str = typer.Option(..., "--build_id", "-b", help="Name of the build ID"),
75
- data: str = typer.Option(..., "--data", "-d", help="Data to post to Docker logs"),
76
- ) -> None:
77
- """
78
- Updates an existing Docker build log entry by a given build ID.
79
-
80
- Args:
81
- build_id (str): The unique identifier of the Docker build to update.
82
- data (str): JSON string containing the updated data for the log.
83
-
84
- This command updates a Docker build log entry, identified by the provided build ID,
85
- with the new data provided in JSON format.
86
- """
87
- client = AdminClient()
88
-
89
- try:
90
- data_dict = json.loads(data)
91
- console.print(client.put_docker_build_logs(build_id, data_dict))
92
- except RequestsApiError:
93
- handle_error(message="Couldn't post a build_log.")
94
-
95
-
96
- @buildlogs_app.command(name="delete")
97
- def delete_docker_build_log(
98
- build_id: str = typer.Option(..., "--build_id", "-b", help="ID of the build log to delete")
99
- ) -> None:
100
- """
101
- Deletes a Docker build log entry by a specified build ID.
102
-
103
- Args:
104
- build_id (str): The unique identifier of the Docker build log to delete.
105
-
106
- This command sends a request to delete a Docker build log identified by the provided build ID.
107
- """
108
- client = AdminClient()
109
-
110
- console.print(client.delete_docker_build_logs(build_id))
111
-
112
-
113
- if __name__ == "__main__":
114
- buildlogs_app()