flask_apps/server.py

47 lines
1.4 KiB
Python

import importlib.util
import sys
from pathlib import Path
from flask import Flask, render_template_string
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.serving import run_simple
root = Flask(__name__)
@root.route("/")
def index():
apps = [
d.name for d in Path(__file__).parent.iterdir()
if d.is_dir() and (d / "app.py").exists()
]
links = "".join(f'<li><a href="/{a}">{a}</a></li>' for a in sorted(apps))
return render_template_string(f"""
<!DOCTYPE html><html><head><title>Tools</title></head>
<body>
<h1>Tools</h1>
<ul>{links}</ul>
</body></html>
""")
def load_sub_apps():
mounts = {}
base = Path(__file__).parent
for app_dir in sorted(base.iterdir()):
app_file = app_dir / "app.py"
if not app_dir.is_dir() or not app_file.exists():
continue
spec = importlib.util.spec_from_file_location(app_dir.name, app_file)
mod = importlib.util.module_from_spec(spec)
sys.modules[app_dir.name] = mod # must be registered before exec so Flask(__name__) resolves root_path correctly
spec.loader.exec_module(mod)
mounts[f"/{app_dir.name}"] = mod.app
print(f" mounted /{app_dir.name}")
return mounts
application = DispatcherMiddleware(root, load_sub_apps())
if __name__ == "__main__":
run_simple("0.0.0.0", 8080, application, use_reloader=False)