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.
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
Open your browser and enter http://localhost:8000/. You will notice that all the files in the current directory are listed.
Stopping an HTTP server
You can stop the HTTP.Server using CTRL + C command.
Starting the server on a different port
Starting HTTP server on a different port
python3 -m http.server <port_name>
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.")
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>
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.
If everything goes right, current directory files will get 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
orip addr
. - Check for wlo1 and copy the IP address present against inet.
- After that, run the following command in the terminal:
python3 -m http.server -b 192.168.121.171
- 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.
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.
FAQs on Python HTTP Server
To stop a running HTTP server in Python, you will need to press CTRL + C
.
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.