Search code examples
pythonhttpserverbasehttpserver

How to access RequestHandlerClass for HTTPServer in Python once it is set?


I have a custom BaseHTTPServer.BaseHTTPRequestHandler that can (partially) be seen below. It has a special method that allows me to assign a reply generator - a class that takes some data in (for example the values of some of the parameters in a GET request) and generates an XML reply that can then be sent back to the client as a reply to the request:

class CustomHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  # implementation
  # ...

  def set_reply_generator(self, generator):
    self.generator = generator

  def do_GET(self):
    # process GET request
    # ...
    # and generate reply using generator
    reply = self.generator.generate(...) # ... are some parameters that were in the GET request
    # Encode
    reply = reply.encode()
    # set headers
    self.__set_headers__(data_type='application/xml', data=reply)
    # and send away
    self.wfile.write(reply)
    self.wfile.write('\n'.encode())

I pass this handler to the BaseHTTPServer.HTTPServer:

def run(addr='127.0.0.1', port=8080):
  server_addr = (addr, port)
  server = BaseHTTPServer.HTTPServer(server_addr)
  server_thread = threading.Thread(target=server.server_forever)
  server_thread.start()

Since the constructor of BaseHTTPServer.HTTPServer expects a class and not an instance to be passed as the RequestHandlerClass argument I cannot just create an instance of my handler, call set_reply_generator() and then pass it on. Even if that worked I would still want to be able to access the handler later on (for example if through a POST request the reply generator for the GET requests is changed) and for that I need to know how to retrieve the instance that the server is using.

I've looked here but I was unable to find it (perhaps missed it). I have the bad feeling that it is private (aka __...__).

All I was able to find out so far is that the class of the handler that the server uses can be retrieved through the RequestHandlerClass member, which however is not the same as retrieving an instance of the handler that will allow me to call the set_reply_generator(...).

In addition I tried to actually create an instance of the custom handler but then I landed in a chicken-and-egg issue:

  • the constructor of the handler requires you to pass the instance of the server
  • the server requires you to pass the handler

This is sort of an indirect proof that the HTTPServer's constructor is the one, that is responsible for instantiating the handler.


Solution

  • Already answered here. No need to directly access the handler but rather create a static class member that can be access without an instance but still be processed when the handler wants to use it.