Category: Web Servers

  • Python Web Server: Run a Simple HTTP Server Locally

    Python Web Server: Run a Simple HTTP Server Locally

    Run a Python web server from the directory you want to share with this command:

    python -m http.server

    Python starts a simple HTTP server on port 8000. Open http://localhost:8000/ in a browser to view the directory contents. On systems where the launcher is named differently, use python3 -m http.server on macOS or Linux, or py -m http.server on Windows.

    Start a Python web server with python -m http.server (or python3/py)

    The command serves files from your current working directory: the folder selected in the terminal when you start the process. For example, to serve a site stored in a folder named website:

    cd website

    python -m http.server

    Then visit http://localhost:8000/. If the directory contains an index.html file, the server displays it as the default page. Otherwise, the built-in handler shows a directory listing that lets you open individual files.

    This simple HTTP server with Python is useful for previewing static HTML, CSS, JavaScript, images, and other files on your own computer. It does not execute server-side Python, PHP, or JavaScript application code.

    Choose the directory, port, and bind address with –directory and –bind

    Use –directory to serve a folder without changing the terminal’s working directory:

    python -m http.server –directory ./website

    A relative path starts from the current working directory. You can also provide an absolute path. Combine it with a port number when 8000 is already in use:

    python -m http.server 9000 –directory ./website

    Open http://localhost:9000/ for that server. A port conflict means another process is already listening on the selected port. Stop that process or choose another unused port, such as 9000 or 8080. The same options work with python3 and py:

    py -m http.server 9000 –directory .\website

    By default, the server can listen beyond the local machine, depending on the platform and network configuration. Use –bind 127.0.0.1 to restrict access to the computer running the server:

    python -m http.server 8000 –directory ./website –bind 127.0.0.1

    To make the server reachable from other devices on the same network, bind it to the computer’s LAN address or use –bind 0.0.0.0, then browse to the host computer’s local IP address and port. Only expose files you intend to share.

    Open http://localhost:8000, read request logs, and stop the server

    With the default command running, browse to http://localhost:8000/. Each browser request appears in the terminal, typically with the client address, method, path, protocol, and status code:

    127.0.0.1 – – “GET /index.html HTTP/1.1” 200 –

    A 200 status means the file was served successfully. A 404 indicates that the requested path was not found. Browsers may make additional requests for stylesheets, scripts, icons, or source maps, so several log lines can appear for one page load.

    Keep the terminal process running while you use the server. Press Ctrl+C to stop it cleanly. Refreshing the browser after changing a file displays the updated version, although browser caching can sometimes require a hard refresh.

    Create a simple Python server with a custom handler—and know its limits

    Use a custom handler when you need a fixed response or a small change to request behavior. Save the following as server.py:

    from http.server import BaseHTTPRequestHandler, HTTPServer

    class Handler(BaseHTTPRequestHandler):

    def do_GET(self):

    body = b”Hello from Python\n”

    self.send_response(200)

    self.send_header(“Content-Type”, “text/plain; charset=utf-8”)

    self.send_header(“Content-Length”, str(len(body)))

    self.end_headers()

    self.wfile.write(body)

    server = HTTPServer((“127.0.0.1”, 8000), Handler)

    server.serve_forever()

    Start it with python server.py, python3 server.py, or py server.py, then open http://localhost:8000/. This simple Python server responds to GET requests with plain text instead of serving files. You can add path checks, headers, or different response bodies inside do_GET.

    The built-in server is intended for local development, testing, and quick file sharing. It provides basic HTTP handling and request logging, but it is not a production application server: it lacks the routing, security controls, concurrency features, deployment tooling, and application framework integration required for a public service.