import os import shlex import subprocess from typing import Tuple from flask import Flask, render_template_string, request app = Flask(__name__) ALLOWED_COMMANDS = { "status": ["openclaw", "status"], "onboard": ["openclaw", "onboard"], "gateway": ["openclaw", "gateway"], "tui": ["openclaw", "tui"], "dashboard": ["openclaw", "dashboard"], } HTML = """ OpenClaw Docker Space

OpenClaw Docker Space

Runs supported openclaw commands inside this Hugging Face Docker Space.
Only a fixed allowlist of commands can be run. Arbitrary shell execution is disabled.
{% for key in commands %} {% endfor %}
{% if executed %}

Executed

{{ executed }}

Exit code

{{ returncode }}

Output

{{ output }}
{% endif %} """ def normalize_custom_command(text: str): text = (text or "").strip() if not text: return None try: parts = shlex.split(text) except ValueError: return None for allowed in ALLOWED_COMMANDS.values(): if parts == allowed: return allowed return None def run_command(cmd: list[str]) -> Tuple[str, int]: env = os.environ.copy() env["PYTHONUNBUFFERED"] = "1" try: result = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=120, env=env, cwd="/app", ) return result.stdout, result.returncode except FileNotFoundError: return "Error: `openclaw` is not installed in the container.", 127 except subprocess.TimeoutExpired: return "Error: command timed out after 120 seconds.", 124 except Exception as e: return f"Unexpected error: {e}", 1 @app.route("/", methods=["GET", "POST"]) def index(): executed = "" output = "" returncode = "" if request.method == "POST": selected = request.form.get("command", "").strip() custom = request.form.get("custom_command", "").strip() cmd = None if selected in ALLOWED_COMMANDS: cmd = ALLOWED_COMMANDS[selected] elif custom: cmd = normalize_custom_command(custom) if cmd is None: executed = custom or selected or "(none)" output = ( "Rejected command.\n\n" "Allowed commands are:\n" + "\n".join(" ".join(v) for v in ALLOWED_COMMANDS.values()) ) returncode = 400 else: executed = " ".join(cmd) output, returncode = run_command(cmd) return render_template_string( HTML, commands=ALLOWED_COMMANDS.keys(), executed=executed, output=output, returncode=returncode, ) if __name__ == "__main__": port = int(os.environ.get("PORT", "7860")) app.run(host="0.0.0.0", port=port, debug=False)