1- import flask
2- from flask import Flask , jsonify
1+ from gevent import monkey
2+ monkey .patch_all ()
3+
4+ from flask import Flask , jsonify , request
35from flask_restx import Api
46from flask_cors import CORS
57from model_generators .tunneling import Wave_Packet3D as t_wp , Animator3D as t_ani
68from model_generators .interference import Wave_Packet3D as i_wp , Animator3D as i_ani
79from model_generators .Qgate1 import Qgate1
810from model_generators .QuantumFourierTransform import QFTStepByStepODE
9- from model_generators .bloch import Bloch
1011import matplotlib .pyplot as plt
11- import time
1212import logging
1313from logging .handlers import RotatingFileHandler
1414import os
1515from db import MongoConnector
1616from flask_socketio import SocketIO , emit
1717from functools import wraps
1818
19+ sid = None
20+
21+ #set swagger info
22+ api : Api = Api (
23+ title = 'quantum_modeling' ,
24+ version = '1.0' ,
25+ description = 'v1.0' ,
26+ prefix = '/v1'
27+ )
28+
1929# Set up logging
2030log_dir = 'logs'
2131if not os .path .exists (log_dir ):
3141 backupCount = 5
3242)
3343file_handler .setFormatter (formatter )
34- file_handler .setLevel (logging .INFO )
44+ file_handler .setLevel (logging .DEBUG )
3545
3646console_handler = logging .StreamHandler ()
3747console_handler .setFormatter (formatter )
4252logger .addHandler (console_handler )
4353logger .setLevel (logging .DEBUG )
4454
45- # Add this after the logger setup
4655class SocketHandler (logging .Handler ):
47- def __init__ (self , socketio ):
56+ def __init__ (self ):
4857 super ().__init__ ()
49- self .socketio = socketio
50- # No need for formatter since we're only using the message
5158
5259 def emit (self , record ):
5360 try :
5461 # Only emit INFO level and above to avoid flooding the client
5562 if record .levelno >= logging .INFO :
56- self .socketio .emit ('status_update' , {'message' : record .getMessage ()})
57- except Exception :
58- self .handleError (record )
63+ global sid
64+ emit ('status_update' , {'message' : record .getMessage ()}, room = sid , namespace = '/' )
65+ except Exception as e :
66+ logger .error (f"Socket emission failed: { str (e )} " , exc_info = True )
5967
60- # Error handling decorator
6168def handle_errors (f ):
6269 @wraps (f )
6370 def wrapped (* args , ** kwargs ):
@@ -69,19 +76,11 @@ def wrapped(*args, **kwargs):
6976 return jsonify ({"error" : str (e )}), 500
7077 return wrapped
7178
72- #set swagger info
73- api : Api = Api (
74- title = 'quantum_modeling' ,
75- version = '1.0' ,
76- description = 'v1.0' ,
77- prefix = '/v1'
78- )
79-
8079app = Flask (__name__ )
8180api .init_app (app )
8281CORS (app , resources = {r"/*" : {"origins" : "*" }})
83- socketio = SocketIO (app , cors_allowed_origins = "*" )
84- socket_handler = SocketHandler (socketio )
82+ socketio = SocketIO (app , async_mode = 'gevent' , cors_allowed_origins = "*" , logger = True , engineio_logger = True )
83+ socket_handler = SocketHandler ()
8584socket_handler .setLevel (logging .INFO )
8685logger .addHandler (socket_handler )
8786mongo = MongoConnector ()
@@ -108,21 +107,18 @@ def Qtunneling(barrier, width, momentum):
108107 try :
109108 tunneling_model = mongo .get (t_collection , parameters )
110109 if not tunneling_model :
111- emit_status ('Generating tunneling model...' )
112110 plt .close ('all' )
113111 plt .switch_backend ('Agg' )
114112
115- emit_status ('Calculating tunneling model...' )
116113 animator = t_ani (t_wp (barrier_height = barrier , barrier_width = width , k0 = momentum ))
117114
118- emit_status ('Animating tunneling model...' )
119115 tunneling_model = animator .animate3D ()
120116
121- # Upload to MongoDB asynchronously after returning response
117+ # Upload to MongoDB asynchronously after emitting response
118+ emit_status (f"Generated new tunneling model with parameters: { parameters } " )
122119 socketio .start_background_task (mongo .upload , t_collection , parameters , tunneling_model )
123- logger .info (f"Generated new tunneling model with parameters: { parameters } " )
124120 else :
125- logger . info (f"Retrieved existing tunneling model with parameters: { parameters } " )
121+ emit_status (f"Retrieved existing tunneling model with parameters: { parameters } " )
126122 return tunneling_model
127123 except Exception as e :
128124 logger .error (f"Error generating tunneling model: { str (e )} " , exc_info = True )
@@ -154,9 +150,9 @@ def Qinterference(spacing, slit_separation, momentum):
154150 interference_model = animator .animate3D ()
155151
156152 socketio .start_background_task (mongo .upload , i_collection , parameters , interference_model )
157- logger . info (f"Generated new interference model with parameters: { parameters } " )
153+ emit_status (f"Generated new interference model with parameters: { parameters } " )
158154 else :
159- logger . info (f"Retrieved existing interference model with parameters: { parameters } " )
155+ emit_status (f"Retrieved existing interference model with parameters: { parameters } " )
160156 return interference_model
161157 except Exception as e :
162158 logger .error (f"Error generating interference model: { str (e )} " , exc_info = True )
@@ -193,7 +189,9 @@ def Qfouriertransform():
193189
194190@socketio .on ('connect' )
195191def handle_connect ():
196- logger .info ("Client connected" )
192+ global sid
193+ sid = request .sid
194+ logger .debug ("Client connected" )
197195 emit ('status_update' , {'message' : 'Connected to quantum model generator server' })
198196
199197@socketio .on ('disconnect' )
@@ -202,9 +200,9 @@ def handle_disconnect():
202200
203201@socketio .on ('message' )
204202def handle_message (data ):
205- logger .info (f"Received message: { data } " )
203+ logger .debug (f"Received message: { data } " )
206204
207205if __name__ == '__main__' :
208206 app .debug = True
209- logger .info ("Starting quantum modeling server" )
210- socketio .run (app , host = "0.0.0.0" , port = 3001 , debug = True )
207+ logger .debug ("Starting quantum modeling server" )
208+ socketio .run (app , host = "0.0.0.0" , port = 3001 , debug = False )
0 commit comments