bluenevus commited on
Commit
906205b
·
1 Parent(s): f11fa32

Update app.py via AI Editor

Browse files
Files changed (1) hide show
  1. app.py +58 -21
app.py CHANGED
@@ -32,14 +32,24 @@ MAX_OUTPUT_TOKENS = 65536
32
 
33
  SESSION_STORE = {}
34
 
35
- def get_session_id():
36
- ctx = dash.callback_context
37
- sid = None
38
- if hasattr(ctx, "request") and hasattr(ctx.request, "cookies"):
39
- cookies = ctx.request.cookies
40
- sid = cookies.get('dash_session', None)
41
- if not sid:
42
- sid = str(uuid.uuid4())
 
 
 
 
 
 
 
 
 
 
43
  return sid
44
 
45
  def get_session_data(session_id):
@@ -471,6 +481,9 @@ def get_proposals_list(proposaldict):
471
 
472
  app.layout = dbc.Container([
473
  dcc.Store(id='preview-window-state', data='expanded'),
 
 
 
474
  dbc.Row([
475
  dbc.Col([
476
  dbc.Card([
@@ -568,6 +581,27 @@ app.layout = dbc.Container([
568
  ], style={'marginTop':'20px'})
569
  ], fluid=True)
570
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571
  @app.callback(
572
  Output('output-preview-container', 'style'),
573
  [Input('preview-window-state', 'data')]
@@ -616,7 +650,8 @@ def update_preview_window_style(state):
616
  State('select-proposal-dropdown', 'value'),
617
  State('chat-input', 'value'),
618
  Input('cancel-action-btn', 'n_clicks'),
619
- State('preview-window-state', 'data')
 
620
  ],
621
  prevent_initial_call=True
622
  )
@@ -624,10 +659,12 @@ def master_callback(
624
  shred_clicks, proposal_clicks, compliance_clicks, recover_clicks, board_clicks, loe_clicks,
625
  rfp_content, rfp_filename, doc_delete_clicks, selected_doc,
626
  proposal_content, proposal_filename, proposal_delete_clicks, selected_proposal,
627
- chat_input, cancel_clicks, preview_window_state
 
628
  ):
629
- session_id = get_session_id()
630
- sess_data = get_session_data(session_id)
 
631
  ctx = callback_context
632
  triggered_id = ctx.triggered[0]['prop_id'].split('.')[0] if ctx.triggered else None
633
 
@@ -669,9 +706,9 @@ def master_callback(
669
  sess_data["uploaded_documents_bytes"][rfp_filename] = decoded
670
  if fileid:
671
  sess_data["uploaded_documents_fileid"][rfp_filename] = fileid
672
- logging.info(f"[{session_id}] Document uploaded: {rfp_filename}")
673
  else:
674
- logging.error(f"[{session_id}] Failed to decode uploaded document: {rfp_filename}")
675
 
676
  if triggered_id == 'upload-proposal' and proposal_content is not None and proposal_filename:
677
  content_type, content_string = proposal_content.split(',')
@@ -684,9 +721,9 @@ def master_callback(
684
  sess_data["proposals"][proposal_filename] = text
685
  if fileid:
686
  sess_data["proposals_fileid"][proposal_filename] = fileid
687
- logging.info(f"[{session_id}] Proposal uploaded: {proposal_filename}")
688
  else:
689
- logging.error(f"[{session_id}] Failed to decode uploaded proposal: {proposal_filename}")
690
 
691
  if triggered_id and isinstance(doc_delete_clicks, list):
692
  for i, n_click in enumerate(doc_delete_clicks):
@@ -699,14 +736,14 @@ def master_callback(
699
  try:
700
  genai.delete_file(sess_data["uploaded_documents_fileid"][del_filename])
701
  except Exception as e:
702
- logging.warning(f"[{session_id}] Failed to delete Gemini file {del_filename}: {e}")
703
  del sess_data["uploaded_documents_fileid"][del_filename]
704
  if del_filename in sess_data["uploaded_documents_bytes"]:
705
  del sess_data["uploaded_documents_bytes"][del_filename]
706
- logging.info(f"[{session_id}] Document deleted: {del_filename}")
707
  if del_filename in sess_data["shredded_documents"]:
708
  del sess_data["shredded_documents"][del_filename]
709
- logging.info(f"[{session_id}] Shredded doc deleted: {del_filename}")
710
  if selected_doc == del_filename:
711
  selected_doc = None
712
  break
@@ -722,9 +759,9 @@ def master_callback(
722
  try:
723
  genai.delete_file(sess_data["proposals_fileid"][del_filename])
724
  except Exception as e:
725
- logging.warning(f"[{session_id}] Failed to delete Gemini proposal file {del_filename}: {e}")
726
  del sess_data["proposals_fileid"][del_filename]
727
- logging.info(f"[{session_id}] Proposal deleted: {del_filename}")
728
  if selected_proposal == del_filename:
729
  selected_proposal = None
730
  break
 
32
 
33
  SESSION_STORE = {}
34
 
35
+ def get_session_id_from_cookie(cookie_str):
36
+ # Parse a cookie string like "dash_session=abcd; something=xyz"
37
+ if not cookie_str:
38
+ return None
39
+ for part in cookie_str.split(";"):
40
+ if part.strip().startswith("dash_session="):
41
+ return part.strip().split("=")[1]
42
+ return None
43
+
44
+ def get_session_id(session_id=None):
45
+ # Always require session_id as input; never generate unless absent
46
+ if session_id and session_id in SESSION_STORE:
47
+ return session_id
48
+ if session_id:
49
+ # New session, not yet in store
50
+ return session_id
51
+ # Defensive fallback: generate a new session_id (should never hit this)
52
+ sid = str(uuid.uuid4())
53
  return sid
54
 
55
  def get_session_data(session_id):
 
481
 
482
  app.layout = dbc.Container([
483
  dcc.Store(id='preview-window-state', data='expanded'),
484
+ dcc.Store(id='session-id-store', storage_type='session'), # Session ID per browser session
485
+ html.Div(id='set-session-cookie', style={'display': 'none'}), # dummy div for JS callback
486
+ dcc.Location(id='dummy-url', refresh=False), # For JS init on page load
487
  dbc.Row([
488
  dbc.Col([
489
  dbc.Card([
 
581
  ], style={'marginTop':'20px'})
582
  ], fluid=True)
583
 
584
+ # JS callback: Set session cookie and session-id-store on first page load if not present
585
+ app.clientside_callback(
586
+ """
587
+ function(n, dummy_url) {
588
+ let sid = window.sessionStorage.getItem('dash_session');
589
+ let store_val = null;
590
+ if(!sid) {
591
+ sid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
592
+ (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
593
+ );
594
+ window.sessionStorage.setItem('dash_session', sid);
595
+ }
596
+ document.cookie = "dash_session=" + sid + "; path=/";
597
+ store_val = sid;
598
+ return store_val;
599
+ }
600
+ """,
601
+ Output('session-id-store', 'data'),
602
+ Input('dummy-url', 'pathname')
603
+ )
604
+
605
  @app.callback(
606
  Output('output-preview-container', 'style'),
607
  [Input('preview-window-state', 'data')]
 
650
  State('select-proposal-dropdown', 'value'),
651
  State('chat-input', 'value'),
652
  Input('cancel-action-btn', 'n_clicks'),
653
+ State('preview-window-state', 'data'),
654
+ State('session-id-store', 'data')
655
  ],
656
  prevent_initial_call=True
657
  )
 
659
  shred_clicks, proposal_clicks, compliance_clicks, recover_clicks, board_clicks, loe_clicks,
660
  rfp_content, rfp_filename, doc_delete_clicks, selected_doc,
661
  proposal_content, proposal_filename, proposal_delete_clicks, selected_proposal,
662
+ chat_input, cancel_clicks, preview_window_state,
663
+ session_id
664
  ):
665
+ # Always get session_id from dcc.Store, never generate
666
+ sid = get_session_id(session_id)
667
+ sess_data = get_session_data(sid)
668
  ctx = callback_context
669
  triggered_id = ctx.triggered[0]['prop_id'].split('.')[0] if ctx.triggered else None
670
 
 
706
  sess_data["uploaded_documents_bytes"][rfp_filename] = decoded
707
  if fileid:
708
  sess_data["uploaded_documents_fileid"][rfp_filename] = fileid
709
+ logging.info(f"[{sid}] Document uploaded: {rfp_filename}")
710
  else:
711
+ logging.error(f"[{sid}] Failed to decode uploaded document: {rfp_filename}")
712
 
713
  if triggered_id == 'upload-proposal' and proposal_content is not None and proposal_filename:
714
  content_type, content_string = proposal_content.split(',')
 
721
  sess_data["proposals"][proposal_filename] = text
722
  if fileid:
723
  sess_data["proposals_fileid"][proposal_filename] = fileid
724
+ logging.info(f"[{sid}] Proposal uploaded: {proposal_filename}")
725
  else:
726
+ logging.error(f"[{sid}] Failed to decode uploaded proposal: {proposal_filename}")
727
 
728
  if triggered_id and isinstance(doc_delete_clicks, list):
729
  for i, n_click in enumerate(doc_delete_clicks):
 
736
  try:
737
  genai.delete_file(sess_data["uploaded_documents_fileid"][del_filename])
738
  except Exception as e:
739
+ logging.warning(f"[{sid}] Failed to delete Gemini file {del_filename}: {e}")
740
  del sess_data["uploaded_documents_fileid"][del_filename]
741
  if del_filename in sess_data["uploaded_documents_bytes"]:
742
  del sess_data["uploaded_documents_bytes"][del_filename]
743
+ logging.info(f"[{sid}] Document deleted: {del_filename}")
744
  if del_filename in sess_data["shredded_documents"]:
745
  del sess_data["shredded_documents"][del_filename]
746
+ logging.info(f"[{sid}] Shredded doc deleted: {del_filename}")
747
  if selected_doc == del_filename:
748
  selected_doc = None
749
  break
 
759
  try:
760
  genai.delete_file(sess_data["proposals_fileid"][del_filename])
761
  except Exception as e:
762
+ logging.warning(f"[{sid}] Failed to delete Gemini proposal file {del_filename}: {e}")
763
  del sess_data["proposals_fileid"][del_filename]
764
+ logging.info(f"[{sid}] Proposal deleted: {del_filename}")
765
  if selected_proposal == del_filename:
766
  selected_proposal = None
767
  break