Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import json | |
| import os | |
| from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer | |
| from urllib.parse import urlparse | |
| from typing import Tuple | |
| from gridgent.core.orchestrator import GridGentOrchestrator | |
| from gridgent.tools.grid_stub import parse_uploaded_grid, save_uploaded_grid, get_all_feeders | |
| ORCHESTRATOR = GridGentOrchestrator() | |
| def _read_file(path: str) -> str: | |
| here = os.path.dirname(os.path.abspath(__file__)) | |
| full = os.path.join(here, "web", path) | |
| with open(full, "r", encoding="utf-8") as f: | |
| return f.read() | |
| class GridGentHandler(BaseHTTPRequestHandler): | |
| def _set_common_headers(self, status: int = 200, content_type: str = "text/html; charset=utf-8"): | |
| self.send_response(status) | |
| self.send_header("Content-Type", content_type) | |
| self.send_header("Access-Control-Allow-Origin", "*") | |
| self.send_header("Access-Control-Allow-Headers", "Content-Type") | |
| self.send_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") | |
| self.end_headers() | |
| def log_message(self, format, *args): | |
| return | |
| def do_OPTIONS(self): | |
| self._set_common_headers(200) | |
| def do_GET(self): | |
| parsed = urlparse(self.path) | |
| if parsed.path in ("/", "/index.html"): | |
| try: | |
| html = _read_file("index.html") | |
| self._set_common_headers(200, "text/html; charset=utf-8") | |
| self.wfile.write(html.encode("utf-8")) | |
| except FileNotFoundError: | |
| self._set_common_headers(500, "text/plain; charset=utf-8") | |
| self.wfile.write(b"index.html not found") | |
| elif parsed.path == "/api/feeders": | |
| data = get_all_feeders() | |
| self._set_common_headers(200, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps({"feeders": data}).encode("utf-8")) | |
| else: | |
| self._set_common_headers(404, "text/plain; charset=utf-8") | |
| self.wfile.write(b"Not Found") | |
| def _read_json(self) -> Tuple[bool, dict]: | |
| length = int(self.headers.get("Content-Length") or "0") | |
| try: | |
| body = self.rfile.read(length).decode("utf-8") | |
| data = json.loads(body) | |
| return True, data | |
| except Exception as exc: | |
| return False, {"error": f"Invalid JSON body: {exc}"} | |
| def do_POST(self): | |
| parsed = urlparse(self.path) | |
| if parsed.path == "/api/ask": | |
| ok, data = self._read_json() | |
| if not ok: | |
| self._set_common_headers(400, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps(data).encode("utf-8")) | |
| return | |
| query = str(data.get("query") or "").strip() | |
| if not query: | |
| self._set_common_headers(400, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps({"error": "Missing 'query' in request body"}).encode("utf-8")) | |
| return | |
| result = ORCHESTRATOR.run(query) | |
| resp = result.to_dict() | |
| self._set_common_headers(200, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps(resp).encode("utf-8")) | |
| elif parsed.path == "/api/upload-grid": | |
| ok, data = self._read_json() | |
| if not ok: | |
| self._set_common_headers(400, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps(data).encode("utf-8")) | |
| return | |
| raw = data.get("raw") | |
| fmt = data.get("format") | |
| if not raw or not fmt: | |
| self._set_common_headers(400, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps({"error": "Missing 'raw' or 'format' in request body"}).encode("utf-8")) | |
| return | |
| try: | |
| cfg = parse_uploaded_grid(str(raw), str(fmt)) | |
| save_uploaded_grid(cfg) | |
| feeders = list(cfg.get("feeders", {}).keys()) | |
| self._set_common_headers(200, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps({"status": "ok", "feeders_loaded": feeders}).encode("utf-8")) | |
| except Exception as exc: | |
| self._set_common_headers(400, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps({"error": str(exc)}).encode("utf-8")) | |
| else: | |
| self._set_common_headers(404, "application/json; charset=utf-8") | |
| self.wfile.write(json.dumps({"error": "Not Found"}).encode("utf-8")) | |
| def run_server(host: str = "0.0.0.0", port: int = 8000): | |
| server_address = (host, port) | |
| httpd = ThreadingHTTPServer(server_address, GridGentHandler) | |
| print(f"Grid-Gent demo server running at http://{host}:{port}") | |
| try: | |
| httpd.serve_forever() | |
| except KeyboardInterrupt: | |
| print("\nShutting down server...") | |
| finally: | |
| httpd.server_close() | |
| if __name__ == "__main__": | |
| port_str = os.environ.get("GRID_GENT_PORT", "8000") | |
| try: | |
| port = int(port_str) | |
| except ValueError: | |
| port = 8000 | |
| run_server(port=port) | |