22
33import RNA
44import dash
5- from dash import callback , html , clientside_callback , Input , Output , dcc , dash_table , State , Patch
5+ from dash import callback , html , clientside_callback , Input , Output , dcc , dash_table , State , Patch , ALL , ctx
66import dash_bootstrap_components as dbc
77from RNAdist .dashboard import MAX_SEQ_LENGTH , CONFIG
88from RNAdist .sampling .ed_sampling import distance_histogram
9+ from RNAdist .dashboard .backends import celery
910from RNAdist .plots .sampling_plots import distance_histo_from_matrix
1011import sqlite3
1112import numpy as np
@@ -68,11 +69,26 @@ def get_submissions_table():
6869 'backgroundColor' : 'var(--bs-tertiary-bg)' ,
6970 },
7071 {
71- 'if' : {'column_id' : 'Header' },
72- 'color' : 'var(--bs-secondary)' , # use Bootstrap link color variable
72+ 'if' : {
73+ 'column_id' : 'Header' ,
74+ 'filter_query' : '{Status} = "finished"' # only style if status is finished
75+ },
76+ 'color' : 'var(--bs-secondary)' , # Bootstrap link color variable
7377 'textDecoration' : 'underline' ,
7478 'cursor' : 'pointer' ,
75- }
79+ },
80+ {
81+ "if" : {"state" : "active" },
82+ "backgroundColor" : "inherit !important" ,
83+ "border" : "inherit !important" ,
84+ "color" : "red"
85+ },
86+ {
87+ "if" : {"column_id" : "Header" , "filter_query" : '{Status} = "finished"' },
88+ "color" : "var(--bs-secondary)" ,
89+ "textDecoration" : "underline" ,
90+ "cursor" : "pointer" ,
91+ },
7692
7793 ],
7894 style_header = {
@@ -98,6 +114,7 @@ def get_submissions_table():
98114 'overflow' : 'hidden' ,
99115 'textOverflow' : 'ellipsis' ,
100116 'whiteSpace' : 'nowrap' ,
117+ "userSelect" : "none"
101118 },
102119 ),
103120
@@ -309,6 +326,8 @@ def check_valid_input(sequence, temperature, bpspan, user_id, header):
309326
310327)
311328def submit_sequence (n_clicks , sequence , header , user_id , temperature , max_bp_span , is_open ):
329+ print ("triggered:" , ctx .triggered_id )
330+
312331 if n_clicks is None :
313332 raise dash .exceptions .PreventUpdate
314333
@@ -346,37 +365,58 @@ def submit_sequence(n_clicks, sequence, header, user_id, temperature, max_bp_spa
346365 return [header , fields , sequence ], is_open , dash .no_update
347366
348367
349- @callback (
350- output = Output ("sequence-computation-finished" , "data" ),
351- inputs = Input ("submitted-job" , "data" ),
352- state = [
353- State ("user_id" , "data" ),
354- ],
355- background = True ,
356- prevent_initial_call = True
357- )
358- def process_sequence (submitted_job , user_id ):
359- logger .info ("STARTED long running task" )
360368
361- if submitted_job is None :
362- return dash . no_update
369+ def _process_sequence_inline ( submitted_job , user_id ) :
370+ """Same code as your Celery task, for local execution without Redis."""
363371 DB .database_cleanup ()
364372 header , md_dict , sequence = submitted_job
373+ logger .info (f"started processing sequence: { header } -{ user_id } " )
374+
365375 RNA .init_rand (42 )
366376 md = RNA .md (** md_dict )
367377 fc = RNA .fold_compound (sequence , md )
368378 _ , md_hash = hash_model_details (md , sequence )
369379 try :
370-
371380 DB .set_status (md_hash , "running" , user_id , header )
372381 histograms , samples = distance_histogram (fc , 10000 , return_samples = True )
373382 DB .compress_and_insert_into_submissions (sequence , histograms , samples , fc , md )
374383 DB .set_status (md_hash , "finished" , user_id , header )
375384 except Exception as e :
376- print ("RUNNING" )
377385 DB .set_status (md_hash , "failed" , user_id , header )
378386 raise e
379- logger .info (f"FINISHED long running task" )
387+ logger .info (f"FINISHED long running task { header } -{ user_id } " )
388+ return True
389+
390+ if CONFIG ["REDIS" ]["URL" ]:
391+ @celery .task (bind = True )
392+ def process_sequence_task (self , submitted_job , user_id ):
393+ _process_sequence_inline (submitted_job , user_id )
394+ return True
395+
396+ else :
397+ process_sequence_task = _process_sequence_inline
398+
399+ @callback (
400+ output = Output ("sequence-computation-finished" , "data" ),
401+ inputs = Input ("submitted-job" , "data" ),
402+ state = [
403+ State ("user_id" , "data" ),
404+ ],
405+ running = [
406+ (Output ("submit-sequence" , "disabled" ), True , False ),
407+ ] if not CONFIG ["REDIS" ]["URL" ] else None ,
408+ background = True if not CONFIG ["REDIS" ]["URL" ] else False ,
409+ prevent_initial_call = "initial_duplicate" ,
410+ allow_duplicate = True ,
411+ )
412+ def process_sequence (submitted_job , user_id ):
413+ print ("triggered:" , ctx .triggered_id , submitted_job )
414+ if submitted_job is None :
415+ return dash .no_update
416+ if CONFIG ["REDIS" ]["URL" ]:
417+ async_result = process_sequence_task .delay (submitted_job , user_id )
418+ else :
419+ process_sequence_task (submitted_job , user_id )
380420 return True
381421
382422@callback (
@@ -390,12 +430,10 @@ def process_sequence(submitted_job, user_id):
390430)
391431def display_status (n , user_id , _ , _2 ):
392432 status = DB .get_jobs_of_user (user_id )
393- logger .info (f"status: { status } " )
394433 table = []
395434 tooltips = []
396435 all_finished = True
397436 for row in status :
398- logger .info (row )
399437 job_id = str (row ["job_hash" ].hex ())
400438 state = row ["status" ]
401439 if state != "finished" :
@@ -411,7 +449,6 @@ def display_status(n, user_id, _, _2):
411449 "Sequence" : {"value" : seq , "type" : "text" } # tooltip shows full sequence on hover
412450 })
413451 row = {"Status" : state , "Job ID" : job_id , "Header" : row ["header" ], "ModelDetails" : model_details , "Sequence" : seq }
414- print (row )
415452 table .append (row )
416453
417454 interval_disabled = all_finished
@@ -423,6 +460,7 @@ def display_status(n, user_id, _, _2):
423460 Output ("page-wide-seqid" , "data" ),
424461 Output ('url' , 'pathname' ),
425462 Output ("not-finished-modal" , "is_open" ),
463+ Output ('submissions-table' , 'active_cell' ),
426464 Input ('submissions-table' , 'active_cell' ),
427465 State ('submissions-table' , 'data' ),
428466)
@@ -436,6 +474,6 @@ def on_row_select(active_cell, data):
436474 if header_value is None :
437475 raise dash .exceptions .PreventUpdate
438476 if status != "finished" :
439- return dash .no_update , dash .no_update , True
477+ return dash .no_update , dash .no_update , True , None
440478
441- return header_value , "visualization" , dash .no_update
479+ return header_value , "visualization" , dash .no_update , None
0 commit comments