4

Is it possible to serve a subdirectory instead of the current directory with SimpleHTTPServer ?

I use it from the command-line like so:

python -m SimpleHTTPServer 5002

The reason I would like to use this is that I have a target folder which I delete from time to time and is regenerated by my tooling. However when I do that I need to restart the SimpleHTTPServer as well. I think that serving it from the parent repository would allow me not to restart it.

nha
  • 17,623
  • 13
  • 87
  • 133

2 Answers2

2

Well, to serve the parent directory, just change the current working directory before running your Python script (python -m SimpleHTTPServer 5002).

You can write your own script, eg.: 'my_server.py':

import SimpleHTTPServer
import os


def main():
    pwd = os.getcwd()
    try:
        os.chdir("..")  # or any path you like
        SimpleHTTPServer.test()
    finally:
        os.chdir(pwd)


if __name__ == "__main__":
    main()

Then run 'my_server.py':

python -m my_server 5002
Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103
2

If you're calling it from shell, you can just use shell features and do:

For Python 2:

pushd /path/you/want/to/serve; python -m SimpleHTTPServer; popd

For Python 3.6 you don't even need to do that.
There's a directory argument to http.server, so just do:

python3 -m http.server -d /path/you/want/to/serve

However, if you want to call it programatically, the solution proposed by Andy Hayden on "How to run a http server which serves a specific path?" seems more appropriate.
(It's less 'hacky'/ dependent on side effects, and uses the class constructor instead.)

Goes like this:

import http.server
import socketserver

PORT = 8000
DIRECTORY = "web"


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


with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

The code above works for Python >= 3.6
For Python up to 3.5, there was no contextmanager protocol available for TCPServer's base class, but that just means you need to change the with statement and turning it into a plain assignment:

httpd = socketserver.TCPServer(("", PORT), Handler)

Credits to Anthony Sottile for this last detail.

Vinícius M
  • 554
  • 6
  • 15