Discussion:
passing context into BaseHTTPRequestHandler
Steve Howell
2012-03-23 18:58:17 UTC
Permalink
I have a use case where I'm running BaseHTTPServer.HTTPServer, and I
want to configure the request handler with some context. I've gotten
the code to work, but it feels overly heavy. I am wondering if
anybody could suggest an easier idiom for this.

This is a brief sketch of the code:

class MyHandler(BaseHTTPRequestHandler):
def __init__(self, context, *args):
self.context = context
BaseHTTPRequestHandler.__init__(self, *args)

def do_GET(self):
// self.context will be available here

context = { .... }
def handler(*args):
MyHandler(context, *args)

server = HTTPServer(('', port), handler)
server.serve_forever()

Basically, it takes five lines of code just to pass context into the
handler:

def handler(*args):
MyHandler(context, *args)

def __init__(self, context, *args):
self.context = context
BaseHTTPRequestHandler.__init__(self, *args)

Typically the second argument to HTTPServer is a subclass of
BaseHTTPRequestHandler, but I pass in "handler" instead, which
instantiates a new instance of MyHandler with the context from the
enclosing scope. At first I tried to say "MyHandler(*args).context =
context", but that assignment was too late, because
BaseHTTPRequestHandler.__init__ does a lot of stuff during the
construction phase. That's what forced me to write my own custom
__init__ as well.

I hope there's enough info here to understand what I'm trying to
achieve, but if it helps to see my code in more context, you can see
it here:

https://gist.github.com/2173618

Thanks.
Bernhard Herzog
2012-03-23 19:19:22 UTC
Permalink
Post by Steve Howell
I have a use case where I'm running BaseHTTPServer.HTTPServer, and I
want to configure the request handler with some context. I've gotten
the code to work, but it feels overly heavy. I am wondering if
anybody could suggest an easier idiom for this.
self.context = context
BaseHTTPRequestHandler.__init__(self, *args)
// self.context will be available here
context = { .... }
MyHandler(context, *args)
server = HTTPServer(('', port), handler)
server.serve_forever()
You could store the context in the server object and access it in the
handler methods via self.server.context. It basically works like this:

class MyHTTPServer(HTTPServer):

def __init__(self, *args, **kw):
HTTPServer.__init__(self, *args, **kw)
self.context = { .... }


class MyHandler(BaseHTTPRequestHandler):

def do_GET(self):
context = self.server.context
...


server = MyHTTPServer(('', port), MyHandler)
server.serve_forever()


Bernhard
--
Bernhard Herzog | ++49-541-335 08 30 | http://www.intevation.de/
Intevation GmbH, Neuer Graben 17, 49074 Osnabr?ck | AG Osnabr?ck, HR B 18998
Gesch?ftsf?hrer: Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner
Steve Howell
2012-03-23 21:37:36 UTC
Permalink
Post by Bernhard Herzog
Post by Steve Howell
I have a use case where I'm running BaseHTTPServer.HTTPServer, and I
want to configure the request handler with some context. ?I've gotten
the code to work, but it feels overly heavy. ?I am wondering if
anybody could suggest an easier idiom for this.
? ? ? ? ? ? self.context = context
? ? ? ? ? ? BaseHTTPRequestHandler.__init__(self, *args)
? ? ? ? ? ? // self.context will be available here
? ? context = { .... }
? ? ? ? MyHandler(context, *args)
? ? server = HTTPServer(('', port), handler)
? ? server.serve_forever()
You could store the context in the server object and access it in the
? ? ? ? HTTPServer.__init__(self, *args, **kw)
? ? ? ? self.context = { .... }
? ? ? ? context = self.server.context
? ? ? ? ...
server = MyHTTPServer(('', port), MyHandler)
server.serve_forever()
Thanks for the suggestion. I made the change, and I think the code's
a bit easier to read now.

Loading...