Introduction
Python's built-in web server is a simple, yet powerful tool that allows you to quickly set up a web server for development and testing purposes. It is part of Python's http.server
module, which provides classes for implementing web servers.
This guide shows you how to use the Python http.server
module.
Prerequisites
Before you begin:
- Deploy a VPS server. For instance, Ubuntu 24.04.
- Create a non-root sudo user.
- Install Python.
Simple Hello, World!
Web Server
Start with a simple example that serves a Hello, World!
message by following the steps below.
-
Create a new Python file (e.g.,
server.py
) and add the following code:Pythonfrom http.server import BaseHTTPRequestHandler, HTTPServer class HelloWorldHandler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(b'Hello, World!') def run(server_class=HTTPServer, handler_class=HelloWorldHandler, port=8000): server_address = ('', port) httpd = server_class(server_address, handler_class) print(f'Starting server on port {port}...') httpd.serve_forever() if __name__ == '__main__': run()
-
Run the server:
Bash$ python3 server.py
-
Access the web server: Open a web browser and navigate to:
``` http://localhost:8000 ````.
You should see "Hello, World!" displayed on the page.
Handling Different HTTP Methods
Now that we you've a basic web server running, extend it to handle different HTTP methods.
GET Requests
You've already seen how to handle a basic GET request. Extend this by adding more functionality to our handler.
POST Requests
Add the following method to handle POST requests:
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f'POST request received: {post_data.decode("utf-8")}'
self.wfile.write(response.encode('utf-8'))
PUT Requests
Add the following method to handle PUT requests:
def do_PUT(self):
content_length = int(self.headers['Content-Length'])
put_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f'PUT request received: {put_data.decode("utf-8")}'
self.wfile.write(response.encode('utf-8'))
DELETE Requests
Add the following method to handle DELETE requests:
def do_DELETE(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b'DELETE request received')
PATCH Requests
Add the following method to handle PATCH requests:
def do_PATCH(self):
content_length = int(self.headers['Content-Length'])
patch_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f'PATCH request received: {patch_data.decode("utf-8")}'
self.wfile.write(response.encode('utf-8'))
Your updated server code should look like this:
from http.server import BaseHTTPRequestHandler, HTTPServer
class MyRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b'Hello, World!')
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f'POST request received: {post_data.decode("utf-8")}'
self.wfile.write(response.encode('utf-8'))
def do_PUT(self):
content_length = int(self.headers['Content-Length'])
put_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f'PUT request received: {put_data.decode("utf-8")}'
self.wfile.write(response.encode('utf-8'))
def do_DELETE(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b'DELETE request received')
def do_PATCH(self):
content_length = int(self.headers['Content-Length'])
patch_data = self.rfile.read(content_length)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f'PATCH request received: {patch_data.decode("utf-8")}'
self.wfile.write(response.encode('utf-8'))
def run(server_class=HTTPServer, handler_class=MyRequestHandler, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print(f'Starting server on port {port}...')
httpd.serve_forever()
if __name__ == '__main__':
run()
Send Requests Using curl
You can test your web server by sending requests using curl
, a command-line tool for transferring data with URLs. Here are some examples of how to use curl
for the different HTTP methods:
-
Send a GET request to the root path:
Bashcurl http://localhost:8000
-
Send a POST request with data:
Bashcurl -X POST -d "name=Francis" http://localhost:8000
-
Send a PUT request with data:
Bashcurl -X PUT -d "name=UpdatedName" http://localhost:8000
-
Send a DELETE request:
Bashcurl -X DELETE http://localhost:8000
-
Send a PATCH request with data:
Bashcurl -X PATCH -d "name=PatchedName" http://localhost:8000
You can use curl
to test different endpoints and verify that your web server is handling requests correctly.
Conclusion
This guide explains how to use Python's built-in web server, starting with a simple Hello, World!
example and gradually introducing more complex functionalities, including handling different HTTP methods (GET, POST, PUT, DELETE, and PATCH) and sending requests using curl
. The built-in web server is a useful tool for development and testing, allowing you to quickly set up a web server and serve static content. Understanding how to use and extend the built-in web server can significantly improve your development workflow and help you create more dynamic and responsive applications.