Update app.py
Browse files
app.py
CHANGED
|
@@ -12,6 +12,8 @@ from typing import Optional, Tuple, Dict, Any
|
|
| 12 |
import logging
|
| 13 |
from datetime import datetime
|
| 14 |
import re
|
|
|
|
|
|
|
| 15 |
|
| 16 |
# Configure logging
|
| 17 |
logging.basicConfig(level=logging.INFO)
|
|
@@ -325,6 +327,11 @@ def create_basic_charts(df: pd.DataFrame) -> str:
|
|
| 325 |
fig.update_layout(height=400)
|
| 326 |
charts_html.append(fig.to_html(include_plotlyjs='cdn'))
|
| 327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
return "\n".join(charts_html) if charts_html else "<p>No charts generated for this dataset.</p>"
|
| 329 |
|
| 330 |
except Exception as e:
|
|
@@ -339,12 +346,12 @@ def clear_all():
|
|
| 339 |
"""Clear all inputs and outputs"""
|
| 340 |
return None, "", "", "", "", "", None
|
| 341 |
|
| 342 |
-
def download_summary(analysis_text, data_summary):
|
| 343 |
-
"""Generate downloadable summary report"""
|
| 344 |
if not analysis_text:
|
| 345 |
return None
|
| 346 |
|
| 347 |
-
|
| 348 |
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
| 349 |
|
| 350 |
## AI Analysis:
|
|
@@ -354,12 +361,34 @@ Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
| 354 |
{data_summary}
|
| 355 |
"""
|
| 356 |
|
| 357 |
-
|
| 358 |
-
filename =
|
| 359 |
-
|
| 360 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
|
| 362 |
-
|
|
|
|
|
|
|
| 363 |
|
| 364 |
# Create enhanced Gradio interface
|
| 365 |
with gr.Blocks(
|
|
@@ -467,7 +496,12 @@ with gr.Blocks(
|
|
| 467 |
|
| 468 |
with gr.Tab("💾 Export"):
|
| 469 |
gr.Markdown("### Download Your Analysis Report")
|
| 470 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
download_file = gr.File(label="Download Link", visible=False)
|
| 472 |
|
| 473 |
# Event handlers
|
|
@@ -494,7 +528,7 @@ with gr.Blocks(
|
|
| 494 |
ask_btn.click(
|
| 495 |
fn=sync_analyze_data,
|
| 496 |
inputs=[file_input, api_key_input, question_input],
|
| 497 |
-
outputs=[question_output, gr.Textbox(visible=False), gr.HTML(visible=False),
|
| 498 |
show_progress=True
|
| 499 |
)
|
| 500 |
|
|
@@ -515,7 +549,7 @@ with gr.Blocks(
|
|
| 515 |
# Download functionality
|
| 516 |
download_btn.click(
|
| 517 |
fn=download_summary,
|
| 518 |
-
inputs=[analysis_output, raw_summary],
|
| 519 |
outputs=[download_file]
|
| 520 |
)
|
| 521 |
|
|
@@ -541,5 +575,10 @@ with gr.Blocks(
|
|
| 541 |
if __name__ == "__main__":
|
| 542 |
app.queue(max_size=10) # Handle multiple users
|
| 543 |
app.launch(
|
| 544 |
-
share=True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
)
|
|
|
|
| 12 |
import logging
|
| 13 |
from datetime import datetime
|
| 14 |
import re
|
| 15 |
+
import markdown
|
| 16 |
+
from weasyprint import HTML as WeasyHTML
|
| 17 |
|
| 18 |
# Configure logging
|
| 19 |
logging.basicConfig(level=logging.INFO)
|
|
|
|
| 327 |
fig.update_layout(height=400)
|
| 328 |
charts_html.append(fig.to_html(include_plotlyjs='cdn'))
|
| 329 |
|
| 330 |
+
# Additional charts from generate_chart_data
|
| 331 |
+
charts_data = analyzer.generate_chart_data(df)
|
| 332 |
+
for key, fig in charts_data.items():
|
| 333 |
+
charts_html.append(fig.to_html(include_plotlyjs='cdn'))
|
| 334 |
+
|
| 335 |
return "\n".join(charts_html) if charts_html else "<p>No charts generated for this dataset.</p>"
|
| 336 |
|
| 337 |
except Exception as e:
|
|
|
|
| 346 |
"""Clear all inputs and outputs"""
|
| 347 |
return None, "", "", "", "", "", None
|
| 348 |
|
| 349 |
+
def download_summary(analysis_text, data_summary, format_choice):
|
| 350 |
+
"""Generate downloadable summary report in chosen format"""
|
| 351 |
if not analysis_text:
|
| 352 |
return None
|
| 353 |
|
| 354 |
+
report_md = f"""# Data Analysis Report
|
| 355 |
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
| 356 |
|
| 357 |
## AI Analysis:
|
|
|
|
| 361 |
{data_summary}
|
| 362 |
"""
|
| 363 |
|
| 364 |
+
base_filename = f"data_analysis_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
| 365 |
+
filename = None
|
| 366 |
+
|
| 367 |
+
try:
|
| 368 |
+
if format_choice == "PDF":
|
| 369 |
+
# Convert MD to HTML first
|
| 370 |
+
report_html = markdown.markdown(report_md)
|
| 371 |
+
# Wrap in basic HTML structure for better PDF rendering
|
| 372 |
+
full_html = f"""
|
| 373 |
+
<html>
|
| 374 |
+
<head><style>body {{ font-family: Arial, sans-serif; }}</style></head>
|
| 375 |
+
<body>{report_html}</body>
|
| 376 |
+
</html>
|
| 377 |
+
"""
|
| 378 |
+
filename = base_filename + ".pdf"
|
| 379 |
+
WeasyHTML(string=full_html).write_pdf(filename)
|
| 380 |
+
|
| 381 |
+
elif format_choice == "HTML":
|
| 382 |
+
report_html = markdown.markdown(report_md, output_format='html5')
|
| 383 |
+
filename = base_filename + ".html"
|
| 384 |
+
with open(filename, 'w', encoding='utf-8') as f:
|
| 385 |
+
f.write(report_html)
|
| 386 |
+
|
| 387 |
+
return filename
|
| 388 |
|
| 389 |
+
except Exception as e:
|
| 390 |
+
logger.error(f"Download generation error: {str(e)}")
|
| 391 |
+
return None
|
| 392 |
|
| 393 |
# Create enhanced Gradio interface
|
| 394 |
with gr.Blocks(
|
|
|
|
| 496 |
|
| 497 |
with gr.Tab("💾 Export"):
|
| 498 |
gr.Markdown("### Download Your Analysis Report")
|
| 499 |
+
format_choice = gr.Dropdown(
|
| 500 |
+
choices=["PDF", "HTML"],
|
| 501 |
+
label="Choose Format",
|
| 502 |
+
value="PDF"
|
| 503 |
+
)
|
| 504 |
+
download_btn = gr.Button("📥 Download Report", variant="secondary")
|
| 505 |
download_file = gr.File(label="Download Link", visible=False)
|
| 506 |
|
| 507 |
# Event handlers
|
|
|
|
| 528 |
ask_btn.click(
|
| 529 |
fn=sync_analyze_data,
|
| 530 |
inputs=[file_input, api_key_input, question_input],
|
| 531 |
+
outputs=[question_output, gr.Textbox(visible=False), gr.HTML(visible=False), charts_output], # Update charts on question too
|
| 532 |
show_progress=True
|
| 533 |
)
|
| 534 |
|
|
|
|
| 549 |
# Download functionality
|
| 550 |
download_btn.click(
|
| 551 |
fn=download_summary,
|
| 552 |
+
inputs=[analysis_output, raw_summary, format_choice],
|
| 553 |
outputs=[download_file]
|
| 554 |
)
|
| 555 |
|
|
|
|
| 575 |
if __name__ == "__main__":
|
| 576 |
app.queue(max_size=10) # Handle multiple users
|
| 577 |
app.launch(
|
| 578 |
+
share=True,
|
| 579 |
+
server_name="0.0.0.0",
|
| 580 |
+
server_port=7860,
|
| 581 |
+
show_error=True,
|
| 582 |
+
favicon_path=None,
|
| 583 |
+
ssl_verify=False
|
| 584 |
)
|