import http.server import urllib.parse import numpy as np import plotly.graph_objects as go import sys import os import multiprocessing import signal import atexit PORT = 8000 pid_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'server.pid') html_form = ''' Sinusoidal Plot




{plot} ''' class PlotlyHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write(html_form.format(plot='').encode('utf-8')) def do_POST(self): content_length = int(self.headers['Content-Length']) post_data = self.rfile.read(content_length) params = urllib.parse.parse_qs(post_data.decode('utf-8')) a = float(params.get('a', [1])[0]) w = float(params.get('w', [10])[0]) tmin = float(params.get('tmin', [0])[0]) tmax = float(params.get('tmax', [10])[0]) tstep = 0.1 t = np.arange(tmin, tmax + tstep, tstep) y = a * np.sin(w * t) fig = go.Figure() fig.add_trace(go.Scatter(x=t, y=y, mode='lines', name='sinusoidal')) fig.update_layout(title='Sinusoidal Plot', xaxis_title='Time (t)', yaxis_title='Amplitude (a*sin(w*t))') plot_html = fig.to_html(full_html=False) self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write(html_form.format(plot=plot_html).encode('utf-8')) def run_cgi(): post_data = sys.stdin.read() params = urllib.parse.parse_qs(post_data) a = float(params.get('a', [1])[0]) w = float(params.get('w', [10])[0]) tmin = float(params.get('tmin', [0])[0]) tmax = float(params.get('tmax', [10])[0]) tstep = 0.1 t = np.arange(tmin, tmax + tstep, tstep) y = a * np.sin(w * t) fig = go.Figure() fig.add_trace(go.Scatter(x=t, y=y, mode='lines', name='sinusoidal')) fig.update_layout(title='Sinusoidal Plot', xaxis_title='Time (t)', yaxis_title='Amplitude (a*sin(w*t))') plot_html = fig.to_html(full_html=False) print("Content-Type: text/html\n") print(html_form.format(plot=plot_html)) def start_server(): server = http.server.HTTPServer(('0.0.0.0', PORT), PlotlyHandler) print(f"Server running on port {PORT}") signal.signal(signal.SIGTERM, handle_exit) signal.signal(signal.SIGINT, handle_exit) server.serve_forever() def handle_exit(*args): if os.path.exists(pid_file_path): os.remove(pid_file_path) print("Clean exit: pid_file removed") sys.exit(0) def stop_server(): if os.path.exists(pid_file_path): with open(pid_file_path, 'r') as f: pid = int(f.read().strip()) try: os.kill(pid, signal.SIGTERM) os.remove(pid_file_path) print("Server stopped") except OSError: print("Error stopping server") else: print("Server is not running") def run_server_process(): process = multiprocessing.Process(target=start_server) process.start() with open(pid_file_path, 'w') as f: f.write(str(process.pid)) print(f"Server started with PID {process.pid}") if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: python server.py [start|stop|run]") sys.exit(1) mode = sys.argv[1] if mode == 'start': atexit.register(handle_exit) run_server_process() elif mode == 'stop': stop_server() elif mode == 'run': run_cgi() else: print("Unknown mode:", mode) sys.exit(1)