mantatech-sdk 0.5b0.dev65__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.
- manta/__init__.light.py +22 -0
- manta/__init__.py +83 -0
- manta/__main__.py +21 -0
- manta/apis/__init__.py +7 -0
- manta/apis/async_user_api.py +6458 -0
- manta/apis/graph.py +498 -0
- manta/apis/module.py +316 -0
- manta/apis/results.py +251 -0
- manta/apis/swarm.py +206 -0
- manta/apis/user_api.py +1016 -0
- manta/cli/__init__.py +1 -0
- manta/cli/commands/__init__.py +1 -0
- manta/cli/commands/base_handler.py +229 -0
- manta/cli/commands/doc.py +192 -0
- manta/cli/commands/install.py +346 -0
- manta/cli/commands/sdk.py +9 -0
- manta/cli/commands/sdk_cluster.py +211 -0
- manta/cli/commands/sdk_config.py +347 -0
- manta/cli/commands/sdk_globals.py +280 -0
- manta/cli/commands/sdk_logs.py +174 -0
- manta/cli/commands/sdk_main.py +167 -0
- manta/cli/commands/sdk_module.py +516 -0
- manta/cli/commands/sdk_nodes.py +168 -0
- manta/cli/commands/sdk_original.py +3873 -0
- manta/cli/commands/sdk_results.py +265 -0
- manta/cli/commands/sdk_swarm.py +454 -0
- manta/cli/commands/sdk_user.py +234 -0
- manta/cli/commands/status.py +292 -0
- manta/cli/component_detector.py +112 -0
- manta/cli/config_manager.py +445 -0
- manta/cli/main.py +265 -0
- manta/cli/utils/__init__.py +27 -0
- manta/cli/utils/converters.py +140 -0
- manta/clients/cluster_management_client.py +486 -0
- manta/clients/local_client.py +149 -0
- manta/clients/module_management_client.py +217 -0
- manta/clients/swarm_management_client.py +562 -0
- manta/clients/user_management_client.py +395 -0
- manta/clients/world_client.py +195 -0
- manta/light/__init__.py +31 -0
- manta/light/globals.py +245 -0
- manta/light/local.py +407 -0
- manta/light/logging_config.py +39 -0
- manta/light/path.py +116 -0
- manta/light/results.py +236 -0
- manta/light/task.py +100 -0
- manta/light/utils.py +217 -0
- manta/light/world.py +177 -0
- mantatech_sdk-0.5b0.dev65.dist-info/METADATA +1039 -0
- mantatech_sdk-0.5b0.dev65.dist-info/RECORD +54 -0
- mantatech_sdk-0.5b0.dev65.dist-info/WHEEL +5 -0
- mantatech_sdk-0.5b0.dev65.dist-info/entry_points.txt +2 -0
- mantatech_sdk-0.5b0.dev65.dist-info/licenses/LICENSE +683 -0
- mantatech_sdk-0.5b0.dev65.dist-info/top_level.txt +1 -0
manta/cli/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI functionality for manta-sdk."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI commands for manta-sdk."""
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"""Base command handler interface for modular SDK commands."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import traceback
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
10
|
+
|
|
11
|
+
from ..config_manager import SDKConfigManager
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseSDKHandler(ABC):
|
|
15
|
+
"""Base class for SDK command handlers."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, console: Console, config_manager: SDKConfigManager):
|
|
18
|
+
self.console = console
|
|
19
|
+
self.config_manager = config_manager
|
|
20
|
+
self.debug = False # Can be set to True for detailed error output
|
|
21
|
+
|
|
22
|
+
def print(self, *args, **kwargs):
|
|
23
|
+
"""Print with console (always available in SDK context)."""
|
|
24
|
+
self.console.print(*args, **kwargs)
|
|
25
|
+
|
|
26
|
+
def print_error(self, message: str):
|
|
27
|
+
"""Print error message."""
|
|
28
|
+
self.console.print(f"[red]Error:[/red] {message}")
|
|
29
|
+
|
|
30
|
+
def print_success(self, message: str):
|
|
31
|
+
"""Print success message."""
|
|
32
|
+
self.console.print(f"[green]Success:[/green] {message}")
|
|
33
|
+
|
|
34
|
+
def print_warning(self, message: str):
|
|
35
|
+
"""Print warning message."""
|
|
36
|
+
self.console.print(f"[yellow]Warning:[/yellow] {message}")
|
|
37
|
+
|
|
38
|
+
def _run_with_progress(self, async_func, message: str):
|
|
39
|
+
"""Run an async function with progress indication and proper error handling."""
|
|
40
|
+
try:
|
|
41
|
+
with Progress(
|
|
42
|
+
SpinnerColumn(),
|
|
43
|
+
TextColumn("[progress.description]{task.description}"),
|
|
44
|
+
console=self.console,
|
|
45
|
+
transient=True, # Remove progress bar after completion
|
|
46
|
+
) as progress:
|
|
47
|
+
task = progress.add_task(message, total=None)
|
|
48
|
+
|
|
49
|
+
# Create event loop and run the async function
|
|
50
|
+
loop = asyncio.new_event_loop()
|
|
51
|
+
asyncio.set_event_loop(loop)
|
|
52
|
+
try:
|
|
53
|
+
result = loop.run_until_complete(async_func())
|
|
54
|
+
progress.update(task, completed=True)
|
|
55
|
+
return result
|
|
56
|
+
except KeyboardInterrupt:
|
|
57
|
+
progress.stop()
|
|
58
|
+
self.print_warning("Operation cancelled by user")
|
|
59
|
+
raise
|
|
60
|
+
except Exception as e:
|
|
61
|
+
progress.stop()
|
|
62
|
+
# Extract meaningful error message
|
|
63
|
+
error_msg = self._extract_error_message(e)
|
|
64
|
+
self.print_error(error_msg)
|
|
65
|
+
|
|
66
|
+
if self.debug:
|
|
67
|
+
self.console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
68
|
+
|
|
69
|
+
raise
|
|
70
|
+
finally:
|
|
71
|
+
loop.close()
|
|
72
|
+
|
|
73
|
+
except KeyboardInterrupt:
|
|
74
|
+
# Re-raise keyboard interrupt so the CLI can exit properly
|
|
75
|
+
raise
|
|
76
|
+
except Exception:
|
|
77
|
+
# Error was already printed, just return None to indicate failure
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
def _extract_error_message(self, error: Exception) -> str:
|
|
81
|
+
"""Extract a meaningful error message from various exception types."""
|
|
82
|
+
error_str = str(error)
|
|
83
|
+
|
|
84
|
+
# Handle gRPC errors specifically
|
|
85
|
+
if "StatusCode" in error_str:
|
|
86
|
+
# Extract the gRPC error details
|
|
87
|
+
if "UNAVAILABLE" in error_str:
|
|
88
|
+
return "Service unavailable - please check if the backend services are running"
|
|
89
|
+
elif "UNAUTHENTICATED" in error_str:
|
|
90
|
+
return "Authentication failed - please check your JWT token"
|
|
91
|
+
elif "PERMISSION_DENIED" in error_str:
|
|
92
|
+
return "Permission denied - you don't have access to this resource"
|
|
93
|
+
elif "NOT_FOUND" in error_str:
|
|
94
|
+
return "Resource not found"
|
|
95
|
+
elif "ALREADY_EXISTS" in error_str:
|
|
96
|
+
return "Resource already exists"
|
|
97
|
+
elif "DEADLINE_EXCEEDED" in error_str:
|
|
98
|
+
return "Request timed out - the operation took too long"
|
|
99
|
+
elif "CANCELLED" in error_str:
|
|
100
|
+
return "Request was cancelled"
|
|
101
|
+
elif "INTERNAL" in error_str:
|
|
102
|
+
# Try to extract the actual error message from internal errors
|
|
103
|
+
if "details =" in error_str:
|
|
104
|
+
details_start = error_str.find("details =") + 10
|
|
105
|
+
details_end = error_str.find('"', details_start + 1)
|
|
106
|
+
if details_end > details_start:
|
|
107
|
+
return f"Backend error: {error_str[details_start:details_end]}"
|
|
108
|
+
return "Internal server error"
|
|
109
|
+
|
|
110
|
+
# Handle connection errors
|
|
111
|
+
if "Failed to connect" in error_str or "Connection refused" in error_str:
|
|
112
|
+
return "Cannot connect to backend service - please check if services are running"
|
|
113
|
+
|
|
114
|
+
# Handle timeout errors
|
|
115
|
+
if "timeout" in error_str.lower():
|
|
116
|
+
return "Operation timed out - please try again"
|
|
117
|
+
|
|
118
|
+
# Default: return the original error message
|
|
119
|
+
return error_str
|
|
120
|
+
|
|
121
|
+
def _run_async(self, coro):
|
|
122
|
+
"""Run async coroutine with proper error handling."""
|
|
123
|
+
try:
|
|
124
|
+
loop = asyncio.new_event_loop()
|
|
125
|
+
asyncio.set_event_loop(loop)
|
|
126
|
+
try:
|
|
127
|
+
return loop.run_until_complete(coro)
|
|
128
|
+
finally:
|
|
129
|
+
loop.close()
|
|
130
|
+
except KeyboardInterrupt:
|
|
131
|
+
self.print_warning("Operation cancelled by user")
|
|
132
|
+
raise
|
|
133
|
+
except Exception as e:
|
|
134
|
+
error_msg = self._extract_error_message(e)
|
|
135
|
+
self.print_error(error_msg)
|
|
136
|
+
if self.debug:
|
|
137
|
+
self.console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
def _get_user_api(self):
|
|
141
|
+
"""Get configured AsyncUserAPI instance."""
|
|
142
|
+
try:
|
|
143
|
+
# Dynamic import of manta-sdk
|
|
144
|
+
from manta.apis import AsyncUserAPI
|
|
145
|
+
|
|
146
|
+
# Get connection parameters from config manager
|
|
147
|
+
try:
|
|
148
|
+
# Use config override if specified, otherwise use active config
|
|
149
|
+
config_name = getattr(self, "_config_override", None)
|
|
150
|
+
connection_params = self.config_manager.get_connection_params(
|
|
151
|
+
config_name
|
|
152
|
+
)
|
|
153
|
+
except Exception as e:
|
|
154
|
+
self.print_error(f"Failed to get connection configuration: {e}")
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
if not connection_params:
|
|
158
|
+
self.print_error(
|
|
159
|
+
"No configuration found. Run 'manta sdk config init' first."
|
|
160
|
+
)
|
|
161
|
+
return None
|
|
162
|
+
|
|
163
|
+
# Create API instance with configuration
|
|
164
|
+
# Note: AsyncUserAPI constructor order is (token, host, port, cafile, certfile, keyfile)
|
|
165
|
+
# Extract certificate paths from cert_folder if use_tls is enabled
|
|
166
|
+
cafile = None
|
|
167
|
+
certfile = None
|
|
168
|
+
keyfile = None
|
|
169
|
+
|
|
170
|
+
if connection_params.get("use_tls", False) and connection_params.get(
|
|
171
|
+
"cert_folder"
|
|
172
|
+
):
|
|
173
|
+
from pathlib import Path
|
|
174
|
+
|
|
175
|
+
cert_path = Path(connection_params["cert_folder"])
|
|
176
|
+
# Try common certificate file names
|
|
177
|
+
if (cert_path / "ca.crt").exists():
|
|
178
|
+
cafile = str(cert_path / "ca.crt")
|
|
179
|
+
if (cert_path / "client.crt").exists():
|
|
180
|
+
certfile = str(cert_path / "client.crt")
|
|
181
|
+
if (cert_path / "client.key").exists():
|
|
182
|
+
keyfile = str(cert_path / "client.key")
|
|
183
|
+
|
|
184
|
+
return AsyncUserAPI(
|
|
185
|
+
token=connection_params["token"],
|
|
186
|
+
host=connection_params.get("host", "localhost"),
|
|
187
|
+
port=connection_params.get("port", 50052),
|
|
188
|
+
cafile=cafile,
|
|
189
|
+
certfile=certfile,
|
|
190
|
+
keyfile=keyfile,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
except ImportError:
|
|
194
|
+
self.print_error(
|
|
195
|
+
"manta-sdk not available. Install with: pip install manta-sdk[api]"
|
|
196
|
+
)
|
|
197
|
+
return None
|
|
198
|
+
except Exception as e:
|
|
199
|
+
self.print_error(f"Failed to create API client: {e}")
|
|
200
|
+
return None
|
|
201
|
+
|
|
202
|
+
def set_profile_override(self, config: Optional[str]):
|
|
203
|
+
"""Set config override for this handler."""
|
|
204
|
+
self._config_override = config
|
|
205
|
+
|
|
206
|
+
def enable_debug(self, enabled: bool = True):
|
|
207
|
+
"""Enable or disable debug output."""
|
|
208
|
+
self.debug = enabled
|
|
209
|
+
|
|
210
|
+
def _format_size(self, size_bytes: float) -> str:
|
|
211
|
+
"""Format byte size in human readable format."""
|
|
212
|
+
if size_bytes == 0:
|
|
213
|
+
return "0 B"
|
|
214
|
+
|
|
215
|
+
for unit in ["B", "KB", "MB", "GB", "TB"]:
|
|
216
|
+
if size_bytes < 1024.0:
|
|
217
|
+
return f"{size_bytes:.1f} {unit}"
|
|
218
|
+
size_bytes /= 1024.0
|
|
219
|
+
return f"{size_bytes:.1f} PB"
|
|
220
|
+
|
|
221
|
+
@abstractmethod
|
|
222
|
+
def add_subparsers(self, parent_parser):
|
|
223
|
+
"""Add command-specific subparsers to the parent parser."""
|
|
224
|
+
pass
|
|
225
|
+
|
|
226
|
+
@abstractmethod
|
|
227
|
+
def handle(self, args) -> int:
|
|
228
|
+
"""Handle command execution."""
|
|
229
|
+
pass
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Documentation commands for Manta CLI."""
|
|
2
|
+
|
|
3
|
+
import webbrowser
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.panel import Panel
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DocCommands:
|
|
11
|
+
"""Handle documentation-related CLI commands."""
|
|
12
|
+
|
|
13
|
+
# Documentation URLs
|
|
14
|
+
DOCS = {
|
|
15
|
+
"main": "https://github.com/Openmesh-Network/manta",
|
|
16
|
+
"sdk": "https://github.com/Openmesh-Network/manta/blob/main/manta-sdk/README.md",
|
|
17
|
+
"node": "https://github.com/Openmesh-Network/manta/blob/main/manta-node/README.md",
|
|
18
|
+
"api": "https://github.com/Openmesh-Network/manta/blob/main/docs/api.md",
|
|
19
|
+
"examples": "https://github.com/Openmesh-Network/manta/tree/main/examples",
|
|
20
|
+
"quickstart": "https://github.com/Openmesh-Network/manta/blob/main/docs/quickstart.md",
|
|
21
|
+
"architecture": "https://github.com/Openmesh-Network/manta/blob/main/docs/architecture.md",
|
|
22
|
+
"configuration": "https://github.com/Openmesh-Network/manta/blob/main/docs/configuration.md",
|
|
23
|
+
"deployment": "https://github.com/Openmesh-Network/manta/blob/main/docs/deployment.md",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def __init__(self, console: Console):
|
|
27
|
+
self.console = console
|
|
28
|
+
|
|
29
|
+
def print(self, *args, **kwargs):
|
|
30
|
+
"""Print with console."""
|
|
31
|
+
self.console.print(*args, **kwargs)
|
|
32
|
+
|
|
33
|
+
def print_error(self, message: str):
|
|
34
|
+
"""Print error message."""
|
|
35
|
+
self.console.print(f"[red]Error:[/red] {message}")
|
|
36
|
+
|
|
37
|
+
def print_success(self, message: str):
|
|
38
|
+
"""Print success message."""
|
|
39
|
+
self.console.print(f"[green]Success:[/green] {message}")
|
|
40
|
+
|
|
41
|
+
def print_warning(self, message: str):
|
|
42
|
+
"""Print warning message."""
|
|
43
|
+
self.console.print(f"[yellow]Warning:[/yellow] {message}")
|
|
44
|
+
|
|
45
|
+
def handle(self, args) -> int:
|
|
46
|
+
"""Handle documentation commands."""
|
|
47
|
+
if hasattr(args, "doc_topic") and args.doc_topic:
|
|
48
|
+
return self.show_topic(
|
|
49
|
+
args.doc_topic,
|
|
50
|
+
open_browser=args.open if hasattr(args, "open") else False,
|
|
51
|
+
)
|
|
52
|
+
else:
|
|
53
|
+
return self.show_documentation_index()
|
|
54
|
+
|
|
55
|
+
def show_documentation_index(self) -> int:
|
|
56
|
+
"""Show documentation index with all available topics."""
|
|
57
|
+
self.print("š Manta Documentation")
|
|
58
|
+
self.print("=" * 25)
|
|
59
|
+
|
|
60
|
+
# Create table of documentation topics
|
|
61
|
+
table = Table(title="Available Documentation")
|
|
62
|
+
table.add_column("Topic", style="cyan")
|
|
63
|
+
table.add_column("Description", style="white")
|
|
64
|
+
table.add_column("Command", style="magenta")
|
|
65
|
+
|
|
66
|
+
topics = [
|
|
67
|
+
("main", "Main documentation and README", "manta doc main"),
|
|
68
|
+
("sdk", "SDK documentation", "manta doc sdk"),
|
|
69
|
+
("node", "Node documentation", "manta doc node"),
|
|
70
|
+
("api", "API reference", "manta doc api"),
|
|
71
|
+
("examples", "Example code and tutorials", "manta doc examples"),
|
|
72
|
+
("quickstart", "Quick start guide", "manta doc quickstart"),
|
|
73
|
+
("architecture", "Architecture overview", "manta doc architecture"),
|
|
74
|
+
("configuration", "Configuration guide", "manta doc configuration"),
|
|
75
|
+
("deployment", "Deployment guide", "manta doc deployment"),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
for topic, description, command in topics:
|
|
79
|
+
table.add_row(topic, description, command)
|
|
80
|
+
|
|
81
|
+
self.console.print(table)
|
|
82
|
+
|
|
83
|
+
# Show usage help
|
|
84
|
+
panel_text = (
|
|
85
|
+
"[cyan]View documentation:[/cyan]\n"
|
|
86
|
+
" manta doc <topic> - Show documentation URL\n"
|
|
87
|
+
" manta doc <topic> --open - Open in browser\n\n"
|
|
88
|
+
"[cyan]Examples:[/cyan]\n"
|
|
89
|
+
" manta doc quickstart\n"
|
|
90
|
+
" manta doc api --open\n\n"
|
|
91
|
+
"[cyan]Online Resources:[/cyan]\n"
|
|
92
|
+
f" Main Docs: {self.DOCS['main']}\n"
|
|
93
|
+
f" Examples: {self.DOCS['examples']}"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
panel = Panel.fit(panel_text, title="How to Use")
|
|
97
|
+
self.console.print(panel)
|
|
98
|
+
|
|
99
|
+
return 0
|
|
100
|
+
|
|
101
|
+
def show_topic(self, topic: str, open_browser: bool = False) -> int:
|
|
102
|
+
"""Show documentation for a specific topic."""
|
|
103
|
+
topic = topic.lower()
|
|
104
|
+
|
|
105
|
+
if topic not in self.DOCS:
|
|
106
|
+
self.print_error(f"Unknown documentation topic: {topic}")
|
|
107
|
+
self.print("Available topics:")
|
|
108
|
+
for t in self.DOCS.keys():
|
|
109
|
+
self.print(f" ⢠{t}")
|
|
110
|
+
return 1
|
|
111
|
+
|
|
112
|
+
url = self.DOCS[topic]
|
|
113
|
+
|
|
114
|
+
# Create panel with documentation info
|
|
115
|
+
panel_text = f"[cyan]Topic:[/cyan] {topic}\n[cyan]URL:[/cyan] {url}"
|
|
116
|
+
|
|
117
|
+
if topic == "main":
|
|
118
|
+
panel_text += "\n\n[yellow]Main documentation includes:[/yellow]\n"
|
|
119
|
+
panel_text += " ⢠Getting started guide\n"
|
|
120
|
+
panel_text += " ⢠Platform overview\n"
|
|
121
|
+
panel_text += " ⢠Installation instructions\n"
|
|
122
|
+
panel_text += " ⢠Basic usage examples"
|
|
123
|
+
elif topic == "sdk":
|
|
124
|
+
panel_text += "\n\n[yellow]SDK documentation includes:[/yellow]\n"
|
|
125
|
+
panel_text += " ⢠API client usage\n"
|
|
126
|
+
panel_text += " ⢠Task deployment\n"
|
|
127
|
+
panel_text += " ⢠Result retrieval\n"
|
|
128
|
+
panel_text += " ⢠Configuration management"
|
|
129
|
+
elif topic == "admin":
|
|
130
|
+
panel_text += "\n\n[yellow]Admin documentation includes:[/yellow]\n"
|
|
131
|
+
panel_text += " ⢠User management\n"
|
|
132
|
+
panel_text += " ⢠Cluster administration\n"
|
|
133
|
+
panel_text += " ⢠System monitoring\n"
|
|
134
|
+
panel_text += " ⢠Security settings"
|
|
135
|
+
elif topic == "node":
|
|
136
|
+
panel_text += "\n\n[yellow]Node documentation includes:[/yellow]\n"
|
|
137
|
+
panel_text += " ⢠Node installation\n"
|
|
138
|
+
panel_text += " ⢠Configuration options\n"
|
|
139
|
+
panel_text += " ⢠Resource management\n"
|
|
140
|
+
panel_text += " ⢠Troubleshooting"
|
|
141
|
+
elif topic == "api":
|
|
142
|
+
panel_text += "\n\n[yellow]API documentation includes:[/yellow]\n"
|
|
143
|
+
panel_text += " ⢠REST API endpoints\n"
|
|
144
|
+
panel_text += " ⢠gRPC service definitions\n"
|
|
145
|
+
panel_text += " ⢠Authentication methods\n"
|
|
146
|
+
panel_text += " ⢠Request/response schemas"
|
|
147
|
+
elif topic == "examples":
|
|
148
|
+
panel_text += "\n\n[yellow]Examples include:[/yellow]\n"
|
|
149
|
+
panel_text += " ⢠Federated learning examples\n"
|
|
150
|
+
panel_text += " ⢠Data processing pipelines\n"
|
|
151
|
+
panel_text += " ⢠Multi-node deployments\n"
|
|
152
|
+
panel_text += " ⢠Integration patterns"
|
|
153
|
+
elif topic == "quickstart":
|
|
154
|
+
panel_text += "\n\n[yellow]Quick start guide includes:[/yellow]\n"
|
|
155
|
+
panel_text += " ⢠5-minute setup\n"
|
|
156
|
+
panel_text += " ⢠First task deployment\n"
|
|
157
|
+
panel_text += " ⢠Basic CLI commands\n"
|
|
158
|
+
panel_text += " ⢠Common workflows"
|
|
159
|
+
elif topic == "architecture":
|
|
160
|
+
panel_text += "\n\n[yellow]Architecture documentation includes:[/yellow]\n"
|
|
161
|
+
panel_text += " ⢠System design overview\n"
|
|
162
|
+
panel_text += " ⢠Component relationships\n"
|
|
163
|
+
panel_text += " ⢠Communication patterns\n"
|
|
164
|
+
panel_text += " ⢠Security architecture"
|
|
165
|
+
elif topic == "configuration":
|
|
166
|
+
panel_text += "\n\n[yellow]Configuration guide includes:[/yellow]\n"
|
|
167
|
+
panel_text += " ⢠Configuration file structure\n"
|
|
168
|
+
panel_text += " ⢠Environment variables\n"
|
|
169
|
+
panel_text += " ⢠Profile management\n"
|
|
170
|
+
panel_text += " ⢠Advanced settings"
|
|
171
|
+
elif topic == "deployment":
|
|
172
|
+
panel_text += "\n\n[yellow]Deployment guide includes:[/yellow]\n"
|
|
173
|
+
panel_text += " ⢠Production deployment\n"
|
|
174
|
+
panel_text += " ⢠Docker configuration\n"
|
|
175
|
+
panel_text += " ⢠Kubernetes setup\n"
|
|
176
|
+
panel_text += " ⢠Scaling strategies"
|
|
177
|
+
|
|
178
|
+
panel = Panel.fit(panel_text, title=f"Documentation: {topic.capitalize()}")
|
|
179
|
+
self.console.print(panel)
|
|
180
|
+
|
|
181
|
+
if open_browser:
|
|
182
|
+
self.print(f"\nš Opening {url} in browser...")
|
|
183
|
+
try:
|
|
184
|
+
webbrowser.open(url)
|
|
185
|
+
self.print_success("Browser opened successfully!")
|
|
186
|
+
except Exception as e:
|
|
187
|
+
self.print_error(f"Failed to open browser: {e}")
|
|
188
|
+
self.print(f"Please visit: {url}")
|
|
189
|
+
else:
|
|
190
|
+
self.print(f"\nš” To open in browser, use: manta doc {topic} --open")
|
|
191
|
+
|
|
192
|
+
return 0
|