5

I can't find any Python code for the equivalent of

python -m http.server port --bind addr --directory dir

I need a server class that processes at least GET requests. Most things I found were either an HTTP server with some special needs or something like that, where you need to code the response behaviour be yourself:

from http.server import BaseHTTPRequestHandler, HTTPServer

def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()

run()

I need a default working skeleton of a Python HTTP server, where you can provide address, port and directory, and it would normally process GET requests.

3 Answers 3

4

You need to subclass the BaseHTTPRequestHandler to, well, handle the requests:

class HTTPRequestHandler(BaseHTTPRequestHandler):
    """HTTP request handler with additional properties and functions"""

    def do_GET(self):
        """Handle GET requests"""
        # Do something
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I know. But what code should be in this method to process simplest GET request, as for example apache2 doing it for default?
That entirely depends on what you want the method / web server to do.
I already wrote. I want simple HTTP server. So I can browse directories and view web-pages with css and images. Means on GET request I will get headers with file body. The command I mentioned in the begging is working perfectly but I need code-based solution
4
# python -m http.server 8000 --directory ./my_dir

from http.server import HTTPServer as BaseHTTPServer, SimpleHTTPRequestHandler
import os


class HTTPHandler(SimpleHTTPRequestHandler):
    """This handler uses server.base_path instead of always using os.getcwd()"""

    def translate_path(self, path):
        path = SimpleHTTPRequestHandler.translate_path(self, path)
        relpath = os.path.relpath(path, os.getcwd())
        fullpath = os.path.join(self.server.base_path, relpath)
        return fullpath


class HTTPServer(BaseHTTPServer):
    """The main server, you pass in base_path which is the path you want to serve requests from"""

    def __init__(self, base_path, server_address, RequestHandlerClass=HTTPHandler):
        self.base_path = base_path
        BaseHTTPServer.__init__(self, server_address, RequestHandlerClass)


web_dir = os.path.join(os.path.dirname(__file__), 'my_dir')
httpd = HTTPServer(web_dir, ("", 8000))
httpd.serve_forever()

A simple HTTP server that handles GET requests with, working with a certain directory.

Comments

0

SimpleHTTPRequestHandler's constructor accepts an optional directory, although trying to get at it is torturous. Here's the simplest thing I came up with:

#!/usr/bin/python3

import http.server
import os
import sys

def MakeHandlerClassWithBakedInDirectory(directory):
  class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs, directory=directory)
  return Handler

if len(sys.argv) != 3:
  exit("Usage: something <port> <directory>")

port = int(sys.argv[1])
directory = sys.argv[2]

assert os.path.isdir(directory), f"{directory!r} is not a directory"

with http.server.ThreadingHTTPServer(('', port), 
                                     MakeHandlerClassWithBakedInDirectory(directory)) as httpd:
  print(f"serving at port {port}")
  httpd.serve_forever()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.