Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,69 +4,83 @@ import base64
|
|
4 |
import streamlit.components.v1 as components
|
5 |
from transformers import pipeline
|
6 |
|
7 |
-
|
|
|
|
|
8 |
@st.cache_resource
|
9 |
def load_model():
|
10 |
-
|
11 |
-
return summarizer
|
12 |
|
13 |
summarizer = load_model()
|
14 |
|
15 |
-
st.
|
16 |
-
st.title("π AR/VR Enhanced Code Visualizer")
|
17 |
-
|
18 |
-
# --- Upload Python file ---
|
19 |
-
uploaded_file = st.file_uploader("π Upload your Python file", type=["py"])
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
code =
|
24 |
-
st.subheader("π Uploaded Code")
|
25 |
-
st.code(code, language='python')
|
26 |
|
27 |
# Parse AST
|
28 |
tree = ast.parse(code)
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
<!DOCTYPE html>
|
66 |
<html>
|
67 |
<head>
|
68 |
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
|
69 |
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
70 |
</head>
|
71 |
<body>
|
72 |
<a-scene background="color: #ECECEC">
|
@@ -74,22 +88,21 @@ if uploaded_file is not None:
|
|
74 |
<a-camera wasd-controls-enabled="true" look-controls-enabled="true"></a-camera>
|
75 |
</a-entity>
|
76 |
<a-light type="ambient" color="#FFF"></a-light>
|
77 |
-
<a-plane rotation="-90 0 0" width="
|
78 |
-
{''.join(
|
|
|
79 |
</a-scene>
|
80 |
</body>
|
81 |
</html>
|
82 |
-
|
83 |
return html
|
84 |
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
data_url = f"data:text/html;base64,{encoded_html}"
|
89 |
|
90 |
-
st.subheader("π
|
91 |
-
|
92 |
-
components.iframe(data_url, height=500, scrolling=True)
|
93 |
|
94 |
else:
|
95 |
-
st.info("
|
|
|
4 |
import streamlit.components.v1 as components
|
5 |
from transformers import pipeline
|
6 |
|
7 |
+
st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide")
|
8 |
+
st.title("π AR/VR Code Visualizer with Call Relationships")
|
9 |
+
|
10 |
@st.cache_resource
|
11 |
def load_model():
|
12 |
+
return pipeline("summarization", model="philschmid/bart-large-cnn-samsum")
|
|
|
13 |
|
14 |
summarizer = load_model()
|
15 |
|
16 |
+
uploaded_file = st.file_uploader("π Upload a Python file", type=["py"])
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
if uploaded_file:
|
19 |
+
code = uploaded_file.read().decode("utf-8")
|
20 |
+
st.code(code, language="python")
|
|
|
|
|
21 |
|
22 |
# Parse AST
|
23 |
tree = ast.parse(code)
|
24 |
+
|
25 |
+
# Find functions and their calls
|
26 |
+
class FunctionCallVisitor(ast.NodeVisitor):
|
27 |
+
def __init__(self):
|
28 |
+
self.calls = {} # {caller: [callee1, callee2]}
|
29 |
+
|
30 |
+
def visit_FunctionDef(self, node):
|
31 |
+
caller = node.name
|
32 |
+
self.calls[caller] = []
|
33 |
+
for child in ast.walk(node):
|
34 |
+
if isinstance(child, ast.Call) and isinstance(child.func, ast.Name):
|
35 |
+
self.calls[caller].append(child.func.id)
|
36 |
+
self.generic_visit(node)
|
37 |
+
|
38 |
+
visitor = FunctionCallVisitor()
|
39 |
+
visitor.visit(tree)
|
40 |
+
call_graph = visitor.calls
|
41 |
+
all_functions = list(call_graph.keys())
|
42 |
+
|
43 |
+
# Show extracted relationships
|
44 |
+
st.subheader("π Call Relationships")
|
45 |
+
for fn, callees in call_graph.items():
|
46 |
+
st.write(f"πΉ `{fn}` calls: {', '.join(callees) if callees else 'None'}")
|
47 |
+
|
48 |
+
# Summarize using Hugging Face
|
49 |
+
prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}"
|
50 |
+
summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False)
|
51 |
+
st.success(summary[0]['summary_text'])
|
52 |
+
|
53 |
+
# Generate A-Frame HTML
|
54 |
+
def generate_aframe(call_graph):
|
55 |
+
spacing = 3
|
56 |
+
boxes = []
|
57 |
+
lines = []
|
58 |
+
positions = {}
|
59 |
+
|
60 |
+
# Assign fixed positions on x-axis
|
61 |
+
for i, fn in enumerate(call_graph):
|
62 |
+
x = i * spacing
|
63 |
+
positions[fn] = (x, 1, -3)
|
64 |
+
boxes.append(f'''
|
65 |
+
<a-box position="{x} 1 -3" depth="0.5" height="0.5" width="2" color="#FFC65D"></a-box>
|
66 |
+
<a-text value="{fn}" position="{x} 1.8 -3" align="center" color="#000"></a-text>
|
67 |
+
''')
|
68 |
+
|
69 |
+
# Draw arrows between caller β callee
|
70 |
+
for caller, callees in call_graph.items():
|
71 |
+
for callee in callees:
|
72 |
+
if callee in positions:
|
73 |
+
x1, y1, z1 = positions[caller]
|
74 |
+
x2, y2, z2 = positions[callee]
|
75 |
+
lines.append(f'''
|
76 |
+
<a-entity line="start: {x1} {y1} {z1}; end: {x2} {y2} {z2}; color: red"></a-entity>
|
77 |
+
''')
|
78 |
+
|
79 |
+
html = f'''
|
80 |
<!DOCTYPE html>
|
81 |
<html>
|
82 |
<head>
|
83 |
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
|
|
|
84 |
</head>
|
85 |
<body>
|
86 |
<a-scene background="color: #ECECEC">
|
|
|
88 |
<a-camera wasd-controls-enabled="true" look-controls-enabled="true"></a-camera>
|
89 |
</a-entity>
|
90 |
<a-light type="ambient" color="#FFF"></a-light>
|
91 |
+
<a-plane rotation="-90 0 0" width="40" height="40" color="#7BC8A4"></a-plane>
|
92 |
+
{''.join(boxes)}
|
93 |
+
{''.join(lines)}
|
94 |
</a-scene>
|
95 |
</body>
|
96 |
</html>
|
97 |
+
'''
|
98 |
return html
|
99 |
|
100 |
+
aframe_html = generate_aframe(call_graph)
|
101 |
+
b64 = base64.b64encode(aframe_html.encode()).decode()
|
102 |
+
data_url = f"data:text/html;base64,{b64}"
|
|
|
103 |
|
104 |
+
st.subheader("π 3D Call Relationship Visualization")
|
105 |
+
components.iframe(data_url, height=500)
|
|
|
106 |
|
107 |
else:
|
108 |
+
st.info("Upload a Python file to visualize function call relationships.")
|