()
| 38 | |
| 39 | @app.route("/api/setup", methods=["POST"]) |
| 40 | def setup(): |
| 41 | data = request.get_json() |
| 42 | openai_key = (data.get("openai_api_key") or "").strip() |
| 43 | firecrawl_key = (data.get("firecrawl_api_key") or "").strip() |
| 44 | |
| 45 | if not openai_key: |
| 46 | return jsonify({"error": "OPENAI_API_KEY is required"}), 400 |
| 47 | |
| 48 | # Basic format validation |
| 49 | if not openai_key.startswith("sk-"): |
| 50 | return jsonify({"error": "OPENAI_API_KEY should start with 'sk-'"}), 400 |
| 51 | |
| 52 | try: |
| 53 | _update_env_key(VM_ENV_PATH, "OPENAI_API_KEY", openai_key) |
| 54 | if firecrawl_key: |
| 55 | _update_env_key(VM_ENV_PATH, "FIRECRAWL_API_KEY", firecrawl_key) |
| 56 | |
| 57 | # Create sentinel to disable this portal on next boot |
| 58 | open(SETUP_SENTINEL, "w").close() |
| 59 | |
| 60 | # Start the main services in background, then stop ourselves |
| 61 | subprocess.Popen( |
| 62 | [ |
| 63 | "bash", "-c", |
| 64 | "sudo systemctl start sandbox-vm.service && " |
| 65 | "sudo systemctl start ai-scientists-web.service && " |
| 66 | "sleep 2 && " |
| 67 | "sudo systemctl stop ai-scientists-setup.service" |
| 68 | ], |
| 69 | stdout=subprocess.DEVNULL, |
| 70 | stderr=subprocess.DEVNULL, |
| 71 | ) |
| 72 | |
| 73 | return jsonify({ |
| 74 | "status": "ok", |
| 75 | "message": "API keys saved. Starting AI Scientists Web UI... " |
| 76 | "The page will redirect in ~30 seconds." |
| 77 | }) |
| 78 | |
| 79 | except Exception as e: |
| 80 | return jsonify({"error": str(e)}), 500 |
| 81 | |
| 82 | |
| 83 | if __name__ == "__main__": |
nothing calls this directly
no test coverage detected