ttnn-visualizer 0.40.3__py3-none-any.whl → 0.42.0__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.
- ttnn_visualizer/app.py +21 -6
- ttnn_visualizer/csv_queries.py +135 -32
- ttnn_visualizer/decorators.py +7 -4
- ttnn_visualizer/exceptions.py +16 -0
- ttnn_visualizer/queries.py +3 -109
- ttnn_visualizer/remote_sqlite_setup.py +97 -19
- ttnn_visualizer/requirements.txt +1 -3
- ttnn_visualizer/sftp_operations.py +637 -219
- ttnn_visualizer/static/assets/{allPaths-DSFl5HNA.js → allPaths-wwXsGKJ2.js} +1 -1
- ttnn_visualizer/static/assets/{allPathsLoader-BwkPDbOI.js → allPathsLoader-BK9jqlVe.js} +2 -2
- ttnn_visualizer/static/assets/{index-CWerbNbe.js → index-Ybr1HJxx.js} +202 -202
- ttnn_visualizer/static/assets/{splitPathsBySizeLoader-DoKJAUb8.js → splitPathsBySizeLoader-CauQGZHk.js} +1 -1
- ttnn_visualizer/static/index.html +5 -5
- ttnn_visualizer/tests/test_queries.py +0 -68
- ttnn_visualizer/views.py +115 -9
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/LICENSE +0 -1
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/METADATA +2 -3
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/RECORD +22 -23
- ttnn_visualizer/ssh_client.py +0 -85
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/LICENSE_understanding.txt +0 -0
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/WHEEL +0 -0
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/entry_points.txt +0 -0
- {ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/top_level.txt +0 -0
@@ -1 +1 @@
|
|
1
|
-
import{_ as o,a as _,b as i,p as c,I as u}from"./index-
|
1
|
+
import{_ as o,a as _,b as i,p as c,I as u}from"./index-Ybr1HJxx.js";var p=function(n,s){return o(void 0,void 0,void 0,function(){var a,r;return _(this,function(e){switch(e.label){case 0:return a=c(n),s!==u.STANDARD?[3,2]:[4,i(()=>import("./index-BKzgFDAn.js").then(t=>t.I),[])];case 1:return r=e.sent(),[3,4];case 2:return[4,i(()=>import("./index-BvSuWPlB.js").then(t=>t.I),[])];case 3:r=e.sent(),e.label=4;case 4:return[2,r[a]]}})})};export{p as splitPathsBySizeLoader};
|
@@ -13,17 +13,17 @@
|
|
13
13
|
<link
|
14
14
|
rel="icon"
|
15
15
|
type="image/svg+xml"
|
16
|
-
href="/favicon/favicon.svg"
|
16
|
+
href="/static/favicon/favicon.svg"
|
17
17
|
/>
|
18
18
|
<link
|
19
19
|
rel="icon"
|
20
20
|
type="image/png"
|
21
21
|
sizes="32x32"
|
22
|
-
href="/favicon/favicon-32x32.png"
|
22
|
+
href="/static/favicon/favicon-32x32.png"
|
23
23
|
/>
|
24
24
|
<link
|
25
25
|
rel="manifest"
|
26
|
-
href="/assets/site-BTBrvHC5.webmanifest"
|
26
|
+
href="/static/assets/site-BTBrvHC5.webmanifest"
|
27
27
|
/>
|
28
28
|
<meta
|
29
29
|
name="theme-color"
|
@@ -34,8 +34,8 @@
|
|
34
34
|
/* SERVER_CONFIG */
|
35
35
|
</script>
|
36
36
|
|
37
|
-
<script type="module" crossorigin src="/assets/index-
|
38
|
-
<link rel="stylesheet" crossorigin href="/assets/index-C1rJBrMl.css">
|
37
|
+
<script type="module" crossorigin src="/static/assets/index-Ybr1HJxx.js"></script>
|
38
|
+
<link rel="stylesheet" crossorigin href="/static/assets/index-C1rJBrMl.css">
|
39
39
|
</head>
|
40
40
|
<body>
|
41
41
|
|
@@ -16,7 +16,6 @@ from ttnn_visualizer.models import (
|
|
16
16
|
)
|
17
17
|
from ttnn_visualizer.queries import DatabaseQueries
|
18
18
|
from ttnn_visualizer.queries import LocalQueryRunner
|
19
|
-
from ttnn_visualizer.queries import RemoteQueryRunner
|
20
19
|
|
21
20
|
|
22
21
|
class TestQueryTable(unittest.TestCase):
|
@@ -222,14 +221,6 @@ class TestDatabaseQueries(unittest.TestCase):
|
|
222
221
|
str(context.exception),
|
223
222
|
)
|
224
223
|
|
225
|
-
@patch("ttnn_visualizer.queries.get_client")
|
226
|
-
def test_init_with_valid_remote_instance(self, _mock_client):
|
227
|
-
mock_instance = Mock()
|
228
|
-
mock_instance.remote_connection = Mock(useRemoteQuerying=True)
|
229
|
-
mock_instance.remote_connection.sqliteBinaryPath = "/usr/bin/sqlite3"
|
230
|
-
mock_instance.remote_profiler_folder = Mock(remotePath="/remote/path")
|
231
|
-
db_queries = DatabaseQueries(instance=mock_instance)
|
232
|
-
self.assertIsInstance(db_queries.query_runner, RemoteQueryRunner)
|
233
224
|
|
234
225
|
def test_init_with_valid_local_instance(self):
|
235
226
|
with tempfile.NamedTemporaryFile(suffix=".sqlite") as temp_db_file:
|
@@ -381,64 +372,5 @@ class TestDatabaseQueries(unittest.TestCase):
|
|
381
372
|
self.assertEqual(result.operation_id, 2)
|
382
373
|
|
383
374
|
|
384
|
-
class TestRemoteQueryRunner(unittest.TestCase):
|
385
|
-
|
386
|
-
def setUp(self):
|
387
|
-
self.mock_instance = Mock()
|
388
|
-
self.mock_instance.remote_connection.sqliteBinaryPath = "/usr/bin/sqlite3"
|
389
|
-
self.mock_instance.remote_connection.host = "mockhost"
|
390
|
-
self.mock_instance.remote_connection.user = "mockuser"
|
391
|
-
self.mock_instance.remote_profiler_folder.remotePath = "/remote/db"
|
392
|
-
|
393
|
-
@patch("ttnn_visualizer.queries.get_client")
|
394
|
-
def test_init_with_mock_get_client(self, mock_get_client):
|
395
|
-
# Mock the SSHClient returned by get_client
|
396
|
-
mock_ssh_client = Mock()
|
397
|
-
mock_get_client.return_value = mock_ssh_client
|
398
|
-
|
399
|
-
runner = RemoteQueryRunner(instance=self.mock_instance)
|
400
|
-
self.assertEqual(runner.ssh_client, mock_ssh_client)
|
401
|
-
mock_get_client.assert_called_once_with(
|
402
|
-
remote_connection=self.mock_instance.remote_connection
|
403
|
-
)
|
404
|
-
|
405
|
-
@patch("ttnn_visualizer.queries.get_client")
|
406
|
-
def test_execute_query(self, mock_get_client):
|
407
|
-
# Mock the SSH client
|
408
|
-
mock_ssh_client = Mock()
|
409
|
-
mock_get_client.return_value = mock_ssh_client
|
410
|
-
|
411
|
-
mock_stdout = Mock()
|
412
|
-
mock_stdout.read.return_value = b'[{"col1": "value1", "col2": "value2"}]'
|
413
|
-
mock_stderr = Mock()
|
414
|
-
mock_stderr.read.return_value = b""
|
415
|
-
mock_ssh_client.exec_command.return_value = (None, mock_stdout, mock_stderr)
|
416
|
-
|
417
|
-
runner = RemoteQueryRunner(instance=self.mock_instance)
|
418
|
-
|
419
|
-
query = "SELECT * FROM table WHERE id = ?"
|
420
|
-
params = [1]
|
421
|
-
results = runner.execute_query(query, params)
|
422
|
-
|
423
|
-
# Validate results
|
424
|
-
self.assertEqual(results, [("value1", "value2")])
|
425
|
-
mock_get_client.assert_called_once()
|
426
|
-
mock_ssh_client.exec_command.assert_called_once()
|
427
|
-
|
428
|
-
@patch("ttnn_visualizer.queries.get_client")
|
429
|
-
def test_close(self, mock_get_client):
|
430
|
-
# Mock the SSH client
|
431
|
-
mock_ssh_client = Mock()
|
432
|
-
mock_get_client.return_value = mock_ssh_client
|
433
|
-
|
434
|
-
runner = RemoteQueryRunner(instance=self.mock_instance)
|
435
|
-
|
436
|
-
runner.close()
|
437
|
-
mock_ssh_client.close.assert_called_once()
|
438
|
-
|
439
|
-
def tearDown(self):
|
440
|
-
pass
|
441
|
-
|
442
|
-
|
443
375
|
if __name__ == "__main__":
|
444
376
|
unittest.main()
|
ttnn_visualizer/views.py
CHANGED
@@ -6,13 +6,13 @@ import dataclasses
|
|
6
6
|
import json
|
7
7
|
import logging
|
8
8
|
import re
|
9
|
+
import shutil
|
9
10
|
import time
|
10
11
|
from http import HTTPStatus
|
11
12
|
from pathlib import Path
|
12
13
|
from typing import List
|
13
|
-
import shutil
|
14
|
-
from wsgiref.validate import bad_header_value_re
|
15
14
|
|
15
|
+
import yaml
|
16
16
|
import zstd
|
17
17
|
from flask import (
|
18
18
|
Blueprint,
|
@@ -23,7 +23,8 @@ from flask import (
|
|
23
23
|
request,
|
24
24
|
)
|
25
25
|
|
26
|
-
from ttnn_visualizer.csv_queries import DeviceLogProfilerQueries, OpsPerformanceQueries, OpsPerformanceReportQueries
|
26
|
+
from ttnn_visualizer.csv_queries import DeviceLogProfilerQueries, OpsPerformanceQueries, OpsPerformanceReportQueries, \
|
27
|
+
NPEQueries
|
27
28
|
from ttnn_visualizer.decorators import with_instance, local_only
|
28
29
|
from ttnn_visualizer.enums import ConnectionTestStates
|
29
30
|
from ttnn_visualizer.exceptions import DataFormatError
|
@@ -34,6 +35,9 @@ from ttnn_visualizer.file_uploads import (
|
|
34
35
|
save_uploaded_files,
|
35
36
|
validate_files,
|
36
37
|
)
|
38
|
+
from ttnn_visualizer.instances import (
|
39
|
+
get_instances, update_instance,
|
40
|
+
)
|
37
41
|
from ttnn_visualizer.models import (
|
38
42
|
RemoteReportFolder,
|
39
43
|
RemoteConnection,
|
@@ -51,9 +55,6 @@ from ttnn_visualizer.serializers import (
|
|
51
55
|
serialize_operations_buffers,
|
52
56
|
serialize_devices, serialize_buffer,
|
53
57
|
)
|
54
|
-
from ttnn_visualizer.instances import (
|
55
|
-
get_instances, update_instance,
|
56
|
-
)
|
57
58
|
from ttnn_visualizer.sftp_operations import (
|
58
59
|
sync_remote_profiler_folders,
|
59
60
|
read_remote_file,
|
@@ -64,14 +65,91 @@ from ttnn_visualizer.sftp_operations import (
|
|
64
65
|
sync_remote_performance_folders,
|
65
66
|
get_cluster_desc,
|
66
67
|
)
|
67
|
-
from ttnn_visualizer.
|
68
|
+
from ttnn_visualizer.exceptions import SSHException, AuthenticationException, NoValidConnectionsError
|
69
|
+
import subprocess
|
68
70
|
from ttnn_visualizer.utils import (
|
69
71
|
get_cluster_descriptor_path,
|
70
72
|
read_last_synced_file,
|
71
73
|
timer,
|
72
74
|
)
|
73
75
|
|
74
|
-
|
76
|
+
|
77
|
+
def handle_ssh_subprocess_error(e: subprocess.CalledProcessError, remote_connection):
|
78
|
+
"""
|
79
|
+
Convert subprocess SSH errors to appropriate SSH exceptions.
|
80
|
+
|
81
|
+
:param e: The subprocess.CalledProcessError
|
82
|
+
:param remote_connection: The RemoteConnection object for context
|
83
|
+
:raises: SSHException, AuthenticationException, or NoValidConnectionsError
|
84
|
+
"""
|
85
|
+
stderr = e.stderr.lower() if e.stderr else ""
|
86
|
+
|
87
|
+
# Check for authentication failures
|
88
|
+
if any(auth_err in stderr for auth_err in [
|
89
|
+
"permission denied",
|
90
|
+
"authentication failed",
|
91
|
+
"publickey",
|
92
|
+
"password",
|
93
|
+
"host key verification failed"
|
94
|
+
]):
|
95
|
+
raise AuthenticationException(f"SSH authentication failed: {e.stderr}")
|
96
|
+
|
97
|
+
# Check for connection failures
|
98
|
+
elif any(conn_err in stderr for conn_err in [
|
99
|
+
"connection refused",
|
100
|
+
"network is unreachable",
|
101
|
+
"no route to host",
|
102
|
+
"name or service not known",
|
103
|
+
"connection timed out"
|
104
|
+
]):
|
105
|
+
raise NoValidConnectionsError(f"SSH connection failed: {e.stderr}")
|
106
|
+
|
107
|
+
# Check for general SSH protocol errors
|
108
|
+
elif "ssh:" in stderr or "protocol" in stderr:
|
109
|
+
raise SSHException(f"SSH protocol error: {e.stderr}")
|
110
|
+
|
111
|
+
# Default to generic SSH exception
|
112
|
+
else:
|
113
|
+
raise SSHException(f"SSH command failed: {e.stderr}")
|
114
|
+
|
115
|
+
|
116
|
+
def test_ssh_connection(connection) -> bool:
|
117
|
+
"""Test SSH connection by running a simple command."""
|
118
|
+
ssh_cmd = ["ssh"]
|
119
|
+
|
120
|
+
# Handle non-standard SSH port
|
121
|
+
if connection.port != 22:
|
122
|
+
ssh_cmd.extend(["-p", str(connection.port)])
|
123
|
+
|
124
|
+
ssh_cmd.extend([
|
125
|
+
f"{connection.username}@{connection.host}",
|
126
|
+
"echo 'SSH connection test'"
|
127
|
+
])
|
128
|
+
|
129
|
+
try:
|
130
|
+
result = subprocess.run(
|
131
|
+
ssh_cmd,
|
132
|
+
capture_output=True,
|
133
|
+
text=True,
|
134
|
+
check=True,
|
135
|
+
timeout=10
|
136
|
+
)
|
137
|
+
return True
|
138
|
+
except subprocess.CalledProcessError as e:
|
139
|
+
if e.returncode == 255: # SSH protocol errors
|
140
|
+
handle_ssh_subprocess_error(e, connection)
|
141
|
+
else:
|
142
|
+
raise RemoteConnectionException(
|
143
|
+
message=f"SSH connection test failed: {e.stderr}",
|
144
|
+
status=ConnectionTestStates.FAILED
|
145
|
+
)
|
146
|
+
return False
|
147
|
+
except subprocess.TimeoutExpired:
|
148
|
+
raise RemoteConnectionException(
|
149
|
+
message="SSH connection test timed out",
|
150
|
+
status=ConnectionTestStates.FAILED
|
151
|
+
)
|
152
|
+
return False
|
75
153
|
|
76
154
|
logger = logging.getLogger(__name__)
|
77
155
|
|
@@ -636,6 +714,34 @@ def get_performance_data_raw(instance: Instance):
|
|
636
714
|
headers={"Content-Disposition": "attachment; filename=profile_log_device.csv"},
|
637
715
|
)
|
638
716
|
|
717
|
+
@api.route("/performance/npe/manifest", methods=["GET"])
|
718
|
+
@with_instance
|
719
|
+
def get_npe_manifest(instance: Instance):
|
720
|
+
if not instance.performance_path:
|
721
|
+
return Response(status=HTTPStatus.NOT_FOUND)
|
722
|
+
try:
|
723
|
+
content = NPEQueries.get_npe_manifest(instance)
|
724
|
+
except FileNotFoundError:
|
725
|
+
return jsonify([])
|
726
|
+
|
727
|
+
return jsonify(content)
|
728
|
+
|
729
|
+
|
730
|
+
@api.route("/performance/npe/timeline", methods=["GET"])
|
731
|
+
@with_instance
|
732
|
+
def get_npe_timeline(instance: Instance):
|
733
|
+
if not instance.performance_path:
|
734
|
+
return Response(status=HTTPStatus.NOT_FOUND)
|
735
|
+
|
736
|
+
filename = request.args.get("filename", default=None)
|
737
|
+
|
738
|
+
try:
|
739
|
+
content = NPEQueries.get_npe_timeline(instance, filename=filename)
|
740
|
+
except FileNotFoundError:
|
741
|
+
return jsonify({})
|
742
|
+
|
743
|
+
return jsonify(content)
|
744
|
+
|
639
745
|
|
640
746
|
@api.route("/performance/device-log/zone/<zone>", methods=["GET"])
|
641
747
|
@with_instance
|
@@ -901,7 +1007,7 @@ def test_remote_folder():
|
|
901
1007
|
|
902
1008
|
# Test SSH Connection
|
903
1009
|
try:
|
904
|
-
|
1010
|
+
test_ssh_connection(connection)
|
905
1011
|
add_status(ConnectionTestStates.OK.value, "SSH connection established")
|
906
1012
|
except RemoteConnectionException as e:
|
907
1013
|
add_status(ConnectionTestStates.FAILED.value, e.message)
|
@@ -109,7 +109,6 @@ The following separate and independent dependencies are utilized by this project
|
|
109
109
|
- Flask – BSD‑3‑Clause – https://github.com/pallets/flask/blob/main/LICENSE.txt
|
110
110
|
- gunicorn – MIT – https://github.com/benoitc/gunicorn/blob/master/LICENSE
|
111
111
|
- uvicorn – BSD‑3‑Clause – https://github.com/encode/uvicorn/blob/master/LICENSE.md
|
112
|
-
- paramiko~=3.4.0 – LGPL‑2.1+ – https://github.com/paramiko/paramiko/blob/main/LICENSE
|
113
112
|
- flask_cors – MIT – https://github.com/corydolphin/flask-cors/blob/main/LICENSE
|
114
113
|
- pydantic – MIT – https://github.com/pydantic/pydantic-settings/blob/main/LICENSE
|
115
114
|
- setuptools – MIT – https://github.com/pypa/setuptools/blob/main/LICENSE
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ttnn_visualizer
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.42.0
|
4
4
|
Summary: TT-NN Visualizer
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -16,7 +16,6 @@ Requires-Dist: Flask-SocketIO==5.4.1
|
|
16
16
|
Requires-Dist: Flask-SQLAlchemy==3.1.1
|
17
17
|
Requires-Dist: pandas==2.2.3
|
18
18
|
Requires-Dist: gunicorn~=22.0.0
|
19
|
-
Requires-Dist: paramiko~=3.4.0
|
20
19
|
Requires-Dist: pydantic==2.7.3
|
21
20
|
Requires-Dist: pydantic-core==2.18.4
|
22
21
|
Requires-Dist: setuptools==65.5.0
|
@@ -24,7 +23,7 @@ Requires-Dist: gevent===24.10.2
|
|
24
23
|
Requires-Dist: python-dotenv==1.0.1
|
25
24
|
Requires-Dist: sqlalchemy==2.0.34
|
26
25
|
Requires-Dist: PyYAML==6.0.2
|
27
|
-
Requires-Dist: tt-perf-report==1.0.
|
26
|
+
Requires-Dist: tt-perf-report==1.0.7
|
28
27
|
Requires-Dist: zstd==1.5.7.0
|
29
28
|
|
30
29
|
|
@@ -1,46 +1,45 @@
|
|
1
1
|
ttnn_visualizer/__init__.py,sha256=tVr9rTN1gXorz5XQQYmcRkzeEYjDGAKez1gP0oOIYeY,94
|
2
|
-
ttnn_visualizer/app.py,sha256=
|
3
|
-
ttnn_visualizer/csv_queries.py,sha256=
|
4
|
-
ttnn_visualizer/decorators.py,sha256=
|
2
|
+
ttnn_visualizer/app.py,sha256=QCgd3nyc_I6iwJEAXGmNCvIXvR6oLSGKmLyV_7ECsH8,7222
|
3
|
+
ttnn_visualizer/csv_queries.py,sha256=WzY1D_2fzrRzgdLnXf5w_aBwsW695Mkq5h2GXGeshyM,25676
|
4
|
+
ttnn_visualizer/decorators.py,sha256=kveD2h6cgXD-rt03uAYWmZ9RKYphgvoGk53g2Pgn_RM,4799
|
5
5
|
ttnn_visualizer/enums.py,sha256=SEIqp1tlc_zw2vQ8nHH9YTaV0m3Cb8fjn_goqz5wurE,203
|
6
|
-
ttnn_visualizer/exceptions.py,sha256=
|
6
|
+
ttnn_visualizer/exceptions.py,sha256=wzD_RuW1L6E2WdfM1pf34e25gisIe9jIMatf3HgyhIA,1375
|
7
7
|
ttnn_visualizer/extensions.py,sha256=AW2aujcvayePfrwovVcsXIUkCFe_k2T4Vk3OblZd4Bk,380
|
8
8
|
ttnn_visualizer/file_uploads.py,sha256=aXolaGeisY3H89y_GxfciPvkSU1XmcvWqpf8vDqKrgM,5011
|
9
9
|
ttnn_visualizer/instances.py,sha256=99L80yT0BXyhEkBbGFC_tNAg8LlGWUqWQrhkK-4-Yxc,11261
|
10
10
|
ttnn_visualizer/models.py,sha256=ut9V9fTzbbjk_WNKKP8ILrVXYnIv7qQaDvNOEEX3BT8,7778
|
11
|
-
ttnn_visualizer/queries.py,sha256=
|
12
|
-
ttnn_visualizer/remote_sqlite_setup.py,sha256=
|
13
|
-
ttnn_visualizer/requirements.txt,sha256=
|
11
|
+
ttnn_visualizer/queries.py,sha256=MB57Ci3gyXn9jdXdR6KaMBHoHYt5jgdk3wP7jSDGWFA,9891
|
12
|
+
ttnn_visualizer/remote_sqlite_setup.py,sha256=0JfSQLA_ST6gh7lyHhxUdsEsmw8moremC37myES6Al8,5892
|
13
|
+
ttnn_visualizer/requirements.txt,sha256=RuHRxxkHKSAAMF7JbvifDMOOFTfQH19AW3qJFL3I69M,339
|
14
14
|
ttnn_visualizer/serializers.py,sha256=7kjtxp3NEpTlBKUNsxdtUcOM23pAyIt5MR-XTl85bVw,8028
|
15
15
|
ttnn_visualizer/settings.py,sha256=r7UdqFuXEVg0qw1F2_zRFM_687PctqpgoUEKjvTVhwU,4578
|
16
|
-
ttnn_visualizer/sftp_operations.py,sha256=
|
16
|
+
ttnn_visualizer/sftp_operations.py,sha256=p06_dYHoM-qbAZuUUR9CN7fWy4U_QpIaXBxPsjxJfgI,32074
|
17
17
|
ttnn_visualizer/sockets.py,sha256=GAvReqKaT0YQyeb0kf7ndtL1odLldHCpbbKkr0INXRM,3624
|
18
|
-
ttnn_visualizer/ssh_client.py,sha256=dTkxzAFCGKyiZL1_LHx23Gn4y0oW4yKfGKjTxuqcx8I,2679
|
19
18
|
ttnn_visualizer/utils.py,sha256=9Ier5XBD4vHzvtIxfbIRnsP1Is03J2usUmhfB5gSqqc,6186
|
20
|
-
ttnn_visualizer/views.py,sha256=
|
19
|
+
ttnn_visualizer/views.py,sha256=WywffIzF5ahslw6qBDHyfL5kIzDKxbUf_yQXxeMUVgA,44784
|
21
20
|
ttnn_visualizer/bin/docker-entrypoint-web,sha256=uuv6aubpMCfOcuvDBxwBDITE8PN39teuwyJ2zA5KWuw,413
|
22
21
|
ttnn_visualizer/bin/pip3-install,sha256=nbSRT4GfJQIQ9KTNO3j-6b5WM4lrx9XA4GBlAURRMws,502
|
23
|
-
ttnn_visualizer/static/index.html,sha256=
|
24
|
-
ttnn_visualizer/static/assets/allPaths-
|
25
|
-
ttnn_visualizer/static/assets/allPathsLoader-
|
22
|
+
ttnn_visualizer/static/index.html,sha256=gM7cQnEuPT29ZMKqJcEqjW9POf4AigZftNS8uw68ViY,1135
|
23
|
+
ttnn_visualizer/static/assets/allPaths-wwXsGKJ2.js,sha256=CxiByiF9vD2BvhrONDu-MQVoLKj-KhOcYm1XBZdSXAw,309
|
24
|
+
ttnn_visualizer/static/assets/allPathsLoader-BK9jqlVe.js,sha256=Bc4W_X5zso_Yf-8g1aZBA9wg0NfKXGjD64lDJWqAyzE,550
|
26
25
|
ttnn_visualizer/static/assets/index-BKzgFDAn.js,sha256=Pu504I3PJMoop2k0KQxrd1qKuS3zR5KtvTTdz9IhfeY,283793
|
27
26
|
ttnn_visualizer/static/assets/index-BvSuWPlB.js,sha256=43E6se9tLaZkX7kCG4waDG_vyL4yED6SEaDKLt3Nw_s,292382
|
28
27
|
ttnn_visualizer/static/assets/index-C1rJBrMl.css,sha256=f1PX54ZLwJIs0PqePOu-B3YP3joUxhrkkZ1Butqil9M,623666
|
29
|
-
ttnn_visualizer/static/assets/index-
|
28
|
+
ttnn_visualizer/static/assets/index-Ybr1HJxx.js,sha256=fSByVEefEo8y-kGOi8sS1n6_thxMXcapSWptHAd3z3Y,7785792
|
30
29
|
ttnn_visualizer/static/assets/site-BTBrvHC5.webmanifest,sha256=Uy_XmnGuYFVf-OZuma2NvgEPdrCrevb3HZvaxSIHoA0,456
|
31
|
-
ttnn_visualizer/static/assets/splitPathsBySizeLoader-
|
30
|
+
ttnn_visualizer/static/assets/splitPathsBySizeLoader-CauQGZHk.js,sha256=431X0PrDog4lr5A_hi5ObsXMZe6KpjgIDgTc65IwZWM,472
|
32
31
|
ttnn_visualizer/static/favicon/android-chrome-192x192.png,sha256=BZWA09Zxaa3fXbaeS6nhWo2e-DUSjm9ElzNQ_xTB5XU,6220
|
33
32
|
ttnn_visualizer/static/favicon/android-chrome-512x512.png,sha256=HBiJSZyguB3o8fMJuqIGcpeBy_9JOdImme3wD02UYCw,62626
|
34
33
|
ttnn_visualizer/static/favicon/favicon-32x32.png,sha256=Zw201qUsczQv1UvoQvJf5smQ2ss10xaTeWxmQNYCGtY,480
|
35
34
|
ttnn_visualizer/static/favicon/favicon.svg,sha256=wDPY3VrekJ_DE1TnJ2vUy602K3S4Xe9TgrdZ7jXK9c8,633
|
36
35
|
ttnn_visualizer/static/sample-data/cluster-desc.yaml,sha256=LMxOmsRUXtVVU5ogzYkXUozB3dg2IzqIRJQpV_O5qMU,29618
|
37
36
|
ttnn_visualizer/tests/__init__.py,sha256=tVr9rTN1gXorz5XQQYmcRkzeEYjDGAKez1gP0oOIYeY,94
|
38
|
-
ttnn_visualizer/tests/test_queries.py,sha256=
|
37
|
+
ttnn_visualizer/tests/test_queries.py,sha256=QLfV_MWnM68WOWKKa1TPzn5aKQJbysQrGPIJ5aoxl7k,13882
|
39
38
|
ttnn_visualizer/tests/test_serializers.py,sha256=XyS5f8JK234CtizslrQ49hhxaz7RmhkEbVTaxOvdSd4,18490
|
40
|
-
ttnn_visualizer-0.
|
41
|
-
ttnn_visualizer-0.
|
42
|
-
ttnn_visualizer-0.
|
43
|
-
ttnn_visualizer-0.
|
44
|
-
ttnn_visualizer-0.
|
45
|
-
ttnn_visualizer-0.
|
46
|
-
ttnn_visualizer-0.
|
39
|
+
ttnn_visualizer-0.42.0.dist-info/LICENSE,sha256=-Y7CZK1-MxZZ7l0Rb414S0SZ9tdCby-bMGl_LmFFicM,14806
|
40
|
+
ttnn_visualizer-0.42.0.dist-info/LICENSE_understanding.txt,sha256=pymi-yb_RvYM9p2ZA4iSNsImcvhDBBxlGuJCY9dTq7M,233
|
41
|
+
ttnn_visualizer-0.42.0.dist-info/METADATA,sha256=PpiZyDS_Vxcen6rGwhwgx1YFrfmCb35x7Jn_mxijYgU,7362
|
42
|
+
ttnn_visualizer-0.42.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
43
|
+
ttnn_visualizer-0.42.0.dist-info/entry_points.txt,sha256=QpuUpkmQ_mEHJTMqOBdU0MH2Z4WF_9iFsGACeyyAO1E,61
|
44
|
+
ttnn_visualizer-0.42.0.dist-info/top_level.txt,sha256=M1EGkvDOuIfbhDbcUdz2-TSdmCtDoQ2Uyag9k5JLDSY,16
|
45
|
+
ttnn_visualizer-0.42.0.dist-info/RECORD,,
|
ttnn_visualizer/ssh_client.py
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
# SPDX-License-Identifier: Apache-2.0
|
2
|
-
#
|
3
|
-
# SPDX-FileCopyrightText: © 2025 Tenstorrent AI ULC
|
4
|
-
|
5
|
-
import paramiko
|
6
|
-
import os
|
7
|
-
from pathlib import Path
|
8
|
-
from paramiko.agent import Agent
|
9
|
-
from paramiko.ssh_exception import SSHException
|
10
|
-
|
11
|
-
from ttnn_visualizer.decorators import remote_exception_handler
|
12
|
-
from ttnn_visualizer.models import RemoteConnection
|
13
|
-
import logging
|
14
|
-
|
15
|
-
logger = logging.getLogger(__name__)
|
16
|
-
|
17
|
-
|
18
|
-
def initialize_ssh_client():
|
19
|
-
ssh = paramiko.SSHClient()
|
20
|
-
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
21
|
-
ssh.load_system_host_keys()
|
22
|
-
return ssh
|
23
|
-
|
24
|
-
|
25
|
-
def get_connection_args(remote_connection: RemoteConnection) -> dict:
|
26
|
-
use_agent = os.getenv("USE_SSH_AGENT", "true").lower() == "true"
|
27
|
-
ssh_config_path = Path(os.getenv("SSH_CONFIG_PATH", "~/.ssh/config")).expanduser()
|
28
|
-
|
29
|
-
if use_agent:
|
30
|
-
agent = Agent()
|
31
|
-
keys = agent.get_keys()
|
32
|
-
if not keys:
|
33
|
-
logger.error("No keys found in agent")
|
34
|
-
raise SSHException("No keys found")
|
35
|
-
return {"look_for_keys": True}
|
36
|
-
|
37
|
-
config = paramiko.SSHConfig.from_path(ssh_config_path).lookup(
|
38
|
-
remote_connection.host
|
39
|
-
)
|
40
|
-
if not config:
|
41
|
-
raise SSHException(f"Host not found in SSH config {remote_connection.host}")
|
42
|
-
|
43
|
-
return {"key_filename": config["identityfile"].pop(), "look_for_keys": False} # type: ignore
|
44
|
-
|
45
|
-
|
46
|
-
@remote_exception_handler
|
47
|
-
def get_client(remote_connection: RemoteConnection) -> paramiko.SSHClient:
|
48
|
-
ssh = initialize_ssh_client()
|
49
|
-
connection_args = get_connection_args(remote_connection)
|
50
|
-
|
51
|
-
ssh.connect(
|
52
|
-
remote_connection.host,
|
53
|
-
port=remote_connection.port,
|
54
|
-
username=remote_connection.username,
|
55
|
-
**connection_args,
|
56
|
-
)
|
57
|
-
return ssh
|
58
|
-
|
59
|
-
|
60
|
-
def check_permissions(client, directory):
|
61
|
-
"""Check if write and delete permissions are available in the remote directory."""
|
62
|
-
test_file = Path(directory) / "test_permission_file.txt"
|
63
|
-
touch_command = f"touch {test_file}"
|
64
|
-
remove_command = f"rm {test_file}"
|
65
|
-
|
66
|
-
stdin, stdout, stderr = client.exec_command(touch_command)
|
67
|
-
error = stderr.read().decode().strip()
|
68
|
-
if error:
|
69
|
-
raise Exception(f"No permission to create files in {directory}: {error}")
|
70
|
-
|
71
|
-
stdin, stdout, stderr = client.exec_command(remove_command)
|
72
|
-
error = stderr.read().decode().strip()
|
73
|
-
if error:
|
74
|
-
raise Exception(f"No permission to delete files in {directory}: {error}")
|
75
|
-
|
76
|
-
return True
|
77
|
-
|
78
|
-
|
79
|
-
def check_gzip_exists(client):
|
80
|
-
"""Check if gzip and tar exist on the remote server."""
|
81
|
-
stdin, stdout, stderr = client.exec_command("which gzip && which tar")
|
82
|
-
result = stdout.read().decode().strip()
|
83
|
-
if not result:
|
84
|
-
return False
|
85
|
-
return True
|
{ttnn_visualizer-0.40.3.dist-info → ttnn_visualizer-0.42.0.dist-info}/LICENSE_understanding.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|