Pathl.Stona/app.py
2026-01-30 13:33:51 +01:00

145 lines
4.4 KiB
Python

from flask import Flask, request, render_template, jsonify, send_from_directory
import os, json, importlib.util
from werkzeug.utils import secure_filename
import markdown
app = Flask(__name__)
UPLOAD_FOLDER = "models"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
ADMIN_KEY = "supersecretadminkey"
MODELS = {}
def load_models():
for folder in os.listdir(UPLOAD_FOLDER):
path = os.path.join(UPLOAD_FOLDER, folder)
if not os.path.isdir(path):
continue
meta_path = os.path.join(path, "meta.json")
if not os.path.exists(meta_path):
continue
with open(meta_path) as f:
meta = json.load(f)
func_name = meta.get("function_name")
if not func_name:
continue
py_file = os.path.join(path, "model.py")
spec = importlib.util.spec_from_file_location("model_module", py_file)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
func = getattr(module, func_name)
MODELS[folder] = {
"func": func,
"inputs": meta.get("inputs", []),
"meta": meta,
"path": path
}
load_models()
# ---- DASHBOARD ----
@app.route("/")
def dashboard():
models_with_md = {}
for name, model in MODELS.items():
md_content = ""
try:
md_path = os.path.join(model["path"], model["meta"]["description_file"])
with open(md_path, "r", encoding="utf-8") as f:
md_text = f.read()
# konwersja Markdown -> HTML
md_content = markdown.markdown(md_text)
except Exception:
md_content = "<p>Brak opisu.</p>"
models_with_md[name] = {**model, "md_content": md_content}
return render_template("user.html", models=models_with_md)
# ---- PREDICT ----
@app.route("/predict/<model_name>", methods=["POST"])
def predict(model_name):
model_entry = MODELS.get(model_name)
if not model_entry:
return jsonify({"output": "Model nie istnieje"}), 404
func = model_entry["func"]
inputs = model_entry["inputs"]
kwargs = {}
for inp in inputs:
kwargs[inp] = request.form.get(inp)
try:
for k in kwargs:
try:
kwargs[k] = float(kwargs[k])
except:
pass
output = func(**kwargs)
except Exception as e:
output = str(e)
return jsonify({"output": str(output)})
# ---- ADD MODEL ----
@app.route("/add_model", methods=["POST"])
def add_model():
admin_key = request.form.get("admin_key")
if admin_key != ADMIN_KEY:
return "Brak dostępu", 403
name = request.form["name"]
function_name = request.form["function_name"]
inputs = request.form.getlist("inputs")
model_py = request.files["model_py"]
description_file = request.files["description"]
folder_name = secure_filename(name)
folder_path = os.path.join(UPLOAD_FOLDER, folder_name)
os.makedirs(folder_path, exist_ok=True)
# zapis plików
model_py.save(os.path.join(folder_path, "model.py"))
description_file.save(os.path.join(folder_path, "description.md"))
# meta.json
meta = {
"name": name,
"function_name": function_name,
"inputs": inputs,
"description_file": "description.md",
"downloadable": True, # można pobrać pliki
"type": request.form.get("type", "algorithmic")
}
with open(os.path.join(folder_path, "meta.json"), "w") as f:
json.dump(meta, f)
# załaduj od razu
spec = importlib.util.spec_from_file_location("model_module", os.path.join(folder_path, "model.py"))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
func = getattr(module, function_name)
MODELS[folder_name] = {
"func": func,
"inputs": inputs,
"meta": meta,
"path": folder_path
}
return "Dodano model!"
# ---- DOWNLOAD FILE ----
@app.route("/download/<model_name>/<file_name>")
def download_file(model_name, file_name):
model_entry = MODELS.get(model_name)
if not model_entry:
return "Model nie istnieje", 404
folder_path = model_entry["path"]
if file_name not in ["model.py", "description.md", "meta.json"]:
return "Nieprawidłowy plik", 400
return send_from_directory(folder_path, file_name, as_attachment=True)
if __name__ == "__main__":
app.run(debug=True)