sherwood
sherwood

Reputation: 143

Python 3 simple HTTP server with GET functional

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

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

So I need basically a working server class that process at least GET requests. Most of the things I found on Google 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()

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

Upvotes: 5

Views: 18818

Answers (4)

Richard Neumann
Richard Neumann

Reputation: 3361

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

Upvotes: 3

Don Hatch
Don Hatch

Reputation: 5402

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()

Upvotes: 0

sherwood
sherwood

Reputation: 143

That's what I ended up with:

# 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.

Upvotes: 3

y0sh1da
y0sh1da

Reputation: 1

Use the Requests library:

import requests

# The required first parameter of the 'get' method is the 'url'(instead of get you can use any other http type, as needed):

r = requests.get('https://stackoverflow.com/questions/73089846/python-3-simple-http-get-functional')

# You can print many other things as well such as content, text and so on
print(r.status_code)

Check the documentation.

Upvotes: -5

Related Questions