Simple Python HTTP (S) Server - Example AnvilEight Blog
Simple Python HTTP (S) Server - Example AnvilEight Blog
The standard Python library has a built-in module that can be used as minimalistic
HTTP/HTTPS web server. It provides
support of the protocol and allows you to extend
capabilities by subclassing.
Serve static HTML/CSS files to outside world can be very helpful and handy in many real life
situations. For example,
to show a client HTML pages you’ve created or stub an API by creating
a static file.
Both port and bind address are optional. For more details, please read the
official docs.
Python 2.X
Python 2.x can only accept port as a parameter Bind address parameter is not available.
Python
2.x Docs.
In both cases contents of the current folder will be accessible via http://127.0.0.1:8000
Python 3.X
import ssl
keyfile="path/to/key.pem",
certfile='path/to/cert.pem', server_side=True)
httpd.serve_forever()
Python 2.X
import BaseHTTPServer, SimpleHTTPServer
import ssl
SimpleHTTPServer.SimpleHTTPRequestHandler)
keyfile="path/tp/key.pem",
certfile='path/to/cert.pem', server_side=True)
httpd.serve_forever()
To generate key and cert files with OpenSSL use following command
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
Do_GET
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, world!')
httpd.serve_forever()
This is a very trivial HTTP server that responds Hello, world! to the requester. Note, that
self.send_response(200) and self.end_headers() are mandatory, otherwise the response wont
be considered
as valid. We can check that it actually works by sending a request using HTTPie:
$ http http://127.0.0.1:8000
HTTP/1.0 200 OK
Hello, world!
Note, that self.wfile is a file like object, thus expects a byte-like objects to the write function.
Another way of feeding the wfile is by using BytesIO
object (see example below).
Do_POST
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, world!')
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
self.send_response(200)
self.end_headers()
response = BytesIO()
response.write(b'Received: ')
response.write(body)
self.wfile.write(response.getvalue())
httpd.serve_forever()
method should be executed in order to get the contents. Note, that size should be
explicitly
passed to the function, otherwise the request will hang and never end.
This is why obtaining content_length is necessary. It could be retrieved via self.headers and
converted
into an integer. An example above just prints back whatever he receives, like follows:
HTTP/1.0 200 OK
Installation
Usage
Options
–path= is either a specific file or a directory to be set as the root of the web server. Use this if
you have a
directory full of HTML, cgi, epy, or rpy files or any other files that you want to be
Commands
web A general-purpose web server which can serve from a filesystem or application resource.
If you are looking for HTTPS and SSL support, consider the following options:
Docker Example
Here are an example of Dockerfile I use to serve simple html pages to outside world.
FROM python:3.5
VOLUME ["/code"]
ADD . /code
WORKDIR /code
EXPOSE 5000
It is possible to write custom handlers and extend the basic functionality. Including creating
HTTPS server etc. Find official documentation for python 3 http server is here. Python 2
documentation is here
Created by AnvilEight