#!/usr/bin/env python3 """ Ensemble Interface Server - HTTP API for ensemble_gen1000 Auto-generated. Do not edit directly. Usage: python server.py # Start on default port 8765 python server.py --port 9000 # Custom port Double-click launch.bat to start server. """ import sys import json import argparse from pathlib import Path from http.server import HTTPServer, BaseHTTPRequestHandler from urllib.parse import parse_qs, urlparse # Add model directory to path MODEL_PATH = r"F:\folder\key\children\ensemble_gen1000.py" sys.path.insert(0, str(Path(MODEL_PATH).parent)) # Import the model import importlib.util spec = importlib.util.spec_from_file_location("model", MODEL_PATH) model_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(model_module) # Create ensemble instance ENSEMBLE = model_module.EnsembleAgent(observe=False) class ModelHandler(BaseHTTPRequestHandler): """HTTP handler for ensemble actions.""" def _send_json(self, data, status=200): self.send_response(status) self.send_header("Content-Type", "application/json") self.send_header("Access-Control-Allow-Origin", "*") self.end_headers() self.wfile.write(json.dumps(data).encode()) def do_OPTIONS(self): """Handle CORS preflight.""" self.send_response(200) self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type") self.end_headers() def do_GET(self): parsed = urlparse(self.path) path = parsed.path if path == "/manifest": manifest = json.loads(Path("manifest.json").read_text()) self._send_json(manifest) elif path == "/info": self._send_json({ "ensemble_size": len(ENSEMBLE.organisms), "best_id": ENSEMBLE.get_best()["id"], "best_fitness": ENSEMBLE.get_best()["fitness"], "inference_count": ENSEMBLE._inference_count, }) elif path == "/readme": self._send_json({"readme": ENSEMBLE.get_readme()}) elif path == "/provenance": self._send_json(ENSEMBLE.get_full_provenance()) elif path == "/capabilities": self._send_json({ "endpoints": [ {"path": "/forward", "method": "POST", "desc": "Run ensemble inference"}, {"path": "/export_pt", "method": "POST", "desc": "Export to PyTorch"}, {"path": "/export_onnx", "method": "POST", "desc": "Export to ONNX"}, {"path": "/bridge", "method": "POST", "desc": "Data bridging"}, {"path": "/info", "method": "GET", "desc": "Model info"}, {"path": "/provenance", "method": "GET", "desc": "Full provenance"}, ] }) elif path == "/health": self._send_json({"status": "ok", "ensemble_size": len(ENSEMBLE.organisms)}) else: self._send_json({"error": "Unknown endpoint"}, 404) def do_POST(self): parsed = urlparse(self.path) path = parsed.path content_length = int(self.headers.get("Content-Length", 0)) body_raw = self.rfile.read(content_length).decode() if content_length else "{}" params = json.loads(body_raw) if body_raw else {} try: if path == "/forward": result = ENSEMBLE.forward( params.get("inputs"), params.get("strategy", "fitness_weighted") ) self._send_json({"result": _serialize(result)}) elif path == "/export_pt": export_path = params.get("path", "ensemble.pt") ENSEMBLE.export_pt(export_path) self._send_json({"status": "ok", "path": export_path}) elif path == "/export_onnx": export_path = params.get("path", "ensemble.onnx") ENSEMBLE.export_onnx(export_path) self._send_json({"status": "ok", "path": export_path}) elif path == "/bridge": bridge = ENSEMBLE.get_bridge() result = bridge.bridge(params["old_form"], params["new_form"]) self._send_json({"result": result}) elif path == "/hold/toggle": # Causation Hold toggle self._send_json({"enabled": True}) elif path == "/hold/state": # Causation Hold state self._send_json({"enabled": False, "paused": False}) else: self._send_json({"error": "Unknown action"}, 404) except Exception as e: self._send_json({"error": str(e)}, 500) def log_message(self, format, *args): print(f"[Server] {args[0]}") def _serialize(obj): """Make object JSON-serializable.""" import numpy as np if isinstance(obj, np.ndarray): return obj.tolist() if isinstance(obj, dict): return {k: _serialize(v) for k, v in obj.items()} if isinstance(obj, (list, tuple)): return [_serialize(v) for v in obj] if hasattr(obj, "item"): return obj.item() return obj if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--port", type=int, default=8765) parser.add_argument("--host", default="127.0.0.1") args = parser.parse_args() print() print("=" * 60) print(f" ENSEMBLE INTERFACE SERVER - ensemble_gen1000") print("=" * 60) print(f" Serving on http://{args.host}:{args.port}") print(f" Model: {MODEL_PATH}") print() print(" Endpoints:") print(" GET /manifest - Model manifest") print(" GET /info - Current state") print(" GET /provenance - Full provenance chain") print(" GET /health - Health check") print(" POST /forward - Run inference") print(" POST /export_pt - Export to PyTorch") print(" POST /export_onnx - Export to ONNX") print(" POST /bridge - Data bridging") print() print(" Press Ctrl+C to stop") print("=" * 60) print() server = HTTPServer((args.host, args.port), ModelHandler) try: server.serve_forever() except KeyboardInterrupt: print("\nShutting down...")