Robin te Hofstee

Creating Local Web Servers with Python for Homelab Use

Robin te Hofstee6 min readViews6
Creating Local Web Servers with Python for Homelab Use

Learn how to use Python's built-in HTTP capabilities to set up local web servers for testing, file sharing, and more in your homelab environment.

Creating Local Web Servers with Python for Homelab Use

This tutorial delves into using Python's built-in HTTP server capabilities to create local web servers, test endpoints, and share files within your homelab setup. We'll cover the basics of setting up a local server, handling request routing, and serving dynamic or static content. This guide is part 5 of a 9-part series on Python scripting, making it accessible for those following along or for standalone reference.

Why Use Python for Web Development?

Python offers a lightweight yet powerful framework for web development, making it ideal for quick prototyping and small projects. By leveraging Python's standard library, you can rapidly set up a local web server for testing, file sharing, and more. Additionally, Python's extensive ecosystem provides numerous libraries and tools for enhancing web development tasks.

Setting Up a Basic HTTP Server

To begin, let's set up a simple HTTP server using Python's http.server module. This module is available in Python 3 and provides a basic HTTP server capable of serving static files.

Step 1: Create a Directory for Your Files

First, create a directory to hold your files. For example, you might create a directory named homelab:

mkdir -p ~/homelab
cd ~/homelab

Step 2: Add Some Static Files

Create a few static files that you want to serve. For example, you could create an index.html file:

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Homelab Web Server</title>
</head>
<body>
    <h1>Welcome to the Homelab Web Server</h1>
    <p>This is a simple web server set up using Python's built-in HTTP server capabilities.</p>
</body>
</html>

Save this file in your homelab directory.

Step 3: Start the HTTP Server

Now, you can start the HTTP server using the following command:

python3 -m http.server 8000

This command will start an HTTP server on port 8000. You can access your server by navigating to http://localhost:8000 in your web browser.

Dynamic Content with CGI

For more advanced use cases, you might want to serve dynamic content. Python's CGIHTTPServer module can be used to handle CGI scripts, allowing you to execute Python code in response to HTTP requests.

Step 1: Create a CGI Script

Create a Python script that will be executed when a specific URL is accessed. For example, create a hello.py file:

# hello.py
import cgi
import cgitb
cgitb.enable()
 
print("Content-type: text/html\n\n")
print("<html>")
print("<head><title>Hello CGI Script</title></head>")
print("<body>")
print("<h1>Hello, World!</h1>")
print("</body>")
print("</html>")

Step 2: Start the CGI Server

Start the CGI server with the following command:

python3 -m http.server --cgi 8000

Access your CGI script by navigating to http://localhost:8000/hello.py in your web browser.

Handling Basic Request Routing

For more complex applications, you might need to handle different routes or endpoints. This can be achieved using a simple routing mechanism.

Step 1: Create a Routing Script

Create a Python script to handle routing. For example, create a router.py file:

# router.py
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
 
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
 
    def do_GET(self):
        path = self.path
        parsed_url = urlparse(path)
        query_params = parse_qs(parsed_url.query)
 
        if parsed_url.path == '/':
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b"Welcome to the Homelab Web Server")
        elif parsed_url.path == '/about':
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b"About Page")
        else:
            self.send_response(404)
            self.end_headers()
            self.wfile.write(b"Page Not Found")
 
if __name__ == "__main__":
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
    httpd.serve_forever()

Step 2: Start the Routing Server

Start the server using the following command:

python3 router.py

Access the root and about pages by navigating to http://localhost:8000/ and http://localhost:8000/about in your web browser.

Serving Static and Dynamic Content

Now that you have a basic routing mechanism, you can combine it with serving static and dynamic content. You can use the http.server module to serve static files and a custom handler for dynamic content.

Step 1: Update the Routing Script

Modify the router.py script to serve static files:

# router.py
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
from http.server import SimpleHTTPRequestHandler, HTTPServer
 
class CustomHandler(BaseHTTPRequestHandler):
 
    def do_GET(self):
        path = self.path
        parsed_url = urlparse(path)
        query_params = parse_qs(parsed_url.query)
 
        if parsed_url.path == '/':
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b"Welcome to the Homelab Web Server")
        elif parsed_url.path == '/about':
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b"About Page")
        elif parsed_url.path.endswith('.html'):
            self.send_response(200)
            self.end_headers()
            with open(parsed_url.path[1:], 'rb') as file:
                self.wfile.write(file.read())
        else:
            self.send_response(404)
            self.end_headers()
            self.wfile.write(b"Page Not Found")
 
if __name__ == "__main__":
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, CustomHandler)
    httpd.serve_forever()

Step 2: Start the Server

Start the server using the following command:

python3 router.py

Access the static HTML files in your homelab directory by navigating to http://localhost:8000/<filename.html> in your web browser.

Conclusion

In this guide, we've covered how to use Python's built-in HTTP capabilities to create local web servers for testing, file sharing, and more in your homelab environment. By leveraging Python's standard library, you can rapidly set up a basic HTTP server, handle request routing, and serve both static and dynamic content.

While this guide focuses on the basics, Python's capabilities extend far beyond this. You can further explore advanced topics like asynchronous handling, SSL/TLS encryption, and integration with other tools and services. Happy coding!

Tutorial series

Python Scripting Series

A step-by-step Python series for self-hosters and developers: from your first script and a clean environment to databases and local AI APIs.

  1. 3.Mastering Python Virtual Environments with python3 -m venv
  2. 4.Automating Daily Filesystem and System Maintenance with Python
  3. 5.Creating Local Web Servers with Python for Homelab Use
  4. 5.Leverage Python for Local Web Server Hosting and Dynamic Content

5 more parts coming soon.

Share this post
Robin te Hofstee

Written by Robin te Hofstee

Technology enthusiast with a deep love for programming. Sharing practical guides on React, Next.js, Linux and self-hosting.