web-dev-qa-db-ja.com

特定のパスを提供するhttpサーバーを実行する方法は?

これは私のPython3プロジェクト階層です:

projet
  \
  script.py
  web
    \
    index.html

script.pyから、webフォルダーのコンテンツを提供するhttpサーバーを実行したいと思います。

ここ は、単純なhttpサーバーを実行するためのこのコードを推奨します。

import http.server
import socketserver

PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()

しかし、これは実際にprojectではなくwebを提供します。提供したいフォルダーのパスを指定するにはどうすればよいですか?

34
roipoussiere

https://docs.python.org/3/library/http.server.html#http.server.SimpleHTTPRequestHandler

このクラスは、現在のディレクトリ以下のファイルを提供し、ディレクトリ構造をHTTPリクエストに直接マッピングします。

したがって、サーバーを起動する前に現在のディレクトリを変更する必要があります- os.chdir を参照してください

例えば:

import http.server
import socketserver
import os

PORT = 8000

web_dir = os.path.join(os.path.dirname(__file__), 'web')
os.chdir(web_dir)

Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
26
John Carter

静的ファイルのみを提供したい場合は、python 2を使用してSimpleHTTPServerモジュールを実行することにより、静的ファイルを提供できます。

 python -m SimpleHTTPServer

またはpython 3を使用:

 python3 -m http.server

この方法では、スクリプトを記述する必要はありません。

22

Python 3.7で SimpleHTTPRequestHandlerdirectory引数を取ることができます

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

コマンドラインから:

python -m http.server --directory web

少し狂ったように...任意のディレクトリのハンドラーを作成できます。

def handler_from(directory):
    def _init(self, *args, **kwargs):
        return http.server.SimpleHTTPRequestHandler.__init__(self, *args, directory=self.directory, **kwargs)
    return type(f'HandlerFrom<{directory}>',
                (http.server.SimpleHTTPRequestHandler,),
                {'__init__': _init, 'directory': directory})


with socketserver.TCPServer(("", PORT), handler_from("web")) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()
19
Andy Hayden

完全を期すために、実際のサーバークラスをセットアップして、任意のディレクトリからファイルを提供する方法を次に示します。

try
    # python 2
    from SimpleHTTPServer import SimpleHTTPRequestHandler
    from BaseHTTPServer import HTTPServer as BaseHTTPServer
except ImportError:
    # python 3
    from http.server import HTTPServer as BaseHTTPServer, SimpleHTTPRequestHandler


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__), 'web')
httpd = HTTPServer(web_dir, ("", 8000))
httpd.serve_forever()
14
Jaymon