libokj commited on
Commit
1eb795a
·
1 Parent(s): 3ffc570

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +100 -76
app.py CHANGED
@@ -462,12 +462,20 @@ def submit_predict(predict_filepath, task, preset, target_family, flag, state, p
462
  predictions = [pd.DataFrame(prediction) for prediction in predictions]
463
  prediction_df = pd.concat([prediction_df, pd.concat(predictions, ignore_index=True)])
464
  prediction_df.set_index('N', inplace=True)
 
 
 
 
 
 
 
465
 
466
  predictions_file = f'temp/{job_id}_predictions.csv'
467
  prediction_df.to_csv(predictions_file)
468
 
469
- return [predictions_file,
470
- False]
 
471
  except Exception as e:
472
  gr.Warning(f"Prediction job failed due to error: {str(e)}")
473
  return {run_state: False}
@@ -655,15 +663,15 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
655
  desc='Processing FASTA...').apply(
656
  lambda x: wrap_text(x) if not pd.isna(x) else x)
657
 
658
- if columns_unique is not None:
659
- unique_df = df_html.loc[:, columns_unique].iloc[[0]]
660
- df_html = df_html.loc[:, ~columns_unique]
661
-
662
  num_cols = df_html.select_dtypes('number').columns
663
  num_col_colors = sns.color_palette('husl', len(num_cols))
664
  bool_cols = df_html.select_dtypes(bool).columns
665
  bool_col_colors = {True: 'lightgreen', False: 'lightpink'}
666
 
 
 
 
 
667
  if not file:
668
  if 'Compound ID' in df_html.columns:
669
  df_html.drop(['Compound SMILES'], axis=1, inplace=True)
@@ -678,28 +686,35 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
678
  styled_df = df_html.style.format(precision=3)
679
 
680
  for i, col in enumerate(num_cols):
681
- if col not in ['Predicted Binding Affinity', 'Actual Binding Affinity']:
682
- styled_df = styled_df.background_gradient(
683
- subset=[col], cmap=sns.light_palette(num_col_colors[i], as_cmap=True))
684
- else:
685
- styled_df = styled_df.background_gradient(
686
- subset=[col], cmap=sns.light_palette(num_col_colors[i], as_cmap=True).reversed())
 
687
 
688
- styled_df.applymap(lambda val: f'background-color: {bool_col_colors[val]}', subset=bool_cols)
 
689
 
690
  table_html = styled_df.to_html()
691
  unique_html = ''
692
  if unique_df is not None:
693
- unique_html = unique_df.replace('\n', '<br>', regex=True).to_html(escape=False, index=False)
694
- unique_html = f'<div style="font-family: Courier !important;">{unique_html}</div>'
 
 
 
 
 
695
 
696
  return (f'<div style="font-size: 16px; font-weight: bold;">{job} Report Preview (Top 30 Records)</div>'
697
- f'{unique_html}'
698
  f'<div style="overflow:auto; height: 300px; font-family: Courier !important;">{table_html}</div>')
699
 
700
  else:
701
- bool_formatters = {col: BooleanFormatter() for col in df_html.select_dtypes(bool).columns}
702
- num_formatters = {col: NumberFormatter(format='0.000') for col in df_html.select_dtypes('floating').columns}
703
  other_formatters = {
704
  'Predicted Interaction Probability': {'type': 'progress', 'max': 1.0, 'legend': True},
705
  'Actual Interaction Probability': {'type': 'progress', 'max': 1.0, 'legend': True},
@@ -716,7 +731,7 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
716
  template='<a href="https://pubchem.ncbi.nlm.nih.gov/compound/<%= value %>" '
717
  'target="_blank"><%= value %></a>')
718
  }
719
- formatters = {**bool_formatters, **num_formatters, **other_formatters}
720
 
721
  # html = df.to_html(file)
722
  # return html
@@ -724,7 +739,7 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
724
  report_table = pn.widgets.Tabulator(
725
  df_html, formatters=formatters,
726
  frozen_columns=['Index', 'Target ID', 'Compound ID', 'Compound', 'Scaffold'],
727
- disabled=True, sizing_mode='stretch_both')
728
 
729
  for i, col in enumerate(num_cols):
730
  if col not in ['Predicted Binding Affinity', 'Actual Binding Affinity']:
@@ -754,34 +769,28 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
754
  font-family: Courier New !important;
755
  font-weight: normal !important;
756
  font-size: 12px !important;
757
- overflow: visible !important;
758
  }
759
 
760
  .tabulator-cell {
761
  overflow: visible !important;
762
  }
763
 
764
- .bk-panel-models-tabulator-DataTabulator {
765
- overflow: visible !important;
766
  }
767
 
768
  .tabulator-cell.tabulator-frozen:hover {
769
  z-index: 1000 !important;
770
  }
771
 
772
- .bk-panel-models-tabulator-DataTabulator:hover {
773
- z-index: 999 !important;
774
- }
775
-
776
  .image-zoom-viewer {
777
  display: inline-block;
778
- position: relative;
779
- overflow: visible; /* Ensures that the scaled SVG isn't clipped */
780
  }
781
 
782
  .image-zoom-viewer::after {
783
  content: "";
784
- position: absolute;
785
  top: 0;
786
  left: 0;
787
  width: 100%;
@@ -795,14 +804,15 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
795
 
796
  /* When hovering over the container, scale its child (the SVG) */
797
  .tabulator-cell:hover .image-zoom-viewer svg {
798
- padding: 3px;
799
- position: relative; /* Position the SVG relative to the viewport */
800
  background-color: rgba(250, 250, 250, 0.854);
801
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.618);
802
  border-radius: 3px;
803
- transform: scale(4) translate(+38.2%, +38.2%); /* Scale up the SVG */
804
  transition: transform 0.3s ease;
805
  pointer-events: none; /* Prevents the SVG from blocking mouse interactions */
 
806
  }
807
 
808
  .image-zoom-viewer svg {
@@ -828,19 +838,24 @@ def create_html_report(df, file=None, task=None, progress=gr.Progress(track_tqdm
828
  busy_indicator=None,
829
  )
830
 
831
- info_row = pn.Row()
832
  if unique_df is not None:
833
- unique_table = pn.widgets.Tabulator(unique_df, formatters=formatters, show_index=False, disabled=True)
834
- info_row.append(pn.Column(f'### {unique_entity}', unique_table))
 
 
 
 
835
  if pie_charts:
836
  for score_name, figure_list in pie_charts.items():
837
- info_row.append(
838
  pn.Column(f'### {category} by Top {score_name}',
839
  pn.Tabs(*figure_list, tabs_location='above'))
840
  # pn.Card(pn.Row(v), title=f'{category} by Top {k}')
841
  )
842
- if info_row:
843
- template.main.append(pn.Card(info_row,
 
844
  sizing_mode='stretch_width', title='Summary Statistics', margin=10))
845
 
846
  template.main.append(
@@ -860,13 +875,19 @@ def create_pie_chart(df, category, value, top_k):
860
  data = pd.DataFrame({category: category_counts.index, 'value': category_counts.values})
861
 
862
  data['proportion'] = data['value'] / data['value'].sum()
863
- # Merge rows with proportion less than 0.1% into one row
864
- mask = data['proportion'] <= 0.001
865
- merged_row = data[mask].sum()
866
- merged_row[category] = 'Other'
867
- data = pd.concat([data[~mask], pd.DataFrame(merged_row).T])
 
868
  data['angle'] = data['proportion'] * 2 * pi
869
- data['color'] = (Category20c_20 * (len(data) // 20 + 1))[:len(data)]
 
 
 
 
 
870
 
871
  tooltips = [
872
  (f"{category}", f"@{{{category}}}"),
@@ -878,30 +899,33 @@ def create_pie_chart(df, category, value, top_k):
878
  data = data.merge(top_k_df[['Scaffold SMILES', 'Scaffold']].drop_duplicates(), how='left',
879
  left_on='Scaffold SMILES', right_on='Scaffold SMILES')
880
  tooltips.append(("Scaffold", "<div>@{Scaffold}{safe}</div>"))
881
- p = figure(height=256, name=f"Top {top_k}" if top_k < len(df) else 'All',
882
- toolbar_location=None, tools="hover", tooltips=tooltips, x_range=(-0.5, 0.5),
883
- sizing_mode="scale_height")
884
- p.axis.axis_label = None
885
- p.axis.visible = False
886
- p.grid.grid_line_color = None
887
- p.outline_line_width = 0
888
- p.min_border = 0
889
- p.min_border_right = 0
890
- p.margin = 0
891
 
892
  p.add_layout(Legend(padding=0, margin=0), 'right')
893
  p.wedge(x=0, y=1, radius=0.3,
894
  start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
895
- line_color="white", fill_color='color', legend_field=category, source=data)
896
 
897
- p.legend.label_text_font_size = "8pt"
898
- p.legend.margin = 0
899
- p.legend.padding = 0
900
-
901
- # Limit the number of legend items to 20 and add "..." if there are more than 30 items
902
  if len(p.legend.items) > 20:
903
- p.legend.items = p.legend.items[:21]
904
- p.legend.items.append(LegendItem(label="..."))
 
 
 
 
 
 
 
 
 
 
905
 
906
  return p
907
 
@@ -1408,7 +1432,7 @@ with gr.Blocks(theme=theme, title='DeepSEQreen', css=CSS) as demo:
1408
  The page shows only a preview report displaying at most 30 records
1409
  (with top predicted CPI/CPA if reporting results from a prediction job).
1410
 
1411
- Please first `**Preview**` the report, then `**Generate**` and download a CSV report
1412
  or an interactive HTML report below if you wish to access the full report.
1413
  ''')
1414
  with gr.Row():
@@ -1841,7 +1865,7 @@ QALAHAYFAQYHDPDDEPVADPYDQSFESRDLLIDEWKSLTYDEVISFVPPPLDQEEMES
1841
  fn=submit_predict,
1842
  inputs=[screen_data_for_predict, drug_screen_task, drug_screen_preset,
1843
  drug_screen_target_family, screen_flag, run_state], # , drug_screen_email],
1844
- outputs=[file_for_report, run_state]
1845
  ).then(
1846
  fn=lambda: [gr.Column(visible=True), gr.Markdown(visible=False), gr.Tabs(selected=3)],
1847
  outputs=[screen_page, screen_waiting, tabs]
@@ -1858,7 +1882,7 @@ QALAHAYFAQYHDPDDEPVADPYDQSFESRDLLIDEWKSLTYDEVISFVPPPLDQEEMES
1858
  fn=submit_predict,
1859
  inputs=[identify_data_for_predict, target_identify_task, target_identify_preset,
1860
  target_identify_target_family, identify_flag, run_state], # , target_identify_email],
1861
- outputs=[file_for_report, run_state]
1862
  ).then(
1863
  fn=lambda: [gr.Column(visible=True), gr.Markdown(visible=False), gr.Tabs(selected=3)],
1864
  outputs=[identify_page, identify_waiting, tabs]
@@ -1875,7 +1899,7 @@ QALAHAYFAQYHDPDDEPVADPYDQSFESRDLLIDEWKSLTYDEVISFVPPPLDQEEMES
1875
  fn=submit_predict,
1876
  inputs=[infer_data_for_predict, pair_infer_task, pair_infer_preset,
1877
  pair_infer_target_family, infer_flag, run_state], # , pair_infer_email],
1878
- outputs=[file_for_report, run_state]
1879
  ).then(
1880
  fn=lambda: [gr.Column(visible=True), gr.Markdown(visible=False), gr.Tabs(selected=3)],
1881
  outputs=[infer_page, infer_waiting, tabs]
@@ -1903,7 +1927,9 @@ QALAHAYFAQYHDPDDEPVADPYDQSFESRDLLIDEWKSLTYDEVISFVPPPLDQEEMES
1903
  else:
1904
  return {report_task: gr.Dropdown(visible=False)}
1905
 
1906
-
 
 
1907
  file_for_report.change(fn=update_df, inputs=file_for_report, outputs=[
1908
  html_report, raw_df, report_df, analyze_btn]).success(
1909
  fn=lambda: [gr.Button(interactive=False)]*2 + [gr.File(visible=False)]*2 + [gr.Dropdown(visible=False)],
@@ -1912,10 +1938,8 @@ QALAHAYFAQYHDPDDEPVADPYDQSFESRDLLIDEWKSLTYDEVISFVPPPLDQEEMES
1912
  fn=inquire_task, inputs=[raw_df, report_upload_flag],
1913
  outputs=[report_task, html_report, analyze_btn, csv_generate, html_generate]
1914
  )
1915
- file_for_report.clear(fn=lambda: gr.Dropdown(visible=False), outputs=report_task)
1916
- file_for_report.upload(
1917
- fn=lambda: True, outputs=report_upload_flag
1918
- )
1919
 
1920
  analyze_btn.click(fn=submit_report, inputs=[raw_df, scores, filters, report_task], outputs=[
1921
  html_report, report_df, csv_download_file, html_download_file
@@ -1969,10 +1993,10 @@ QALAHAYFAQYHDPDDEPVADPYDQSFESRDLLIDEWKSLTYDEVISFVPPPLDQEEMES
1969
  # demo.load(None, None, None, js="() => {document.body.classList.remove('dark')}")
1970
 
1971
  if __name__ == "__main__":
1972
- screen_block.queue(max_size=2)
1973
- identify_block.queue(max_size=2)
1974
- infer_block.queue(max_size=2)
1975
- report.queue(max_size=20)
1976
 
1977
  # SCHEDULER.add_job(func=file_cleanup(), trigger="interval", seconds=60)
1978
  # SCHEDULER.start()
 
462
  predictions = [pd.DataFrame(prediction) for prediction in predictions]
463
  prediction_df = pd.concat([prediction_df, pd.concat(predictions, ignore_index=True)])
464
  prediction_df.set_index('N', inplace=True)
465
+ orig_df = pd.read_csv(
466
+ predict_filepath,
467
+ usecols=lambda x: x not in ['X1', 'ID1', 'Compound', 'Scaffold', 'Scaffold SMILES',
468
+ 'X2', 'ID2',
469
+ 'Y', 'Y^']
470
+ )
471
+ prediction_df = pd.merge(prediction_df, orig_df, left_index=True, right_index=True, how='left')
472
 
473
  predictions_file = f'temp/{job_id}_predictions.csv'
474
  prediction_df.to_csv(predictions_file)
475
 
476
+ return {file_for_report: predictions_file,
477
+ run_state: False,
478
+ report_upload_flag: False}
479
  except Exception as e:
480
  gr.Warning(f"Prediction job failed due to error: {str(e)}")
481
  return {run_state: False}
 
663
  desc='Processing FASTA...').apply(
664
  lambda x: wrap_text(x) if not pd.isna(x) else x)
665
 
 
 
 
 
666
  num_cols = df_html.select_dtypes('number').columns
667
  num_col_colors = sns.color_palette('husl', len(num_cols))
668
  bool_cols = df_html.select_dtypes(bool).columns
669
  bool_col_colors = {True: 'lightgreen', False: 'lightpink'}
670
 
671
+ if columns_unique is not None:
672
+ unique_df = df_html.loc[:, columns_unique].iloc[[0]].copy()
673
+ df_html = df_html.loc[:, ~columns_unique]
674
+
675
  if not file:
676
  if 'Compound ID' in df_html.columns:
677
  df_html.drop(['Compound SMILES'], axis=1, inplace=True)
 
686
  styled_df = df_html.style.format(precision=3)
687
 
688
  for i, col in enumerate(num_cols):
689
+ if col in df_html.columns:
690
+ if col not in ['Predicted Binding Affinity', 'Actual Binding Affinity']:
691
+ styled_df = styled_df.background_gradient(
692
+ subset=[col], cmap=sns.light_palette(num_col_colors[i], as_cmap=True))
693
+ else:
694
+ styled_df = styled_df.background_gradient(
695
+ subset=[col], cmap=sns.light_palette(num_col_colors[i], as_cmap=True).reversed())
696
 
697
+ if any(df_html.columns.isin(bool_cols)):
698
+ styled_df.applymap(lambda val: f'background-color: {bool_col_colors[val]}', subset=bool_cols)
699
 
700
  table_html = styled_df.to_html()
701
  unique_html = ''
702
  if unique_df is not None:
703
+ if 'Target FASTA' in unique_df.columns:
704
+ unique_df['Target FASTA'] = unique_df['Target FASTA'].str.replace('\n', '<br>')
705
+ if any(unique_df.columns.isin(bool_cols)):
706
+ unique_df = unique_df.style.applymap(
707
+ lambda val: f"background-color: {bool_col_colors[val]}", subset=bool_cols)
708
+ unique_html = (f'<div style="font-family: Courier !important;">'
709
+ f'{unique_df.to_html(escape=False, index=False)}</div>')
710
 
711
  return (f'<div style="font-size: 16px; font-weight: bold;">{job} Report Preview (Top 30 Records)</div>'
712
+ f'<div style="overflow-x:auto; font-family: Courier !important;">{unique_html}</div>'
713
  f'<div style="overflow:auto; height: 300px; font-family: Courier !important;">{table_html}</div>')
714
 
715
  else:
716
+ bool_formatters = {col: BooleanFormatter() for col in bool_cols}
717
+ float_formatters = {col: NumberFormatter(format='0.000') for col in df_html.select_dtypes('floating').columns}
718
  other_formatters = {
719
  'Predicted Interaction Probability': {'type': 'progress', 'max': 1.0, 'legend': True},
720
  'Actual Interaction Probability': {'type': 'progress', 'max': 1.0, 'legend': True},
 
731
  template='<a href="https://pubchem.ncbi.nlm.nih.gov/compound/<%= value %>" '
732
  'target="_blank"><%= value %></a>')
733
  }
734
+ formatters = {**bool_formatters, **float_formatters, **other_formatters}
735
 
736
  # html = df.to_html(file)
737
  # return html
 
739
  report_table = pn.widgets.Tabulator(
740
  df_html, formatters=formatters,
741
  frozen_columns=['Index', 'Target ID', 'Compound ID', 'Compound', 'Scaffold'],
742
+ disabled=True, sizing_mode='stretch_both', pagination='local')
743
 
744
  for i, col in enumerate(num_cols):
745
  if col not in ['Predicted Binding Affinity', 'Actual Binding Affinity']:
 
769
  font-family: Courier New !important;
770
  font-weight: normal !important;
771
  font-size: 12px !important;
 
772
  }
773
 
774
  .tabulator-cell {
775
  overflow: visible !important;
776
  }
777
 
778
+ .tabulator-cell:hover {
779
+ z-index: 1000 !important;
780
  }
781
 
782
  .tabulator-cell.tabulator-frozen:hover {
783
  z-index: 1000 !important;
784
  }
785
 
 
 
 
 
786
  .image-zoom-viewer {
787
  display: inline-block;
788
+ overflow: visible;
789
+ z-index: 1000;
790
  }
791
 
792
  .image-zoom-viewer::after {
793
  content: "";
 
794
  top: 0;
795
  left: 0;
796
  width: 100%;
 
804
 
805
  /* When hovering over the container, scale its child (the SVG) */
806
  .tabulator-cell:hover .image-zoom-viewer svg {
807
+ padding: 3px;
808
+ position: absolute;
809
  background-color: rgba(250, 250, 250, 0.854);
810
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.618);
811
  border-radius: 3px;
812
+ transform: scale(3) translate(+38.2%, +38.2%); /* Scale up the SVG */
813
  transition: transform 0.3s ease;
814
  pointer-events: none; /* Prevents the SVG from blocking mouse interactions */
815
+ z-index: 1000;
816
  }
817
 
818
  .image-zoom-viewer svg {
 
838
  busy_indicator=None,
839
  )
840
 
841
+ stats_pane = pn.Row()
842
  if unique_df is not None:
843
+ unique_table = pn.widgets.Tabulator(unique_df, formatters=formatters, sizing_mode='stretch_width',
844
+ show_index=False, disabled=True,
845
+ frozen_columns=['Compound ID', 'Compound', 'Scaffold'])
846
+ # if pie_charts:
847
+ # unique_table.width = 640
848
+ stats_pane.append(pn.Column(f'### {unique_entity}', unique_table))
849
  if pie_charts:
850
  for score_name, figure_list in pie_charts.items():
851
+ stats_pane.append(
852
  pn.Column(f'### {category} by Top {score_name}',
853
  pn.Tabs(*figure_list, tabs_location='above'))
854
  # pn.Card(pn.Row(v), title=f'{category} by Top {k}')
855
  )
856
+
857
+ if stats_pane:
858
+ template.main.append(pn.Card(stats_pane,
859
  sizing_mode='stretch_width', title='Summary Statistics', margin=10))
860
 
861
  template.main.append(
 
875
  data = pd.DataFrame({category: category_counts.index, 'value': category_counts.values})
876
 
877
  data['proportion'] = data['value'] / data['value'].sum()
878
+ # Merge rows with proportion less than 0.2% into one row
879
+ mask = data['proportion'] < 0.002
880
+ if any(mask):
881
+ merged_row = data[mask].sum()
882
+ merged_row[category] = '...'
883
+ data = pd.concat([data[~mask], pd.DataFrame(merged_row).T])
884
  data['angle'] = data['proportion'] * 2 * pi
885
+
886
+ color_dict = {cat: color for cat, color in
887
+ zip(df[category].unique(),
888
+ (Category20c_20 * (len(df[category].unique()) // 20 + 1))[:len(df[category].unique())])}
889
+ color_dict['...'] = '#636363'
890
+ data['color'] = data[category].map(color_dict)
891
 
892
  tooltips = [
893
  (f"{category}", f"@{{{category}}}"),
 
899
  data = data.merge(top_k_df[['Scaffold SMILES', 'Scaffold']].drop_duplicates(), how='left',
900
  left_on='Scaffold SMILES', right_on='Scaffold SMILES')
901
  tooltips.append(("Scaffold", "<div>@{Scaffold}{safe}</div>"))
902
+ p = figure(height=384, width=960, name=f"Top {top_k}" if top_k < len(df) else 'All', sizing_mode='stretch_height',
903
+ toolbar_location=None, tools="hover", tooltips=tooltips, x_range=(-0.4, 0.4))
904
+
905
+ def truncate_label(label, max_length=60):
906
+ return label if len(label) <= max_length else label[:max_length] + "..."
907
+
908
+ data['legend_field'] = data[category].apply(truncate_label)
 
 
 
909
 
910
  p.add_layout(Legend(padding=0, margin=0), 'right')
911
  p.wedge(x=0, y=1, radius=0.3,
912
  start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
913
+ line_color="white", fill_color='color', legend_field='legend_field', source=data)
914
 
915
+ # Limit the number of legend items to 20 and add "..." if there are more than 20 items
 
 
 
 
916
  if len(p.legend.items) > 20:
917
+ new_legend_items = p.legend.items[:20]
918
+ new_legend_items.append(LegendItem(label="..."))
919
+ p.legend.items = new_legend_items
920
+
921
+ p.legend.label_text_font_size = "10pt"
922
+ p.legend.label_text_font="courier"
923
+ p.axis.axis_label = None
924
+ p.axis.visible = False
925
+ p.grid.grid_line_color = None
926
+ p.outline_line_width = 0
927
+ p.min_border = 0
928
+ p.margin = 0
929
 
930
  return p
931
 
 
1432
  The page shows only a preview report displaying at most 30 records
1433
  (with top predicted CPI/CPA if reporting results from a prediction job).
1434
 
1435
+ Please first `Preview` the report, then `Generate` and download a CSV report
1436
  or an interactive HTML report below if you wish to access the full report.
1437
  ''')
1438
  with gr.Row():
 
1865
  fn=submit_predict,
1866
  inputs=[screen_data_for_predict, drug_screen_task, drug_screen_preset,
1867
  drug_screen_target_family, screen_flag, run_state], # , drug_screen_email],
1868
+ outputs=[file_for_report, run_state, report_upload_flag]
1869
  ).then(
1870
  fn=lambda: [gr.Column(visible=True), gr.Markdown(visible=False), gr.Tabs(selected=3)],
1871
  outputs=[screen_page, screen_waiting, tabs]
 
1882
  fn=submit_predict,
1883
  inputs=[identify_data_for_predict, target_identify_task, target_identify_preset,
1884
  target_identify_target_family, identify_flag, run_state], # , target_identify_email],
1885
+ outputs=[file_for_report, run_state, report_upload_flag]
1886
  ).then(
1887
  fn=lambda: [gr.Column(visible=True), gr.Markdown(visible=False), gr.Tabs(selected=3)],
1888
  outputs=[identify_page, identify_waiting, tabs]
 
1899
  fn=submit_predict,
1900
  inputs=[infer_data_for_predict, pair_infer_task, pair_infer_preset,
1901
  pair_infer_target_family, infer_flag, run_state], # , pair_infer_email],
1902
+ outputs=[file_for_report, run_state, report_upload_flag]
1903
  ).then(
1904
  fn=lambda: [gr.Column(visible=True), gr.Markdown(visible=False), gr.Tabs(selected=3)],
1905
  outputs=[infer_page, infer_waiting, tabs]
 
1927
  else:
1928
  return {report_task: gr.Dropdown(visible=False)}
1929
 
1930
+ file_for_report.upload(
1931
+ fn=lambda: True, outputs=report_upload_flag
1932
+ )
1933
  file_for_report.change(fn=update_df, inputs=file_for_report, outputs=[
1934
  html_report, raw_df, report_df, analyze_btn]).success(
1935
  fn=lambda: [gr.Button(interactive=False)]*2 + [gr.File(visible=False)]*2 + [gr.Dropdown(visible=False)],
 
1938
  fn=inquire_task, inputs=[raw_df, report_upload_flag],
1939
  outputs=[report_task, html_report, analyze_btn, csv_generate, html_generate]
1940
  )
1941
+ file_for_report.clear(fn=lambda: [gr.Dropdown(visible=False, value=None), False],
1942
+ outputs=[report_task, report_upload_flag])
 
 
1943
 
1944
  analyze_btn.click(fn=submit_report, inputs=[raw_df, scores, filters, report_task], outputs=[
1945
  html_report, report_df, csv_download_file, html_download_file
 
1993
  # demo.load(None, None, None, js="() => {document.body.classList.remove('dark')}")
1994
 
1995
  if __name__ == "__main__":
1996
+ screen_block.queue(max_size=3)
1997
+ identify_block.queue(max_size=3)
1998
+ infer_block.queue(max_size=3)
1999
+ report.queue(max_size=3)
2000
 
2001
  # SCHEDULER.add_job(func=file_cleanup(), trigger="interval", seconds=60)
2002
  # SCHEDULER.start()