Update app.py
Browse files
app.py
CHANGED
|
@@ -26,6 +26,7 @@ from functools import wraps
|
|
| 26 |
import plotly.graph_objects as go
|
| 27 |
import plotly.express as px
|
| 28 |
import tabulate
|
|
|
|
| 29 |
|
| 30 |
# ─────────────────────────────────────────────
|
| 31 |
# CACHE SYSTEM (TTL = 24 h)
|
|
@@ -73,84 +74,6 @@ def retry(max_attempts=3, delay=1):
|
|
| 73 |
return wrapper
|
| 74 |
return decorator
|
| 75 |
|
| 76 |
-
# ─────────────────────────────────────────────
|
| 77 |
-
# LAB JOURNAL (уніфікована система кодування S1)
|
| 78 |
-
# ─────────────────────────────────────────────
|
| 79 |
-
JOURNAL_FILE = "./lab_journal.csv"
|
| 80 |
-
JOURNAL_CATEGORIES = [
|
| 81 |
-
# S1-A Genomics
|
| 82 |
-
"S1-A·R1a", # Real Variant Lookup
|
| 83 |
-
"S1-A·R1b", # Variant Concepts
|
| 84 |
-
"S1-A·R2a", # Gray Zones Explorer
|
| 85 |
-
"S1-A·R2b", # Understudied Target Finder
|
| 86 |
-
"S1-A·R2c", # Literature Gap Finder
|
| 87 |
-
"S1-A·R2d", # Druggable Orphans
|
| 88 |
-
"S1-A·R2e", # Research Assistant
|
| 89 |
-
# S1-C Drug Discovery
|
| 90 |
-
"S1-C·R1a", # FGFR3 RNA Drug
|
| 91 |
-
"S1-C·R1b", # SL Drug Mapping
|
| 92 |
-
"S1-C·R2a", # m6A × Ferroptosis × Circadian
|
| 93 |
-
# S1-D LNP
|
| 94 |
-
"S1-D·R1a", # LNP Corona ML
|
| 95 |
-
"S1-D·R2a", # Flow Corona
|
| 96 |
-
"S1-D·R3a", # LNP Brain / BBB
|
| 97 |
-
"S1-D·R4a", # AutoCorona NLP
|
| 98 |
-
"S1-D·R5a", # CSF/Vitreous/BM
|
| 99 |
-
"S1-D·R6a", # Corona Database
|
| 100 |
-
# S1-E Biomarkers
|
| 101 |
-
"S1-E·R1a", # Liquid Biopsy Classifier
|
| 102 |
-
"S1-E·R1b", # Protein Panel Validator
|
| 103 |
-
"S1-E·R2a", # Multi-protein Biomarkers
|
| 104 |
-
# S1-F Rare Cancers
|
| 105 |
-
"S1-F·R1a", # DIPG Toolkit
|
| 106 |
-
"S1-F·R2a", # UVM Toolkit
|
| 107 |
-
"S1-F·R3a", # pAML Toolkit
|
| 108 |
-
# Learning Sandbox
|
| 109 |
-
"S1-B·R1a", # miRNA Explorer
|
| 110 |
-
"S1-B·R2a", # siRNA Targets
|
| 111 |
-
"S1-G·General", # 3D Models
|
| 112 |
-
"Manual"
|
| 113 |
-
]
|
| 114 |
-
|
| 115 |
-
def journal_log(category: str, action: str, result: str, note: str = ""):
|
| 116 |
-
"""Log an entry with category."""
|
| 117 |
-
ts = datetime.datetime.utcnow().isoformat()
|
| 118 |
-
row = [ts, category, action, result[:200], note]
|
| 119 |
-
write_header = not os.path.exists(JOURNAL_FILE)
|
| 120 |
-
with open(JOURNAL_FILE, "a", newline="") as f:
|
| 121 |
-
w = csv.writer(f)
|
| 122 |
-
if write_header:
|
| 123 |
-
w.writerow(["timestamp", "category", "action", "result_summary", "note"])
|
| 124 |
-
w.writerow(row)
|
| 125 |
-
return ts
|
| 126 |
-
|
| 127 |
-
def journal_read(category: str = "All") -> str:
|
| 128 |
-
"""Read journal entries, optionally filtered by category. Returns markdown."""
|
| 129 |
-
if not os.path.exists(JOURNAL_FILE):
|
| 130 |
-
return "No entries yet."
|
| 131 |
-
try:
|
| 132 |
-
df = pd.read_csv(JOURNAL_FILE)
|
| 133 |
-
if df.empty:
|
| 134 |
-
return "No entries yet."
|
| 135 |
-
if category != "All":
|
| 136 |
-
df = df[df["category"] == category]
|
| 137 |
-
if df.empty:
|
| 138 |
-
return f"No entries for category: {category}"
|
| 139 |
-
df_display = df[["timestamp", "category", "action", "result_summary"]].tail(50)
|
| 140 |
-
return df_display.to_markdown(index=False)
|
| 141 |
-
except Exception as e:
|
| 142 |
-
print(f"Journal read error: {e}")
|
| 143 |
-
return "Error reading journal."
|
| 144 |
-
|
| 145 |
-
def clear_journal():
|
| 146 |
-
try:
|
| 147 |
-
if os.path.exists(JOURNAL_FILE):
|
| 148 |
-
os.remove(JOURNAL_FILE)
|
| 149 |
-
return "Journal cleared."
|
| 150 |
-
except Exception as e:
|
| 151 |
-
print(f"Clear journal error: {e}")
|
| 152 |
-
return "Error clearing journal."
|
| 153 |
-
|
| 154 |
# ─────────────────────────────────────────────
|
| 155 |
# CONSTANTS
|
| 156 |
# ─────────────────────────────────────────────
|
|
|
|
| 26 |
import plotly.graph_objects as go
|
| 27 |
import plotly.express as px
|
| 28 |
import tabulate
|
| 29 |
+
from journal import journal_log, journal_read, clear_journal, JOURNAL_CATEGORIES
|
| 30 |
|
| 31 |
# ─────────────────────────────────────────────
|
| 32 |
# CACHE SYSTEM (TTL = 24 h)
|
|
|
|
| 74 |
return wrapper
|
| 75 |
return decorator
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
# ─────────────────────────────────────────────
|
| 78 |
# CONSTANTS
|
| 79 |
# ─────────────────────────────────────────────
|