All You Need to Know About Python HTTP Server

In the following article, we will be talking about HTTP.server in Python. We will be creating a local HTTP server using it and how we can test web apps in development. Furthermore, we will show you how we can share files between two devices.

Before discussing the HTTP server, let’s briefly discuss some fundamental terms.

HTTP or Hypertext Transfer Protocol is a protocol that defines how a web client requests web pages from web servers. Moreover, it also governs how a web server responds to the client’s requests and serves the web pages.

Think of it like a web language that has rules for communication, just like any other language.

A web server is a dedicated computer system that stores web pages. It has specialized software like apache that runs on it and serves pages when requested by the client.

How a site is rendered
How a site is rendered

What is an HTTP Server?

An HTTP web server is a process that runs on your machine and has the following tasks.

  • Listens, or in other words, waits for incoming HTTP requests on a specific TCP socket address(IP address and Port).
  • It then handles the request and sends back a response.

Creating a simple http.server using Python

Using the command-line

In Python3

python3 -m http.server
HTTP.server started
HTTP.server started

Open your browser and enter http://localhost:8000/. You will notice that all the files in the current directory are listed.

Running a HTTP server
I am running an HTTP server.
Stopping an HTTP server

You can stop the HTTP.Server using CTRL + C command.

Stopping HTTP.server
Stopping an HTTP.server
Starting the server on a different port

Starting HTTP server on a different port

python3 -m http.server <port_name>
HTTP.server started at port 9000
HTTP.server started at port 9000

In Python2

python -m SimpleHTTPServer

Starting HTTP server on a different port

python -m SimpleHTTPServer <port_name>

Note: SimpleHTTPServer has been merged with HTTP.server class of HTTP module in python 3.

Creating HTTP server programmatically

from http.server import BaseHTTPRequestHandler, HTTPServer

hostName = "localhost"
serverPort = 9000

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes("<html><head><title>https://pythonpool.com</title></head>", "utf-8"))
        self.wfile.write(bytes("<body>", "utf-8"))
        self.wfile.write(bytes("<h2>Web server running...</h2>", "utf-8"))
        self.wfile.write(bytes("</body></html>", "utf-8"))

if __name__ == "__main__":        
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print(f"Server started http://{hostName}:{serverPort}")

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Http server stopped.")
Creating HTTP server programmatically
Creating HTTP server programmatically

Http.server authentication in Python

from functools import partial
from http.server import SimpleHTTPRequestHandler, test
import base64
import os

class AuthHTTPRequestHandler(SimpleHTTPRequestHandler):
    """Main class to present webpages and authentication."""

    def __init__(self, *args, **kwargs):
        username = kwargs.pop("username")
        password = kwargs.pop("password")
        directory = kwargs.pop("directory")
        self._auth = base64.b64encode(f"{username}:{password}".encode()).decode()
        super().__init__(*args, **kwargs)

    def do_HEAD(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()

    def do_AUTHHEAD(self):
        self.send_response(401)
        self.send_header("WWW-Authenticate", 'Basic realm="Test"')
        self.send_header("Content-type", "text/html")
        self.end_headers()

    def do_GET(self):
        """Present frontpage with user authentication."""
        if self.headers.get("Authorization") == None:
            self.do_AUTHHEAD()
            self.wfile.write(b"no auth header received")
        elif self.headers.get("Authorization") == "Basic " + self._auth:
            SimpleHTTPRequestHandler.do_GET(self)
        else:
            self.do_AUTHHEAD()
            self.wfile.write(self.headers.get("Authorization").encode())
            self.wfile.write(b"not authenticated")


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("--cgi", action="store_true", help="Run as CGI Server")
    parser.add_argument(
        "--bind",
        "-b",
        metavar="ADDRESS",
        default="127.0.0.1",
        help="Specify alternate bind address " "[default: all interfaces]",
    )
    parser.add_argument(
        "--directory",
        "-d",
        default=os.getcwd(),
        help="Specify alternative directory " "[default:current directory]",
    )
    parser.add_argument(
        "port",
        action="store",
        default=8000,
        type=int,
        nargs="?",
        help="Specify alternate port [default: 8000]",
    )
    parser.add_argument("--username", "-u", metavar="USERNAME")
    parser.add_argument("--password", "-p", metavar="PASSWORD")
    args = parser.parse_args()
    handler_class = partial(
        AuthHTTPRequestHandler,
        username=args.username,
        password=args.password,
        directory=args.directory,
    )
    test(HandlerClass=handler_class, port=args.port, bind=args.bind)

To run the above code, use the following command:

python3 <file_name>.py -u <username> -p <password>
Server started at port 9000
The server started at port 9000

If you go to http://localhost:9000/ (change 9000 as per your Port), there will be a prompt asking for a username and password. Enter the username and password you used in the command. Prompt will repeatedly ask for correct credentials if wrong.

Enter username and password into respecticve fields
Enter username and password into respective fields

If everything goes right, current directory files will get displayed.

Current directly files displayed.
Current directory files are displayed.

Sharing files using an http.server in Python

For this example, we will be sharing files over a network. We will host the files on our computer, which can be accessed by a mobile device. The computer will act as a host or server, while the mobile device will act as a client. However, you will need to ensure they are connected to the same network. We have connected the two devices using a wireless network, i.e., wi-fi.

Let’s go through the steps to achieve this task:

  • For Linux or macOS, use the commands ipconfig or ip addr.
  • Check for wlo1 and copy the IP address present against inet.
copy the inet IP-address
Copy the inet IP-address
  • After that, run the following command in the terminal:
python3 -m http.server -b 192.168.121.171
HTTP server started on the host computer
HTTP server started on the host computer
  • Now, when we open http://192.168.121.171:8000/ on a mobile device, we will be able to access the files of the current directory. Moreover, we can easily download files by tapping on the intended file.
Files can be accessed on the mobile device
Files can be accessed on the mobile device

Testing sites using http.server in Python

You can quickly test out your web application using Python’s HTTP.server. Start the server inside the folder which contains the index.html.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="refresh" content="30" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>This is a test html file.</h1>
    <h2>For testing http.server of python</h2>
    <h3>Random lines these are</h3>
    <h4>More random lines....</h4>
    <h5>Some more randome lines.</h5>
</body>
</html>

You can make changes to your file and refresh the browser window to see the results.

The output of index.html
The output of index.html

FAQs on Python HTTP Server

How to stop a running HTTP server in Python?

To stop a running HTTP server in Python, you will need to press CTRL + C.

Can we use HTTP server python ipv6?

Yes, since python version 3.8, support for ipv6 has been added.

Conclusion

HTTP.server class of HTTP module can come in handy when you want to test your applications or might be trying to send data across devices.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments