3

I have a HTTP server in Python created with

    from http.server import BaseHTTPRequestHandler, HTTPServer
    import bson.json_util
    import json
    server = HTTPServer((ip, port), GetHandler)
    print ('Starting server, use <Ctrl-C> to stop')
    server.serve_forever()

where GetHandler

class GetHandler(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def do_GET(self):
        json_string = json.dumps({"message" : "Hello"}, default=bson.json_util.default)+"\n"
        self._set_headers()
        self.wfile.write(json_string.encode())#encoding='UTF-8'
        return

Suppose I want to pass a variable to the method do_GET of the class GetHandler from the line server = HTTPServer((ip, port), GetHandler): how can I do that?

EDIT

Just as example suppose that I have a string my_str defined before the line server = HTTPServer((ip, port), GetHandler) and I want to use this string as response message.

roschach
  • 8,390
  • 14
  • 74
  • 124
  • Sorry for deleting my previous answer. I noticed that I did not really answer the question from your post. I have now edited with something that - I think - answers the question. – exhuma Oct 01 '19 at 11:33
  • Possible duplicate of [BaseHTTPRequestHandler with custom instance](https://stackoverflow.com/questions/18444395/basehttprequesthandler-with-custom-instance) – Maurice Meyer Oct 01 '19 at 11:42

1 Answers1

5

In Python you can actually create classes inside functions. These classes will then have access the the function's locals via a closure.

The following code defines the function make_handler which, when called defines a new "handler" class with the value in myvariable available inside the whole class:

import json
from http.server import BaseHTTPRequestHandler, HTTPServer


def make_handler(myvariable):

    class GetHandler(BaseHTTPRequestHandler):
        def _set_headers(self):
            self.send_response(200)
            self.send_header('Content-type', 'text/plain')
            self.end_headers()

        def do_GET(self):
            self._set_headers()
            self.wfile.write(myvariable.encode('utf8'))
            return

    return GetHandler

server = HTTPServer(('127.0.0.1', 50002), make_handler('my_str'))
print ('Starting server, use <Ctrl-C> to stop')
server.serve_forever()
exhuma
  • 20,071
  • 12
  • 90
  • 123
  • How would you feel about subclassing `GetHandler` and using `super`? – Chillie Oct 01 '19 at 11:48
  • It depends on what OP would like to achieve. When using subclassing you must define a new class for every possible input string. If that string value is very dynamic (f. ex. from user- or external-input), this is not feasible. If the values are however well-defined at the time the program is written, I would prefer subclassing, as it is easier to understand. – exhuma Oct 01 '19 at 11:54