如何 运行 提供特定路径的 http 服务器?

How to run a http server which serves a specific path?

这是我的 Python3 项目层次结构:

projet
  \
  script.py
  web
    \
    index.html

来自 script.py,我想要 运行 一个提供 web 文件夹内容的 http 服务器。

Here 建议将此代码用于 运行 一个简单的 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。如何指定我要提供的文件夹的路径?

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

This class serves files from the current directory and below, directly mapping the directory structure to HTTP requests.

所以您只需要在启动服务器之前更改当前目录 - 请参阅 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()

如果您只想提供静态文件,您可以使用 python 2:

通过 运行 SimpleHTTPServer 模块来实现
 python -m SimpleHTTPServer

或者用 python 3:

 python3 -m http.server

这样就不用写脚本了

为了完整起见,以下是如何设置实际服务器 类 以提供来自任意目录的文件:

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

在Python3.7 SimpleHTTPRequestHandler can take a directory argument:

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

Python 3+ 有一个更短的方法:

import functools
    
Handler = functools.partial(http.server.SimpleHTTPRequestHandler, directory='/my/dir/goes/here')

您也可以运行命令行

python3 -m http.server -d web 8000

另一种从特定目录提供服务的简单方法。

因为您实际上只需要为 SimpleHTTPRequestHandler 设置 directory 参数,您可以使用 functools.partial 准备 处理程序 class 没有实例化 class.

from functools import partial
from http.server import HTTPServer, SimpleHTTPRequestHandler
from pathlib import Path


def start_httpd(directory: Path, port: int = 8000):
    print(f"serving from {directory}...")
    handler = partial(SimpleHTTPRequestHandler, directory=directory)
    httpd = HTTPServer(('localhost', port), handler)
    httpd.serve_forever()
    

如果你只需要一个现代网络静态服务器,
deno 是替代 file server 没有任何 code.

单行安装 deno

https://github.com/denoland/deno_install#deno_install

单行安装file server

deno install --allow-net --allow-read https://deno.land/std@0.125.0/http/file_server.ts

使用 deno file-server

file_server . --port=<port>
# Downloading https://deno.land/std@0.125.0/http/file_server.ts...
# HTTP server listening on http://0.0.0.0:<port>/

阅读更多https://deno.land/manual/examples/file_server#using-the-codestdhttpcode-file-server