From 9c43e2721aa683c1dfab5dee56d10a9373193838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana?= Date: Fri, 9 Jun 2023 22:27:09 +0200 Subject: [PATCH] Begin adding sockets --- app/app.py | 10 +- app/env.dist | 2 +- app/{results => interactive}/forms.py | 4 +- app/interactive/main_interactive.py | 91 ++++++++++++++++ app/interactive/templates/iobase.html | 8 ++ app/interactive/templates/ranking.html | 144 +++++++++++++++++++++++++ app/results/main_results.py | 35 +----- app/results/templates/ranking.html | 13 --- app/static/.gitignore | 1 + app/templates/_nav.html | 2 +- requeriments.txt | 1 - requirements.txt | 8 ++ run.py | 3 +- 13 files changed, 269 insertions(+), 53 deletions(-) rename app/{results => interactive}/forms.py (63%) create mode 100644 app/interactive/main_interactive.py create mode 100644 app/interactive/templates/iobase.html create mode 100644 app/interactive/templates/ranking.html delete mode 100644 app/results/templates/ranking.html create mode 100644 app/static/.gitignore delete mode 100644 requeriments.txt create mode 100644 requirements.txt diff --git a/app/app.py b/app/app.py index f06521b..e5a8aac 100644 --- a/app/app.py +++ b/app/app.py @@ -2,11 +2,13 @@ from flask import Flask from flask_bootstrap import Bootstrap5 from flask_login import LoginManager +from flask_socketio import SocketIO from .config import Config from .models import User, db from .results.main_results import results from .admin.main_admin import admin + from .main import main bootstrap = Bootstrap5() @@ -36,6 +38,12 @@ def create_app(): app.register_blueprint(admin, url_prefix="/admin") app.register_blueprint(main) app.shell_context_processor(make_shell_context) + socketio = SocketIO(app) with app.app_context(): db.create_all() - return app + app.socket = socketio + from .interactive.main_interactive import interactive + + app.register_blueprint(interactive, url_prefix="/admin") + + return socketio, app diff --git a/app/env.dist b/app/env.dist index 3273d0c..6cebbe8 100644 --- a/app/env.dist +++ b/app/env.dist @@ -1 +1 @@ -COMPARE=True \ No newline at end of file +SECRET=Really-hard-to-guess-secret. \ No newline at end of file diff --git a/app/results/forms.py b/app/interactive/forms.py similarity index 63% rename from app/results/forms.py rename to app/interactive/forms.py index fa18845..67b793b 100644 --- a/app/results/forms.py +++ b/app/interactive/forms.py @@ -1,8 +1,10 @@ from flask_wtf import FlaskForm -from wtforms import SubmitField, SelectField +from wtforms import SubmitField, SelectField, TextAreaField from benchmark.Arguments import ALL_METRICS +##### NOT USED ##### class RankingForm(FlaskForm): score = SelectField("Score", choices=ALL_METRICS) + output = TextAreaField("Output") submit = SubmitField("Generate Ranking") diff --git a/app/interactive/main_interactive.py b/app/interactive/main_interactive.py new file mode 100644 index 0000000..f4e1404 --- /dev/null +++ b/app/interactive/main_interactive.py @@ -0,0 +1,91 @@ +import os +import shutil +from pathlib import Path +from flask import Blueprint, render_template, url_for, current_app +from benchmark.ResultsFiles import Benchmark +from flask_login import current_user, login_required + +interactive = Blueprint("interactive", __name__, template_folder="templates") + + +@interactive.route("/ranking") +@login_required +def ranking(): + os.chdir(current_user.benchmark.folder) + return render_template("ranking.html") + + +@current_app.socket.on("client") +def handle_client(message): + current_app.logger.info(message) + if message.get("action") == "ReadyToRock!": + get_benchmark(message.get("score"), excel=message.get("excel", False)) + current_app.socket.emit("server", {"message": "Ready!", "percentage": 0}) + + +def send_message(message, percentage, status="Ok", payload={}): + output = { + "message": message, + "percentage": percentage, + "status": status, + "payload": payload, + } + current_app.socket.emit("server", output) + + +def get_benchmark(score, excel=False): + def move_exreport(): + src = os.path.join( + current_user.benchmark.folder, "exreport", "exreport_output" + ) + dst = os.path.join( + current_app.static_folder, "exreport", "exreport_output" + ) + shutil.copytree(src, dst, dirs_exist_ok=True) + + benchmark = Benchmark(score=score, visualize=True) + send_message("Start", 0) + try: + send_message("Generating ranking...", 0) + benchmark.compile_results() + send_message("Saving results...", 20 if excel else 40) + benchmark.save_results() + send_message("Generating report...", 40 if excel else 60) + benchmark.report(tex_output=False) + send_message("Generating exreport...", 60 if excel else 80) + benchmark.exreport() + if excel: + send_message("Generating excel...", 80) + benchmark.excel() + except ValueError as e: + send_message( + "Error: Couldn't generate ranking. " + str(e), + percentage=100, + status="Error", + ) + return + except KeyError as e: + send_message( + "Couldn't generate ranking. It seems that there are " + "partial results for some classifierss. " + f"Key not found {str(e)}", + percentage=100, + status="Error", + ) + return + # copy the results to the static folder + move_exreport() + excel_payload = ( + "" if not excel else str(Path(benchmark.get_excel_file_name())) + ) + current_app.logger.info("excel_payload:" + excel_payload) + send_message( + "Done!", + 100, + payload={ + "excel": excel_payload, + "html": url_for( + "static", filename="exreport/exreport_output/report.html" + ), + }, + ) diff --git a/app/interactive/templates/iobase.html b/app/interactive/templates/iobase.html new file mode 100644 index 0000000..ee640fc --- /dev/null +++ b/app/interactive/templates/iobase.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} +{% block jscript %} + {{ super() }} + +{% endblock %} diff --git a/app/interactive/templates/ranking.html b/app/interactive/templates/ranking.html new file mode 100644 index 0000000..c69e6fb --- /dev/null +++ b/app/interactive/templates/ranking.html @@ -0,0 +1,144 @@ +{% extends "iobase.html" %} +{% block content %} + +{% endblock %} +{% block jscript %} + {{ super() }} + +{% endblock %} diff --git a/app/results/main_results.py b/app/results/main_results.py index 33c4e6d..8e65135 100644 --- a/app/results/main_results.py +++ b/app/results/main_results.py @@ -1,18 +1,16 @@ import json import os import shutil -from pathlib import Path import xlsxwriter from benchmark.Datasets import Datasets from benchmark.ResultsBase import StubReport -from benchmark.ResultsFiles import Benchmark, Excel, ReportDatasets +from benchmark.ResultsFiles import Excel, ReportDatasets from benchmark.Utils import Files, Folders from dotenv import dotenv_values from flask import ( Blueprint, current_app, - redirect, render_template, request, send_file, @@ -20,8 +18,6 @@ from flask import ( ) from flask_login import current_user, login_required -from .forms import RankingForm - results = Blueprint("results", __name__, template_folder="templates") @@ -235,32 +231,3 @@ def dataset_report(dataset): results=results, app_config=app_config, ) - - -@results.route("/ranking", methods=["GET", "POST"]) -@login_required -def ranking(): - os.chdir(current_user.benchmark.folder) - form = RankingForm() - if form.validate_on_submit(): - benchmark = Benchmark(score=form.score.data, visualize=False) - try: - benchmark.compile_results() - benchmark.save_results() - benchmark.report(tex_output=False) - benchmark.exreport() - benchmark.excel() - except ValueError as e: - return render_template( - "error.html", message="Couldn't generate ranking", error=str(e) - ) - except KeyError as e: - return render_template( - "error.html", - message="Couldn't generate ranking. It seems that there are " - "partial results for some classifiers", - error=f"Key not found {str(e)}", - ) - file_name = Path(benchmark.get_excel_file_name()).name - return redirect(url_for("results.download", file_name=file_name)) - return render_template("ranking.html", form=form) diff --git a/app/results/templates/ranking.html b/app/results/templates/ranking.html deleted file mode 100644 index d9eb8d4..0000000 --- a/app/results/templates/ranking.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "base.html" %} -{% from 'bootstrap5/form.html' import render_form %} -{% block content %} - -{% endblock %} -``` diff --git a/app/static/.gitignore b/app/static/.gitignore new file mode 100644 index 0000000..788255d --- /dev/null +++ b/app/static/.gitignore @@ -0,0 +1 @@ +exreport/** \ No newline at end of file diff --git a/app/templates/_nav.html b/app/templates/_nav.html index 8f1d564..8730dfd 100644 --- a/app/templates/_nav.html +++ b/app/templates/_nav.html @@ -20,7 +20,7 @@
  • {{ render_nav_item('results.select', 'Results') }}
  • {{ render_nav_item('results.datasets', 'Datasets') }}
  • -
  • {{ render_nav_item('results.ranking', 'Ranking') }}
  • +
  • {{ render_nav_item('interactive.ranking', 'Ranking') }}
  • {{ render_nav_item('main.config', 'Config') }}
  • {% endif %} diff --git a/requeriments.txt b/requeriments.txt deleted file mode 100644 index c337b9b..0000000 --- a/requeriments.txt +++ /dev/null @@ -1 +0,0 @@ -email-validator diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..59fb6ed --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +flask +flask-login +bootstrap-flask +flask-sqlalchemy +flask-socketio +flask-wtf +simple-websocket +email-validator diff --git a/run.py b/run.py index 20cdaa4..b714525 100644 --- a/run.py +++ b/run.py @@ -1,3 +1,4 @@ from app import app -app.create_app().run(debug=True) +socketio, app = app.create_app() +socketio.run(app, debug=True)