Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,26 +6,34 @@ from datetime import datetime
|
|
| 6 |
from reportlab.lib.pagesizes import letter
|
| 7 |
from reportlab.pdfgen import canvas
|
| 8 |
|
|
|
|
|
|
|
| 9 |
# ----------------------------
|
| 10 |
-
# Load Logs
|
| 11 |
# ----------------------------
|
| 12 |
def load_logs(file_obj):
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
'
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
# ----------------------------
|
| 31 |
# Summarize Log Data
|
|
@@ -49,11 +57,10 @@ def generate_chart(df):
|
|
| 49 |
return fig
|
| 50 |
|
| 51 |
# ----------------------------
|
| 52 |
-
# Export PDF
|
| 53 |
# ----------------------------
|
| 54 |
def export_pdf(df):
|
| 55 |
summary = summarize_logs(df)
|
| 56 |
-
|
| 57 |
buffer = io.BytesIO()
|
| 58 |
pdf = canvas.Canvas(buffer, pagesize=letter)
|
| 59 |
width, height = letter
|
|
@@ -73,12 +80,10 @@ def export_pdf(df):
|
|
| 73 |
pdf.setFont("Helvetica", 10)
|
| 74 |
|
| 75 |
for (lab, dev_type), row in summary.iterrows():
|
| 76 |
-
ok = int(row.get('OK', 0))
|
| 77 |
-
down = int(row.get('DOWN', 0))
|
| 78 |
pdf.drawString(50, y, str(lab))
|
| 79 |
pdf.drawString(150, y, str(dev_type))
|
| 80 |
-
pdf.drawString(300, y, str(
|
| 81 |
-
pdf.drawString(350, y, str(
|
| 82 |
y -= 20
|
| 83 |
if y < 50:
|
| 84 |
pdf.showPage()
|
|
@@ -89,29 +94,42 @@ def export_pdf(df):
|
|
| 89 |
return ("LabOps_Summary.pdf", buffer.read())
|
| 90 |
|
| 91 |
# ----------------------------
|
| 92 |
-
#
|
| 93 |
# ----------------------------
|
| 94 |
def dashboard(file_obj):
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
| 98 |
|
|
|
|
|
|
|
|
|
|
| 99 |
def generate_pdf_button(file_obj):
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
|
|
|
|
|
|
|
|
|
|
| 103 |
with gr.Blocks() as demo:
|
| 104 |
gr.Markdown("## 🧪 LabOps Dashboard")
|
| 105 |
-
gr.Markdown("
|
| 106 |
|
| 107 |
with gr.Row():
|
| 108 |
file_input = gr.File(label="Upload Log CSV", file_types=[".csv"])
|
| 109 |
download_button = gr.Button("Download PDF Summary")
|
| 110 |
-
download_file = gr.File(label="Download PDF", visible=
|
| 111 |
|
| 112 |
plot_output = gr.Plot()
|
|
|
|
| 113 |
|
| 114 |
file_input.change(fn=dashboard, inputs=file_input, outputs=plot_output)
|
| 115 |
-
download_button.click(fn=generate_pdf_button, inputs=file_input, outputs=download_file)
|
| 116 |
|
| 117 |
demo.launch()
|
|
|
|
| 6 |
from reportlab.lib.pagesizes import letter
|
| 7 |
from reportlab.pdfgen import canvas
|
| 8 |
|
| 9 |
+
REQUIRED_COLUMNS = ['DeviceID', 'Lab', 'Type', 'Timestamp', 'Status', 'UsageCount']
|
| 10 |
+
|
| 11 |
# ----------------------------
|
| 12 |
+
# Load Logs Safely
|
| 13 |
# ----------------------------
|
| 14 |
def load_logs(file_obj):
|
| 15 |
+
try:
|
| 16 |
+
if file_obj is not None:
|
| 17 |
+
content = file_obj.read().decode('utf-8')
|
| 18 |
+
df = pd.read_csv(io.StringIO(content))
|
| 19 |
+
if not all(col in df.columns for col in REQUIRED_COLUMNS):
|
| 20 |
+
raise ValueError(f"CSV must contain columns: {', '.join(REQUIRED_COLUMNS)}")
|
| 21 |
+
df['Timestamp'] = pd.to_datetime(df['Timestamp'], errors='coerce')
|
| 22 |
+
df.dropna(subset=['Timestamp'], inplace=True)
|
| 23 |
+
else:
|
| 24 |
+
df = pd.DataFrame({
|
| 25 |
+
'DeviceID': ['D001', 'D002', 'D003'],
|
| 26 |
+
'Lab': ['Lab A', 'Lab B', 'Lab A'],
|
| 27 |
+
'Type': ['UV', 'Weight', 'Cell'],
|
| 28 |
+
'Timestamp': [pd.Timestamp('2025-06-01 09:00:00'),
|
| 29 |
+
pd.Timestamp('2025-06-01 10:00:00'),
|
| 30 |
+
pd.Timestamp('2025-06-01 11:00:00')],
|
| 31 |
+
'Status': ['OK', 'DOWN', 'OK'],
|
| 32 |
+
'UsageCount': [120, 85, 100]
|
| 33 |
+
})
|
| 34 |
+
return df
|
| 35 |
+
except Exception as e:
|
| 36 |
+
raise ValueError(f"Failed to load CSV: {e}")
|
| 37 |
|
| 38 |
# ----------------------------
|
| 39 |
# Summarize Log Data
|
|
|
|
| 57 |
return fig
|
| 58 |
|
| 59 |
# ----------------------------
|
| 60 |
+
# Export PDF using ReportLab
|
| 61 |
# ----------------------------
|
| 62 |
def export_pdf(df):
|
| 63 |
summary = summarize_logs(df)
|
|
|
|
| 64 |
buffer = io.BytesIO()
|
| 65 |
pdf = canvas.Canvas(buffer, pagesize=letter)
|
| 66 |
width, height = letter
|
|
|
|
| 80 |
pdf.setFont("Helvetica", 10)
|
| 81 |
|
| 82 |
for (lab, dev_type), row in summary.iterrows():
|
|
|
|
|
|
|
| 83 |
pdf.drawString(50, y, str(lab))
|
| 84 |
pdf.drawString(150, y, str(dev_type))
|
| 85 |
+
pdf.drawString(300, y, str(int(row.get('OK', 0))))
|
| 86 |
+
pdf.drawString(350, y, str(int(row.get('DOWN', 0))))
|
| 87 |
y -= 20
|
| 88 |
if y < 50:
|
| 89 |
pdf.showPage()
|
|
|
|
| 94 |
return ("LabOps_Summary.pdf", buffer.read())
|
| 95 |
|
| 96 |
# ----------------------------
|
| 97 |
+
# Dashboard Display
|
| 98 |
# ----------------------------
|
| 99 |
def dashboard(file_obj):
|
| 100 |
+
try:
|
| 101 |
+
df = load_logs(file_obj)
|
| 102 |
+
return generate_chart(df)
|
| 103 |
+
except Exception as e:
|
| 104 |
+
return gr.update(visible=True), gr.Textbox.update(value=f"❌ Error: {e}", visible=True)
|
| 105 |
|
| 106 |
+
# ----------------------------
|
| 107 |
+
# PDF Generator
|
| 108 |
+
# ----------------------------
|
| 109 |
def generate_pdf_button(file_obj):
|
| 110 |
+
try:
|
| 111 |
+
df = load_logs(file_obj)
|
| 112 |
+
filename, pdf_bytes = export_pdf(df)
|
| 113 |
+
return gr.File.update(value=(filename, pdf_bytes), visible=True)
|
| 114 |
+
except Exception as e:
|
| 115 |
+
return gr.File.update(visible=False), gr.Textbox.update(value=f"❌ Error: {e}", visible=True)
|
| 116 |
|
| 117 |
+
# ----------------------------
|
| 118 |
+
# Gradio Interface
|
| 119 |
+
# ----------------------------
|
| 120 |
with gr.Blocks() as demo:
|
| 121 |
gr.Markdown("## 🧪 LabOps Dashboard")
|
| 122 |
+
gr.Markdown("Upload lab device logs to visualize uptime/downtime & generate PDF reports.")
|
| 123 |
|
| 124 |
with gr.Row():
|
| 125 |
file_input = gr.File(label="Upload Log CSV", file_types=[".csv"])
|
| 126 |
download_button = gr.Button("Download PDF Summary")
|
| 127 |
+
download_file = gr.File(label="Download PDF", visible=False)
|
| 128 |
|
| 129 |
plot_output = gr.Plot()
|
| 130 |
+
error_output = gr.Textbox(visible=False, label="Errors")
|
| 131 |
|
| 132 |
file_input.change(fn=dashboard, inputs=file_input, outputs=plot_output)
|
| 133 |
+
download_button.click(fn=generate_pdf_button, inputs=file_input, outputs=[download_file, error_output])
|
| 134 |
|
| 135 |
demo.launch()
|