Differences between BaseHttpServer and wsgiref.simple_server

I’m looking for a module that provides me a basic http server capabilities for local access. It seems like Python has two methods to implement simple http servers in the standard library: wsgiref.simple_server and BaseHttpServer.

What are the differences? Is there any strong reason to prefer one over the other?

Best answer

Short answer: wsgiref.simple_server is a WSGI adapter over BaseHTTPServer.

Longer answer:

BaseHTTPServer (and SocketServer, on which it builds) is the module that implements most of the actual HTTP server. It can accept requests and return responses, but it has to know how to handle those requests. When you are using BaseHTTPServer directly, you provide the handlers by subclassing BaseHTTPRequestHandler, for example:

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('Hello world!\n')

HTTPServer(('', 8000), MyHandler).serve_forever()

wsgiref.simple_server adapts this BaseHTTPServer interface to the WSGI specification, which is the standard for server-independent Python web applications. In WSGI, you provide the handler in the form of a function, for example:

from wsgiref.simple_server import make_server

def my_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield 'Hello world!\n'

make_server('', 8000, my_app).serve_forever()

The make_server function returns an instance of WSGIServer, which inherits most of the actual protocol/network logic from BaseHTTPServer.HTTPServer and SocketServer.TCPServer (although it does end up reimplementing some simple rules of HTTP). What mainly differs is the way you integrate your application code with that logic.

It really depends on the problem you’re trying to solve, but coding against wsgiref is probably a better idea because it will make it easy for you to move to a different, production-grade HTTP server, such as uWSGI or Gunicorn, in the future.