GIGAParviz's picture
Update app.py
195ad08 verified
raw
history blame
6.89 kB
from flask import Flask, render_template, request, redirect, url_for, send_file, flash, jsonify
import os
import traceback
from pathlib import Path
import json
import pandas as pd
app = Flask(__name__)
app.secret_key = os.urandom(24)
try:
import main as project_main
except Exception as e:
project_main = None
import_error = traceback.format_exc()
else:
import_error = None
RESULTS_CSV = Path("results_flask.csv")
def safe_update_dict_from_json(orig_dict, json_text):
if not json_text or not json_text.strip():
return orig_dict
try:
new = json.loads(json_text)
if not isinstance(new, dict):
return orig_dict
d = orig_dict.copy()
d.update(new)
return d
except Exception:
return orig_dict
@app.route("/", methods=["GET"])
def index():
if project_main is None:
return render_template("index.html", import_error=import_error, project=None)
techs = list(project_main.TECHNOLOGY_DATA.keys())
defaults = {
"inflation": project_main.INFLATION_RATE,
"tax": project_main.TAX_RATE,
"years": project_main.PROJECT_YEARS,
"cap_min": project_main.OPTIMIZATION_SPACE['capacity_kta'][0],
"cap_max": project_main.OPTIMIZATION_SPACE['capacity_kta'][1],
"export_mix": project_main.OPTIMIZATION_SPACE['export_market_mix'][0],
"technology": "Engro_Pakistan", # FIX: default برای match IRR main.py
}
return render_template("index.html", import_error=None, project=project_main, techs=techs, defaults=defaults)
@app.route("/run", methods=["POST"])
def run():
if project_main is None:
flash("خطا: فایل main.py بارگزاری نشد. لطفاً لاگ را بررسی کنید.", "danger")
return redirect(url_for("index"))
try:
inflation_rate = float(request.form.get("inflation", project_main.INFLATION_RATE))
tax_rate = float(request.form.get("tax", project_main.TAX_RATE))
project_years = int(request.form.get("years", project_main.PROJECT_YEARS))
capacity_min = float(request.form.get("cap_min", project_main.OPTIMIZATION_SPACE['capacity_kta'][0]))
capacity_max = float(request.form.get("cap_max", project_main.OPTIMIZATION_SPACE['capacity_kta'][1]))
technology = request.form.get("technology", "Engro_Pakistan") # FIX: default Engro
export_mix = float(request.form.get("export_mix", project_main.OPTIMIZATION_SPACE['export_market_mix'][0]))
sell_byproducts = request.form.get("sell_byproducts") == "on"
tech_json = request.form.get("tech_json", "")
prices_json = request.form.get("prices_json", "")
except Exception as e:
flash("خطا در خواندن ورودی‌ها: " + str(e), "danger")
return redirect(url_for("index"))
try:
project_main.INFLATION_RATE = inflation_rate
project_main.TAX_RATE = tax_rate
project_main.PROJECT_YEARS = project_years
project_main.OPTIMIZATION_SPACE['capacity_kta'] = (capacity_min, capacity_max)
# FIX: هم‌خوانی با main.py (technology پرهزینه، sourcing صریح)
project_main.OPTIMIZATION_SPACE['technology'] = ["Engro_Pakistan", "Shin_Etsu_2004"] if technology not in ["Engro_Pakistan", "Shin_Etsu_2004"] else [technology]
project_main.OPTIMIZATION_SPACE['sourcing_strategy'] = ['Integrated_Production'] # FIX: صریح
project_main.OPTIMIZATION_SPACE['export_market_mix'] = (0.6, 0.8)
project_main.OPTIMIZATION_SPACE['sell_byproducts'] = [bool(sell_byproducts)]
project_main.TECHNOLOGY_DATA = safe_update_dict_from_json(project_main.TECHNOLOGY_DATA, tech_json)
project_main.PRODUCT_PRICES_USD_PER_TON = safe_update_dict_from_json(project_main.PRODUCT_PRICES_USD_PER_TON, prices_json)
except Exception as e:
flash("خطا در اعمال پارامترها: " + str(e), "danger")
return redirect(url_for("index"))
try:
flash("محاسبات شروع شد — صبر کنید تا عملیات به پایان برسد...", "info")
results = project_main.run_optimizations_without_ml()
df_results = pd.DataFrame(results).sort_values(by="irr", ascending=False).reset_index(drop=True)
df_results = df_results.round(2)
RESULTS_CSV = Path.cwd() / "results_flask.csv" # FIX: ذخیره در دایرکتوری فعلی
df_results.to_csv(RESULTS_CSV, index=False, encoding='utf-8-sig')
try:
project_main.display_and_save_results(df_results)
project_main.create_kpi_comparison_dashboard(df_results)
except Exception:
pass
if not df_results.empty:
best = df_results.iloc[0]
top_kpis = {
"irr": round(float(best['irr']), 2),
"annual_profit_M": round(float(best['annual_profit'])/1_000_000, 2),
"capex_M": round(float(best['total_capex'])/1_000_000, 2),
"payback": round(float(best['payback_period']), 2)
}
else:
top_kpis = None
charts_data = df_results.to_dict(orient="records")
flash("محاسبات با موفقیت تکمیل شد.", "success")
kpi_img = Path("static/images/kpi_dashboard.png") if Path("static/images/kpi_dashboard.png").exists() else None
tornado_img = Path("static/images/sensitivity_analysis_tornado.png") if Path("static/images/sensitivity_analysis_tornado.png").exists() else None
return render_template(
"index.html",
project=project_main,
techs=list(project_main.TECHNOLOGY_DATA.keys()),
defaults={"inflation": project_main.INFLATION_RATE, "tax": project_main.TAX_RATE},
table_html = df_results.to_html(
classes='table table-striped table-dark',
index=False,
justify='center',
float_format=lambda x: f"{x:.2f}"
),
top_kpis=top_kpis,
charts_json=json.dumps(charts_data, default=str),
kpi_img="images/kpi_dashboard.png" if kpi_img else None,
tornado_img="images/sensitivity_analysis_tornado.png" if tornado_img else None
)
except Exception as e:
tb = traceback.format_exc()
flash("خطا در اجرای الگوریتم‌ها. لاگ: " + str(e), "danger")
return render_template("index.html", import_error=tb, project=project_main)
@app.route("/download")
def download_results():
if RESULTS_CSV.exists():
return send_file(str(RESULTS_CSV), as_attachment=True)
flash("فایل نتایج آماده نیست.", "warning")
return redirect(url_for("index"))
if __name__ == "__main__":
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))