Update app.py via AI Editor
Browse files
app.py
CHANGED
@@ -167,7 +167,7 @@ def get_file_cards(file_dict):
|
|
167 |
dbc.Col(
|
168 |
dbc.Button(
|
169 |
"Delete",
|
170 |
-
id={'type': '
|
171 |
color="danger",
|
172 |
size="sm",
|
173 |
style={'marginLeft': 'auto', 'float': 'right'}
|
@@ -273,54 +273,60 @@ app.layout = dbc.Container([
|
|
273 |
|
274 |
@app.callback(
|
275 |
Output('file-list', 'children'),
|
276 |
-
[
|
277 |
-
|
278 |
-
|
|
|
|
|
|
|
|
|
279 |
prevent_initial_call='initial_duplicate'
|
280 |
)
|
281 |
-
def
|
282 |
ctx = callback_context
|
283 |
session_data, lock = get_session_data()
|
284 |
-
# On first load, restore file list from session temp dir
|
285 |
with lock:
|
286 |
restore_session_files(session_data)
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
removed_file = triggered_id_dict['index']
|
309 |
-
except Exception:
|
310 |
-
raise PreventUpdate
|
311 |
-
with lock:
|
312 |
-
if removed_file in session_data['uploaded_files']:
|
313 |
try:
|
314 |
-
|
315 |
-
|
316 |
except Exception as e:
|
317 |
-
logger.warning(f"
|
318 |
-
|
319 |
-
session_data['
|
320 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
321 |
return get_file_cards(session_data['uploaded_files'])
|
322 |
-
# Otherwise just display current files (e.g. on initial load)
|
323 |
-
return get_file_cards(session_data['uploaded_files'])
|
324 |
|
325 |
def generate_matrix_with_gpt(matrix_type, file_contents):
|
326 |
prompt = f"""Generate a {matrix_type} based on the following project artifacts:
|
@@ -367,7 +373,6 @@ Now, generate the {matrix_type}:
|
|
367 |
def handle_matrix_and_chat(*args):
|
368 |
session_data, lock = get_session_data()
|
369 |
ctx = callback_context
|
370 |
-
# Matrix generation button pressed
|
371 |
matrix_btns_len = len(matrix_types)
|
372 |
matrix_btn_inputs = args[:matrix_btns_len]
|
373 |
chat_n_clicks = args[matrix_btns_len]
|
@@ -375,7 +380,6 @@ def handle_matrix_and_chat(*args):
|
|
375 |
if not ctx.triggered:
|
376 |
raise PreventUpdate
|
377 |
triggered_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
378 |
-
# If matrix button triggered
|
379 |
if "matrix-btn" in triggered_id:
|
380 |
import ast
|
381 |
try:
|
@@ -395,7 +399,6 @@ def handle_matrix_and_chat(*args):
|
|
395 |
except Exception as e:
|
396 |
logger.exception(f"Error generating matrix: {str(e)}")
|
397 |
return html.Div(f"Error generating matrix: {str(e)}"), "Error", ""
|
398 |
-
# If chat send button triggered
|
399 |
elif "btn-send-chat" in triggered_id:
|
400 |
if not chat_input_value or session_data['current_matrix'] is None or session_data['matrix_type'] is None:
|
401 |
raise PreventUpdate
|
|
|
167 |
dbc.Col(
|
168 |
dbc.Button(
|
169 |
"Delete",
|
170 |
+
id={'type': 'delete-file-btn', 'index': name},
|
171 |
color="danger",
|
172 |
size="sm",
|
173 |
style={'marginLeft': 'auto', 'float': 'right'}
|
|
|
273 |
|
274 |
@app.callback(
|
275 |
Output('file-list', 'children'),
|
276 |
+
[
|
277 |
+
Input('upload-files', 'contents'),
|
278 |
+
Input({'type': 'delete-file-btn', 'index': ALL}, 'n_clicks')
|
279 |
+
],
|
280 |
+
[
|
281 |
+
State('upload-files', 'filename'),
|
282 |
+
],
|
283 |
prevent_initial_call='initial_duplicate'
|
284 |
)
|
285 |
+
def handle_file_upload_and_delete(list_of_contents, delete_clicks, list_of_names):
|
286 |
ctx = callback_context
|
287 |
session_data, lock = get_session_data()
|
|
|
288 |
with lock:
|
289 |
restore_session_files(session_data)
|
290 |
+
triggered = ctx.triggered
|
291 |
+
if triggered:
|
292 |
+
prop_id = triggered[0]['prop_id']
|
293 |
+
# Handle file upload
|
294 |
+
if prop_id.startswith("upload-files.contents"):
|
295 |
+
logger.info("Uploading files...")
|
296 |
+
if list_of_contents is not None and list_of_names is not None:
|
297 |
+
for content, name in zip(list_of_contents, list_of_names):
|
298 |
+
content_type, content_string = content.split(',')
|
299 |
+
decoded = base64.b64decode(content_string)
|
300 |
+
temp_path = os.path.join(session_data['temp_dir'], name)
|
301 |
+
with open(temp_path, 'wb') as f:
|
302 |
+
f.write(decoded)
|
303 |
+
session_data['uploaded_files'][name] = temp_path
|
304 |
+
session_data['file_texts'][name] = parse_file_content(temp_path, name)
|
305 |
+
logger.info(f"Files after upload: {list(session_data['uploaded_files'].keys())}")
|
306 |
+
return get_file_cards(session_data['uploaded_files'])
|
307 |
+
# Handle delete button click
|
308 |
+
elif "delete-file-btn" in prop_id:
|
309 |
+
import ast
|
310 |
+
btn_id = prop_id.split('.')[0]
|
|
|
|
|
|
|
|
|
|
|
311 |
try:
|
312 |
+
btn_id_dict = ast.literal_eval(btn_id)
|
313 |
+
filename = btn_id_dict['index']
|
314 |
except Exception as e:
|
315 |
+
logger.warning(f"Could not extract filename from delete prop_id: {prop_id} error: {e}")
|
316 |
+
raise PreventUpdate
|
317 |
+
if filename in session_data['uploaded_files']:
|
318 |
+
filepath = session_data['uploaded_files'][filename]
|
319 |
+
try:
|
320 |
+
os.remove(filepath)
|
321 |
+
logger.info(f"Deleted file from disk: {filename}")
|
322 |
+
except Exception as e:
|
323 |
+
logger.warning(f"Failed to delete temp file {filename}: {e}")
|
324 |
+
session_data['uploaded_files'].pop(filename, None)
|
325 |
+
session_data['file_texts'].pop(filename, None)
|
326 |
+
logger.info(f"Files after deletion: {list(session_data['uploaded_files'].keys())}")
|
327 |
+
return get_file_cards(session_data['uploaded_files'])
|
328 |
+
# On initial load or no trigger, show files from session
|
329 |
return get_file_cards(session_data['uploaded_files'])
|
|
|
|
|
330 |
|
331 |
def generate_matrix_with_gpt(matrix_type, file_contents):
|
332 |
prompt = f"""Generate a {matrix_type} based on the following project artifacts:
|
|
|
373 |
def handle_matrix_and_chat(*args):
|
374 |
session_data, lock = get_session_data()
|
375 |
ctx = callback_context
|
|
|
376 |
matrix_btns_len = len(matrix_types)
|
377 |
matrix_btn_inputs = args[:matrix_btns_len]
|
378 |
chat_n_clicks = args[matrix_btns_len]
|
|
|
380 |
if not ctx.triggered:
|
381 |
raise PreventUpdate
|
382 |
triggered_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
|
|
383 |
if "matrix-btn" in triggered_id:
|
384 |
import ast
|
385 |
try:
|
|
|
399 |
except Exception as e:
|
400 |
logger.exception(f"Error generating matrix: {str(e)}")
|
401 |
return html.Div(f"Error generating matrix: {str(e)}"), "Error", ""
|
|
|
402 |
elif "btn-send-chat" in triggered_id:
|
403 |
if not chat_input_value or session_data['current_matrix'] is None or session_data['matrix_type'] is None:
|
404 |
raise PreventUpdate
|