ttnn-visualizer 0.24.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/__init__.py +4 -0
- ttnn_visualizer/app.py +193 -0
- ttnn_visualizer/bin/docker-entrypoint-web +16 -0
- ttnn_visualizer/bin/pip3-install +17 -0
- ttnn_visualizer/csv_queries.py +618 -0
- ttnn_visualizer/decorators.py +117 -0
- ttnn_visualizer/enums.py +12 -0
- ttnn_visualizer/exceptions.py +40 -0
- ttnn_visualizer/extensions.py +14 -0
- ttnn_visualizer/file_uploads.py +78 -0
- ttnn_visualizer/models.py +275 -0
- ttnn_visualizer/queries.py +388 -0
- ttnn_visualizer/remote_sqlite_setup.py +91 -0
- ttnn_visualizer/requirements.txt +24 -0
- ttnn_visualizer/serializers.py +249 -0
- ttnn_visualizer/sessions.py +245 -0
- ttnn_visualizer/settings.py +118 -0
- ttnn_visualizer/sftp_operations.py +486 -0
- ttnn_visualizer/sockets.py +118 -0
- ttnn_visualizer/ssh_client.py +85 -0
- ttnn_visualizer/static/assets/allPaths-CKt4gwo3.js +1 -0
- ttnn_visualizer/static/assets/allPathsLoader-Dzw0zTnr.js +2 -0
- ttnn_visualizer/static/assets/index-BXlT2rEV.js +5247 -0
- ttnn_visualizer/static/assets/index-CsS_OkTl.js +1 -0
- ttnn_visualizer/static/assets/index-DTKBo2Os.css +7 -0
- ttnn_visualizer/static/assets/index-DxLGmC6o.js +1 -0
- ttnn_visualizer/static/assets/site-BTBrvHC5.webmanifest +19 -0
- ttnn_visualizer/static/assets/splitPathsBySizeLoader-HHqSPeQM.js +1 -0
- ttnn_visualizer/static/favicon/android-chrome-192x192.png +0 -0
- ttnn_visualizer/static/favicon/android-chrome-512x512.png +0 -0
- ttnn_visualizer/static/favicon/favicon-32x32.png +0 -0
- ttnn_visualizer/static/favicon/favicon.svg +3 -0
- ttnn_visualizer/static/index.html +36 -0
- ttnn_visualizer/static/sample-data/cluster-desc.yaml +763 -0
- ttnn_visualizer/tests/__init__.py +4 -0
- ttnn_visualizer/tests/test_queries.py +444 -0
- ttnn_visualizer/tests/test_serializers.py +582 -0
- ttnn_visualizer/utils.py +185 -0
- ttnn_visualizer/views.py +794 -0
- ttnn_visualizer-0.24.0.dist-info/LICENSE +202 -0
- ttnn_visualizer-0.24.0.dist-info/LICENSE_understanding.txt +3 -0
- ttnn_visualizer-0.24.0.dist-info/METADATA +144 -0
- ttnn_visualizer-0.24.0.dist-info/RECORD +46 -0
- ttnn_visualizer-0.24.0.dist-info/WHEEL +5 -0
- ttnn_visualizer-0.24.0.dist-info/entry_points.txt +2 -0
- ttnn_visualizer-0.24.0.dist-info/top_level.txt +1 -0
ttnn_visualizer/app.py
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC
|
4
|
+
|
5
|
+
import logging
|
6
|
+
import os
|
7
|
+
import subprocess
|
8
|
+
import threading
|
9
|
+
import webbrowser
|
10
|
+
from os import environ
|
11
|
+
from pathlib import Path
|
12
|
+
import sys
|
13
|
+
from typing import cast
|
14
|
+
|
15
|
+
import flask
|
16
|
+
from dotenv import load_dotenv
|
17
|
+
from flask import Flask, jsonify
|
18
|
+
from flask_cors import CORS
|
19
|
+
from werkzeug.debug import DebuggedApplication
|
20
|
+
from werkzeug.middleware.proxy_fix import ProxyFix
|
21
|
+
|
22
|
+
from ttnn_visualizer.exceptions import DatabaseFileNotFoundException
|
23
|
+
from ttnn_visualizer.settings import Config, DefaultConfig
|
24
|
+
|
25
|
+
logger = logging.getLogger(__name__)
|
26
|
+
|
27
|
+
|
28
|
+
def create_app(settings_override=None):
|
29
|
+
from ttnn_visualizer.views import api
|
30
|
+
|
31
|
+
"""
|
32
|
+
Create a Flask application using the app factory pattern.
|
33
|
+
|
34
|
+
:param settings_override: Override settings
|
35
|
+
:return: Flask app
|
36
|
+
"""
|
37
|
+
|
38
|
+
dotenv_path = Path(__file__).parent.parent.joinpath(".env")
|
39
|
+
if dotenv_path.exists():
|
40
|
+
load_dotenv(str(dotenv_path))
|
41
|
+
|
42
|
+
flask_env = environ.get("FLASK_ENV", "development")
|
43
|
+
|
44
|
+
config = cast(DefaultConfig, Config())
|
45
|
+
|
46
|
+
app = Flask(__name__, static_folder=config.STATIC_ASSETS_DIR, static_url_path="/")
|
47
|
+
logging.basicConfig(level=app.config.get("LOG_LEVEL", "INFO"))
|
48
|
+
|
49
|
+
app.config.from_object(config)
|
50
|
+
|
51
|
+
if settings_override:
|
52
|
+
app.config.update(settings_override)
|
53
|
+
|
54
|
+
middleware(app)
|
55
|
+
|
56
|
+
app.register_blueprint(api)
|
57
|
+
|
58
|
+
extensions(app)
|
59
|
+
|
60
|
+
if flask_env == "production":
|
61
|
+
|
62
|
+
@app.route("/", defaults={"path": ""})
|
63
|
+
@app.route("/<path:path>")
|
64
|
+
def catch_all(path):
|
65
|
+
return app.send_static_file("index.html")
|
66
|
+
|
67
|
+
return app
|
68
|
+
|
69
|
+
|
70
|
+
def extensions(app: flask.Flask):
|
71
|
+
from ttnn_visualizer.extensions import flask_static_digest, db, socketio
|
72
|
+
from ttnn_visualizer.sockets import register_handlers
|
73
|
+
|
74
|
+
"""
|
75
|
+
Register 0 or more extensions (mutates the app passed in).
|
76
|
+
|
77
|
+
:param app: Flask application instance
|
78
|
+
:return: None
|
79
|
+
"""
|
80
|
+
|
81
|
+
flask_static_digest.init_app(app)
|
82
|
+
if app.config["USE_WEBSOCKETS"]:
|
83
|
+
socketio.init_app(app)
|
84
|
+
db.init_app(app)
|
85
|
+
|
86
|
+
app.config["SESSION_TYPE"] = "sqlalchemy"
|
87
|
+
app.config["SESSION_SQLALCHEMY"] = db
|
88
|
+
|
89
|
+
if app.config["USE_WEBSOCKETS"]:
|
90
|
+
register_handlers(socketio)
|
91
|
+
|
92
|
+
# Create the tables within the application context
|
93
|
+
with app.app_context():
|
94
|
+
db.create_all()
|
95
|
+
|
96
|
+
# For automatically reflecting table data
|
97
|
+
# with app.app_context():
|
98
|
+
# db.reflect()
|
99
|
+
|
100
|
+
return None
|
101
|
+
|
102
|
+
|
103
|
+
def middleware(app: flask.Flask):
|
104
|
+
"""
|
105
|
+
Register 0 or more middleware (mutates the app passed in).
|
106
|
+
|
107
|
+
:param app: Flask application instance
|
108
|
+
:return: None
|
109
|
+
"""
|
110
|
+
|
111
|
+
@app.errorhandler(DatabaseFileNotFoundException)
|
112
|
+
def handle_database_not_found_error(error):
|
113
|
+
# Return a JSON response with a 404 status code
|
114
|
+
response = jsonify({"error": str(error)})
|
115
|
+
response.status_code = 404
|
116
|
+
return response
|
117
|
+
|
118
|
+
# Only use the middleware if running in pure WSGI (HTTP requests)
|
119
|
+
if not app.config.get("USE_WEBSOCKETS"):
|
120
|
+
# Enable the Flask interactive debugger in the browser for development.
|
121
|
+
if app.debug:
|
122
|
+
app.wsgi_app = DebuggedApplication(app.wsgi_app, evalex=True)
|
123
|
+
|
124
|
+
# Set the real IP address into request.remote_addr when behind a proxy.
|
125
|
+
app.wsgi_app = ProxyFix(app.wsgi_app)
|
126
|
+
|
127
|
+
# CORS configuration
|
128
|
+
origins = ["http://localhost:5173", "http://localhost:8000"]
|
129
|
+
|
130
|
+
CORS(
|
131
|
+
app,
|
132
|
+
origins=origins,
|
133
|
+
)
|
134
|
+
|
135
|
+
return None
|
136
|
+
|
137
|
+
|
138
|
+
def open_browser(host, port, protocol="http"):
|
139
|
+
|
140
|
+
url = f"{protocol}://{host}:{port}"
|
141
|
+
|
142
|
+
print(f"Launching browser with url: {url}")
|
143
|
+
try:
|
144
|
+
if os.name == "posix" and "DISPLAY" in os.environ: # Checks for non-headless
|
145
|
+
subprocess.run(["xdg-open", url], check=True)
|
146
|
+
else:
|
147
|
+
webbrowser.open(url)
|
148
|
+
except webbrowser.Error as e:
|
149
|
+
print(f"Could not open the default browser: {e}")
|
150
|
+
|
151
|
+
|
152
|
+
def main():
|
153
|
+
|
154
|
+
run_command = sys.argv[0].split("/")
|
155
|
+
if run_command[-1] == "ttnn-visualizer":
|
156
|
+
os.environ.setdefault("FLASK_ENV", "production")
|
157
|
+
|
158
|
+
config = cast(DefaultConfig, Config())
|
159
|
+
|
160
|
+
# Check if DEBUG environment variable is set
|
161
|
+
debug_mode = os.environ.get("DEBUG", "false").lower() == "true"
|
162
|
+
if config.PRINT_ENV:
|
163
|
+
print("ENVIRONMENT:")
|
164
|
+
for key, value in config.to_dict().items():
|
165
|
+
print(f"{key}={value}")
|
166
|
+
|
167
|
+
gunicorn_args = [
|
168
|
+
"gunicorn",
|
169
|
+
"-k",
|
170
|
+
config.GUNICORN_WORKER_CLASS,
|
171
|
+
"-w",
|
172
|
+
config.GUNICORN_WORKERS,
|
173
|
+
"-b",
|
174
|
+
config.GUNICORN_BIND,
|
175
|
+
config.GUNICORN_APP_MODULE,
|
176
|
+
]
|
177
|
+
|
178
|
+
if debug_mode:
|
179
|
+
gunicorn_args.insert(1, "--reload")
|
180
|
+
|
181
|
+
if config.LAUNCH_BROWSER_ON_START:
|
182
|
+
flask_env = os.getenv("FLASK_ENV", "development")
|
183
|
+
port = config.PORT if flask_env == "production" else config.DEV_SERVER_PORT
|
184
|
+
host = config.HOST if flask_env == "production" else config.DEV_SERVER_HOST
|
185
|
+
threading.Timer(2, open_browser, [host, port]).start()
|
186
|
+
try:
|
187
|
+
subprocess.run(gunicorn_args)
|
188
|
+
except KeyboardInterrupt:
|
189
|
+
print("\nServer stopped by user (Ctrl+C)")
|
190
|
+
|
191
|
+
|
192
|
+
if __name__ == "__main__":
|
193
|
+
main()
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
4
|
+
#
|
5
|
+
# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC
|
6
|
+
|
7
|
+
set -e
|
8
|
+
|
9
|
+
# Always keep this here as it ensures your latest built assets make their way
|
10
|
+
# into your volume persisted public directory.
|
11
|
+
cp -r /public /app/backend/ttnn_visualizer/static
|
12
|
+
|
13
|
+
echo "Running as user: $(whoami)"
|
14
|
+
echo "Keys present in agent: $(ssh-add -L)"
|
15
|
+
echo "Current env $(env)"
|
16
|
+
exec "$@"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
4
|
+
#
|
5
|
+
# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC
|
6
|
+
|
7
|
+
set -e
|
8
|
+
|
9
|
+
pip3 install --no-warn-script-location --no-cache-dir --user -r requirements.txt
|
10
|
+
|
11
|
+
# If requirements.txt is newer than the lock file or the lock file doesn't exist.
|
12
|
+
if [ requirements.txt -nt requirements-lock.txt ]; then
|
13
|
+
pip3 freeze --user > requirements-lock.txt
|
14
|
+
fi
|
15
|
+
|
16
|
+
pip3 install --no-warn-script-location --no-cache-dir --user \
|
17
|
+
-r requirements.txt -c requirements-lock.txt
|