Python's built-in http.server module lets you create HTTP servers easily. You can serve files, test web applications, and build custom servers without installing extra packages.
This guide shows you how to create HTTP servers in Python, starting with a simple one-line command and building up servers with more features.
Prerequisites
Make sure you have installed Python 3.6 or later. Check your version by running python --version
or python3 --version
in your terminal.
Creating a one-line HTTP server
Python includes a simple way to start an HTTP server from the command line. This is perfect for quickly sharing files or testing websites.
Open your terminal and create a directory for your HTTP server project:
mkdir python-http-server
cd python-http-server
Now, let's add some files to work with. Create a CSS file:
echo "body { font-family: Arial; margin: 40px; }" > styles.css
Create a text file with some content:
echo "This is a sample text file served by Python's http.server module." > readme.txt
With your directory and test file ready, start the server by running:
python3 -m http.server
Let's look at what makes this simple server work:
python3 -m
tells Python to run a module as a scripthttp.server
is the built-in module that creates HTTP servers- By default, it uses port 8000 and serves your current folder
When you run the command, you'll see:
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
You now have a working HTTP server. Open your browser and go to http://localhost:8000
to see the listed files:
You can click any file to open it. For example, click readme.txt
to view its contents in your browser:
When you go back to the terminal, you’ll see the server log has updated:
::1 - - [05/May/2025 11:22:25] "GET / HTTP/1.1" 200 -
::1 - - [05/May/2025 11:29:31] "GET /readme.txt HTTP/1.1" 200 -
The server logs each request it receives, including the time, file requested, and status code.
Adding an index.html
file
You can customize what visitors see when they access your site using Python's HTTP server. The server displays a directory listing by default, but adding an index.html
file changes this behavior.
Let's create an index.html
file in your project directory:
<!DOCTYPE html>
<html>
<head>
<title>My Python Server</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Welcome to My Python HTTP Server</h1>
<p>This page is being served by Python's built-in HTTP server.</p>
<h2>Files available on this server:</h2>
<ul>
<li><a href="readme.txt">readme.txt</a> - Sample text file</li>
<li><a href="styles.css">styles.css</a> - CSS styles for this page</li>
</ul>
</body>
</html>
Save this file in your python-http-server
directory. Now reload http://localhost:8000
in your browser.
Instead of seeing the directory listing, you'll now see your custom welcome page. The HTTP server automatically looks for and serves index.html
when someone requests a directory.
When you check your terminal, you'll see the logged requests:
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
::1 - - [05/May/2025 11:42:26] "GET / HTTP/1.1" 200 -
::1 - - [05/May/2025 11:42:26] "GET /styles.css HTTP/1.1" 200 -
Notice that when you requested the root directory ("/"), the server sent your index.html
file, followed by the CSS file linked in your HTML.
This behavior mimics standard web servers like Apache and Nginx, which also serve index.html
files by default when a directory is requested.
Customizing your server
The one-line HTTP server is simple but has limited options. Let's explore how to customize it to suit your needs better.
Changing the port number
By default, the server uses port 8000
, but you can specify a different port:
python3 -m http.server 9000
This starts the server on port 9000 instead. You'll see:
Serving HTTP on :: port 9000 (http://[::]:9000/) ...
Now access your site at http://localhost:9000
.
Restricting network access
For security, you might want to restrict access to your computer only. Use the --bind
option:
python3 -m http.server --bind 127.0.0.1
This makes the server accessible only from your own machine (localhost), not from other computers on your network.
Serving HTTP on 127.0.0.1 port 8000 (http://127.0.0.1:8000/) ...
You can combine these options:
python3 -m http.server 8080 --bind 127.0.0.1
Serving a different directory
To serve files from a different directory without changing your current working directory:
python3 -m http.server --directory /path/to/your/files
The server will now serve files from the specified directory instead of your current one.
Viewing all available options
To see all the options available for the HTTP server:
python3 -m http.server --help
You'll see output like:
usage: server.py [-h] [--cgi] [-b ADDRESS] [-d DIRECTORY] [-p VERSION] [port]
positional arguments:
port bind to this port (default: 8000)
options:
-h, --help show this help message and exit
--cgi run as CGI server
-b, --bind ADDRESS bind to this address (default: all interfaces)
-d, --directory DIRECTORY
serve this directory (default: current directory)
-p, --protocol VERSION
conform to this HTTP version (default: HTTP/1.0)
These options give you flexibility for different scenarios while still maintaining the simplicity of a one-line command.
Creating a custom server script
Writing your script is the next logical step when you need more control over your HTTP server. The one-line command works well for basic tasks, but a custom script lets you add error handling, customize behavior, and extend functionality. This approach gives you a foundation you can build upon for more sophisticated server applications.
In your root directory, create a new file called basic_server.py
with the following code:
from http.server import HTTPServer, SimpleHTTPRequestHandler
# Define server address
host = "localhost"
port = 8000
# Create handler and server objects
handler = SimpleHTTPRequestHandler
server = HTTPServer((host, port), handler)
print(f"Server started at http://{host}:{port}")
# Start the server
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nServer stopped")
server.server_close()
This script performs the same function as the one-line command from earlier sections but with an improved structure. The SimpleHTTPRequestHandler
class handles incoming requests and serves files from your directory, just like before. The key improvement is adding proper error handling and shutdown behavior.
Run this script by entering this command in your terminal:
python basic_server.py
You'll see this confirmation message:
Server started at http://localhost:8000
Now open or refresh http://localhost:8000
in your browser. You should still see your custom welcome page:
When you want to stop the server, press Ctrl
+ C
in your terminal. Unlike the one-line version, this script catches the keyboard interrupt and performs a clean shutdown, displaying a confirmation message:
...
Server stopped
This basic script serves as a template for more advanced server implementations. By understanding these fundamentals, you can create custom servers that precisely meet your requirements. The code is simple yet powerful, providing you with complete control over how requests are handled and responses are generated.
Final thoughts
Python’s built-in http.server
module makes it easy to serve files, test web pages, or create simple HTTP tools without installing anything extra.
In this guide, you started with a one-line command, added custom content like index.html
, explored useful options, and wrote a standalone server script for more control.
This lightweight tool is perfect for quick tasks and learning how HTTP works. For more details and advanced features, visit the official http.server documentation.
Make your mark
Join the writer's program
Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.
Write for us
Build on top of Better Stack
Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.
community@betterstack.comor submit a pull request and help us build better products for everyone.
See the full list of amazing projects on github