= BaseHTTPServer =

You can use this to make a simple HTTP web server.

<<TableOfContents>>

== Official Documentation ==

 * [[http://docs.python.org/lib/module-BaseHTTPServer.html|BaseHTTPServer module documentation]] - what we use directly
 * [[http://docs.python.org/lib/module-SocketServer.html|SocketServer module documentation]] - behind the BaseHttpServer

== Example Code ==

=== Responding with an HTML Page ===

{{{
#!python
import time
import BaseHTTPServer


HOST_NAME = 'example.net' # !!!REMEMBER TO CHANGE THIS!!!
PORT_NUMBER = 80 # Maybe set this to 9000.


class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_HEAD(s):
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
    def do_GET(s):
        """Respond to a GET request."""
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
        s.wfile.write("<html><head><title>Title goes here.</title></head>")
        s.wfile.write("<body><p>This is a test.</p>")
        # If someone went to "http://something.somewhere.net/foo/bar/",
        # then s.path equals "/foo/bar/".
        s.wfile.write("<p>You accessed path: %s</p>" % s.path)
        s.wfile.write("</body></html>")

if __name__ == '__main__':
    server_class = BaseHTTPServer.HTTPServer
    httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
}}}

=== Responding with URL Redirection ===

This code demonstrates simple URL redirection:

{{{
#!python
"""
URL redirection example.
"""

import BaseHTTPServer
import time
import sys


HOST_NAME = 'example.net' # !!!REMEMBER TO CHANGE THIS!!!
PORT_NUMBER = 80 # Maybe set this to 9000.
REDIRECTIONS = {"/slashdot/": "http://slashdot.org/",
                "/freshmeat/": "http://freshmeat.net/"}
LAST_RESORT = "http://google.com/"

class RedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_HEAD(s):
        s.send_response(301)
        s.send_header("Location", REDIRECTIONS.get(s.path, LAST_RESORT))
        s.end_headers()
    def do_GET(s):
        s.do_HEAD()

if __name__ == '__main__':
    server_class = BaseHTTPServer.HTTPServer
    httpd = server_class((HOST_NAME, PORT_NUMBER), RedirectHandler)
    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
}}}

== Parameterizing ==

When you want to make your server respect some parameters, it's easiest to do so via the ''server,'' rather than the ''handler.''

That is, make a subclass of the server, that accepts some additional parameters. Have the server record those parameters.

Then, in the handler, use {{{s.server}}} to get to the server, and access the parameters through it.

== See Also ==

 * DocXmlRpcServer -- self-documenting XML-RPC servers
 * CgiScripts -- using invoked CGI scripts, rather than running micro-web servers

= Discussion =

I'd ultimately like to see a BaseHttpServer here that can both handle XML-RPC requests (with ''that'' request handler,) and normal web requests (with a custom handler.)

Yes- I know and love TwistedPython. But I want to make something that works in a single install. -- LionKimbro <<DateTime(2004-05-31T01:13:16Z)>>

I'd also like to add code here showing how to service a POST request.

-- LionKimbro <<DateTime(2004-07-03T23:07:53Z)>>

There exist tools like CherryPy which will create a single-file Python HTTP server (based on BaseHTTPServer).  This is a fair amount easier to work with than the raw BaseHTTPServer.  For most cases, using a more complete framework will be preferable (see WebProgramming).  -- IanBicking

I like the BaseHttpServer because it is in the default Python distributions. I encourage all work towards putting a standard web framework into the default Python distribution. I'm not picky, just as long as something is chosen. -- LionKimbro <<DateTime(2005-01-25T04:53:53Z)>>

What's the matter with server_close()? I can call the method, but it is undocumented (see [[http://docs.python.org/lib/node634.html]]). Could someone knowledgable either remove the calls, or add a comment why they're necessary? Thanks. -- Anonymous Coward, 23 Oct 2007