I have a python BaseHTTPRequestHandler
class that is called by an HTTPServer
class. Basically the BaseHTTPRequestHandler
just runs a basic algorithm and then responds to a Get
request. The issue is that every time I do a Get
request, I get the correct response but all the gathered data in BaseHTTPRequestHandler
is reset as if each time a request is sent to the HTTPServer
it creates a new instance of BaseHTTPRequestHandler
. I can't find anything online that really explains what's going on behind the scenes. I've attached a simplified version of my code. Any help or explanation would be greatly appreciated.
Before anyone suggests creating a class or global variable, I am using a thread to create multiple instances of this class at once and doing so makes all the instances on each thread share and replace each other's data.
CODE (indentation off when copy and pasted)
BaseHTTPRequestHandler
This simplified version just keeps track of the number of alerts that have happened. The problem is that the count always resets to 0 when I call a Get
request as if the instance of the class is reset.
class SimulationServer(BaseHTTPRequestHandler):
def __init__(self, address, port, randomNumberMax, *args):
self.IP_ADDRESS = address
self.PORT = port
self.RANDOM_NUMBER_MAX = randomNumberMax
self.COUNT = 0
BaseHTTPRequestHandler.__init__(self, *args)
def do_GET(self):
if self.headers['Authorization'] == 'Basic ' + str(key):
print("send response")
self.do_HEAD()
randomNumberMax = self.RANDOM_NUMBER_MAX
response = ""
if randint(0, randomNumberMax) == 0:
self.generateAlert()
base_path = urlparse(self.path).path
print('base_path: ' + base_path)
if base_path == '/count':
response = self.getCount()
self.wfile.write(bytes(response, 'utf-8'))
def getCount(self):
count = self.COUNT
jsonString = '{"_sig": "","count": ' + str(count) + '}'
return jsonString
def generateAlert(self):
newAlert = {}
newAlert['siteId'] = "siteId"+ str(self.COUNT)
newAlert['mesg'] = "Simulated Alert"
newAlert['when'] = int(time.time())
self.COUNT += 1
HTTPServer
class CustomHTTPServer(HTTPServer):
key = ''
def __init__(self, address, handlerClass=SimulationServer):
super().__init__(address, handlerClass)
def set_auth(self, username, password):
self.key = base64.b64encode(
bytes('%s:%s' % (username, password), 'utf-8')).decode('ascii')
def get_auth_key(self):
return self.key
Main
This class creates the HTTPServer
and attaches the handler
class RunSimulator(object):
def run(self, alertFrequency=50, port=9000):
ipAddress="127.0.0.1"
def handler(*args):
SimulationServer(ipAddress, port, alertFrequency, *args)
simulationServer = CustomHTTPServer((ipAddress, port), handler)
simulationServer.set_auth('username', 'password')
try:
simulationServer.serve_forever()
except KeyboardInterrupt:
pass
simulationServer.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (ipAddress, port))
if __name__ == "__main__":
from sys import argv
simu = RunSimulator()
simu.run()
So the short answer is that it does create a new instance every time a request is sent.
BaseHTTPServer.HTTPServer
is a subclass of SocketServer.TCPServer
which itself is a subclass of SocketServer.BaseServer
. Every time a request comes in it will process the request process_request
and then call finish_request
. finish_request
will instantiate a fresh instance of whatever your request handler is.