Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1 |
-
# app.py
|
2 |
from flask import Flask, request, render_template, jsonify, send_file
|
3 |
from parser import parse_python_code
|
4 |
import os
|
5 |
import json
|
6 |
import io
|
|
|
|
|
7 |
|
8 |
app = Flask(__name__)
|
9 |
|
@@ -12,13 +14,59 @@ def reconstruct_code(parts):
|
|
12 |
sorted_parts = sorted(parts, key=lambda p: p['location'][0])
|
13 |
return ''.join(part['source'] for part in sorted_parts)
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
@app.route('/', methods=['GET', 'POST'])
|
16 |
def index():
|
17 |
if request.method == 'POST':
|
18 |
parts = None
|
19 |
filename = 'unnamed.py'
|
20 |
code_input = None
|
|
|
21 |
|
|
|
22 |
if 'file' in request.files and request.files['file'].filename:
|
23 |
file = request.files['file']
|
24 |
if not file.filename.endswith('.py'):
|
@@ -28,13 +76,32 @@ def index():
|
|
28 |
file.save(file_path)
|
29 |
with open(file_path, 'r') as f:
|
30 |
code_input = f.read()
|
31 |
-
parts = parse_python_code(code_input)
|
|
|
|
|
|
|
|
|
32 |
elif 'code' in request.form and request.form['code'].strip():
|
33 |
code_input = request.form['code']
|
34 |
filename = request.form.get('filename', 'unnamed.py') or 'unnamed.py'
|
35 |
if not filename.endswith('.py'):
|
36 |
filename += '.py'
|
37 |
-
parts = parse_python_code(code_input)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
if parts:
|
40 |
indexed_parts = [{'index': i + 1, **part} for i, part in enumerate(parts)]
|
@@ -44,11 +111,15 @@ def index():
|
|
44 |
parts=indexed_parts,
|
45 |
filename=filename,
|
46 |
reconstructed_code=reconstructed_code,
|
47 |
-
code_input=code_input
|
|
|
48 |
)
|
49 |
-
return 'No file or
|
50 |
|
51 |
-
|
|
|
|
|
|
|
52 |
|
53 |
@app.route('/export_json', methods=['POST'])
|
54 |
def export_json():
|
@@ -67,4 +138,4 @@ def export_json():
|
|
67 |
if __name__ == '__main__':
|
68 |
if not os.path.exists('uploads'):
|
69 |
os.makedirs('uploads')
|
70 |
-
app.run(
|
|
|
1 |
+
# app.py
|
2 |
from flask import Flask, request, render_template, jsonify, send_file
|
3 |
from parser import parse_python_code
|
4 |
import os
|
5 |
import json
|
6 |
import io
|
7 |
+
import sqlite3
|
8 |
+
from database import init_db, populate_sample_db
|
9 |
|
10 |
app = Flask(__name__)
|
11 |
|
|
|
14 |
sorted_parts = sorted(parts, key=lambda p: p['location'][0])
|
15 |
return ''.join(part['source'] for part in sorted_parts)
|
16 |
|
17 |
+
def is_subsequence(subseq, seq):
|
18 |
+
"""Check if subseq is a subsequence of seq."""
|
19 |
+
it = iter(seq)
|
20 |
+
return all(item in it for item in subseq)
|
21 |
+
|
22 |
+
def query_programs(operations):
|
23 |
+
"""Query the database for programs matching the operations sequence."""
|
24 |
+
conn = sqlite3.connect('python_programs.db')
|
25 |
+
c = conn.cursor()
|
26 |
+
c.execute("SELECT id, code, sequence, vectors FROM programs")
|
27 |
+
results = []
|
28 |
+
for row in c.fetchall():
|
29 |
+
program_id, code, sequence_str, vectors_str = row
|
30 |
+
sequence = sequence_str.split(',')
|
31 |
+
vectors = eval(vectors_str) # Convert string back to list (use JSON in production)
|
32 |
+
if is_subsequence(operations, sequence):
|
33 |
+
# Compute similarity (simple average vector for now)
|
34 |
+
program_vector = sum(vectors, []) / len(vectors) if vectors else [0, 0, 0, 0, 0, 0]
|
35 |
+
query_vector = sum([create_vector(op, 0, (1, 1), 100, []) for op in operations], []) / len(operations) if operations else [0, 0, 0, 0, 0, 0]
|
36 |
+
similarity = cosine_similarity([program_vector], [query_vector])[0][0] if program_vector and query_vector else 0
|
37 |
+
results.append({'id': program_id, 'code': code, 'similarity': similarity})
|
38 |
+
conn.close()
|
39 |
+
return sorted(results, key=lambda x: x['similarity'], reverse=True)[:5] # Top 5 matches
|
40 |
+
|
41 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
42 |
+
import numpy as np
|
43 |
+
|
44 |
+
def create_vector(category, level, location, total_lines, parent_path):
|
45 |
+
"""Helper to create a vector for query (matches parser's create_vector)."""
|
46 |
+
category_map = {
|
47 |
+
'import': 1, 'function': 2, 'async_function': 3, 'class': 4,
|
48 |
+
'if': 5, 'while': 6, 'for': 7, 'try': 8, 'expression': 9, 'spacer': 10,
|
49 |
+
'other': 11, 'elif': 12, 'else': 13, 'except': 14, 'finally': 15, 'return': 16,
|
50 |
+
'assigned_variable': 17, 'input_variable': 18, 'returned_variable': 19
|
51 |
+
}
|
52 |
+
category_id = category_map.get(category, 0)
|
53 |
+
start_line, end_line = location
|
54 |
+
span = (end_line - start_line + 1) / total_lines
|
55 |
+
center_pos = ((start_line + end_line) / 2) / total_lines
|
56 |
+
parent_depth = len(parent_path)
|
57 |
+
parent_weight = sum(category_map.get(parent.split('[')[0].lower(), 0) * (1 / (i + 1))
|
58 |
+
for i, parent in enumerate(parent_path)) / max(1, len(category_map))
|
59 |
+
return [category_id, level, center_pos, span, parent_depth, parent_weight]
|
60 |
+
|
61 |
@app.route('/', methods=['GET', 'POST'])
|
62 |
def index():
|
63 |
if request.method == 'POST':
|
64 |
parts = None
|
65 |
filename = 'unnamed.py'
|
66 |
code_input = None
|
67 |
+
query_results = None
|
68 |
|
69 |
+
# Handle file upload or pasted code (parsing)
|
70 |
if 'file' in request.files and request.files['file'].filename:
|
71 |
file = request.files['file']
|
72 |
if not file.filename.endswith('.py'):
|
|
|
76 |
file.save(file_path)
|
77 |
with open(file_path, 'r') as f:
|
78 |
code_input = f.read()
|
79 |
+
parts, sequence = parse_python_code(code_input)
|
80 |
+
# Store in database (for new files)
|
81 |
+
vectors = [part['vector'] for part in parts]
|
82 |
+
from database import store_program
|
83 |
+
store_program(code_input, sequence, vectors)
|
84 |
elif 'code' in request.form and request.form['code'].strip():
|
85 |
code_input = request.form['code']
|
86 |
filename = request.form.get('filename', 'unnamed.py') or 'unnamed.py'
|
87 |
if not filename.endswith('.py'):
|
88 |
filename += '.py'
|
89 |
+
parts, sequence = parse_python_code(code_input)
|
90 |
+
vectors = [part['vector'] for part in parts]
|
91 |
+
from database import store_program
|
92 |
+
store_program(code_input, sequence, vectors)
|
93 |
+
elif 'query_ops' in request.form and request.form['query_ops'].strip():
|
94 |
+
# Handle query for operations
|
95 |
+
operations = [op.strip() for op in request.form['query_ops'].split(',')]
|
96 |
+
query_results = query_programs(operations)
|
97 |
+
return render_template(
|
98 |
+
'results_partial.html',
|
99 |
+
parts=None,
|
100 |
+
filename=filename,
|
101 |
+
reconstructed_code=None,
|
102 |
+
code_input=None,
|
103 |
+
query_results=query_results
|
104 |
+
)
|
105 |
|
106 |
if parts:
|
107 |
indexed_parts = [{'index': i + 1, **part} for i, part in enumerate(parts)]
|
|
|
111 |
parts=indexed_parts,
|
112 |
filename=filename,
|
113 |
reconstructed_code=reconstructed_code,
|
114 |
+
code_input=code_input,
|
115 |
+
query_results=None
|
116 |
)
|
117 |
+
return 'No file, code, or query provided', 400
|
118 |
|
119 |
+
# Initial page load
|
120 |
+
init_db() # Ensure database is initialized
|
121 |
+
populate_sample_db() # Populate with sample data
|
122 |
+
return render_template('index.html', parts=None, filename=None, reconstructed_code=None, code_input=None, query_results=None)
|
123 |
|
124 |
@app.route('/export_json', methods=['POST'])
|
125 |
def export_json():
|
|
|
138 |
if __name__ == '__main__':
|
139 |
if not os.path.exists('uploads'):
|
140 |
os.makedirs('uploads')
|
141 |
+
app.run(port=7860)
|