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

roi*_*ere 39 python simplehttpserver python-3.x

这是我的Python3项目hiearchy:

projet
  \
  script.py
  web
    \
    index.html
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

但这实际上是服务project,而不是web.如何指定要提供的文件夹的路径?

Joh*_*ter 28

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()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!注意:我添加了try:`httpd.serve_forever(); 除了KeyboardInterrupt:pass; httpd.server_close()`实际关闭端口. (2认同)
  • 对于未来的读者:下面安迪·海登的解决方案不太“hacky”,并且可能是首选,因为它不依赖于副作用。 (2认同)

Jer*_*ski 25

如果你只想要服务静态文件,可以通过使用python 2运行SimpleHTTPServer模块来实现:

 python -m SimpleHTTPServer
Run Code Online (Sandbox Code Playgroud)

或者使用python 3:

 python3 -m http.server
Run Code Online (Sandbox Code Playgroud)

这样您就不需要编写任何脚本了.

  • http.server有一个目录参数。所以你可以做python3 -m http.server -d / path / to / web / dir (9认同)
  • OP 询问如何在特定文件夹路径而不是从当前工作目录运行它。 (3认同)
  • 虽然这个答案被问题的所有者接受为最佳答案,但我认为它不应该是最佳答案。问题是询问如何在 python 中对其进行编码,而不是如何从命令行调用它。 (3认同)
  • 请注意,您还可以在最后添加端口以指定服务器的端口。 (2认同)
  • 进一步说明;您运行服务器的目录中必须有一个“index.html”或“index.htm”文件才能提供服务;否则你会得到一个目录列表。 (2认同)

And*_*den 20

在Python 3.7中SimpleHTTPRequestHandler可以采用一个directory参数:

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()
Run Code Online (Sandbox Code Playgroud)

从命令行:

python -m http.server --directory web
Run Code Online (Sandbox Code Playgroud)

为了有点疯狂......你可以为任意目录制作处理程序:

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()
Run Code Online (Sandbox Code Playgroud)


Jay*_*mon 16

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

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)
Run Code Online (Sandbox Code Playgroud)

然后,您可以在代码中设置任意路径:

web_dir = os.path.join(os.path.dirname(__file__), 'web')
httpd = HTTPServer(web_dir, ("", 8000))
httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)


Hab*_*bie 15

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

import functools
    
Handler = functools.partial(http.server.SimpleHTTPRequestHandler, directory='/my/dir/goes/here')
Run Code Online (Sandbox Code Playgroud)

  • 停止使用 Python 2 :) (9认同)

mon*_*kut 8

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

由于您实际上只需要设置 的directory参数SimpleHTTPRequestHandler,因此您可以使用functools.partial准备处理程序类,而无需实例化该类。

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()
    
Run Code Online (Sandbox Code Playgroud)


mut*_*toe 7

您还可以运行命令行

python3 -m http.server -d web 8000
Run Code Online (Sandbox Code Playgroud)

  • 或者要查看所有支持的参数,请尝试“python3 -m http.server --help” (2认同)