8

我正在尝试用它http.server来测试 Python 项目中的所有链接。如果我在运行我的脚本之前启动服务器,我可以让我的脚本工作,然后当我关闭终端窗口时服务器停止。但我真的很希望脚本本身启动和停止服务器。

我制作了一个测试脚本来简单地启动服务器,获取页面并证明服务器正在运行,然后停止服务器。我似乎无法获得服务器的 pid。当我在脚本运行后尝试终止该脚本报告的 pid 时,我收到一条消息,指出没有这样的进程;但服务器仍在运行。

如何获得服务器的正确 pid,或者更一般地说,如何从脚本中停止服务器?

import os
import requests
from time import sleep

# Start server, in background.
print("Starting server...")
os.system('python -m http.server &')
# Make sure server has a chance to start before making request.
sleep(1)

print "Server pid: "
os.system('echo $$')

url = 'http://localhost:8000/index.html'
print("Testing request: ", url)
r = requests.get(url)
print("Status code: ", r.status_code)
4

8 回答 8

10

这是我正在做的事情:

import threading

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

server = HTTPServer(('localhost', 0), SimpleHTTPRequestHandler)
thread = threading.Thread(target = server.serve_forever)
thread.daemon = True
thread.start()

def fin():
    server.shutdown()

print('server running on port {}'.format(server.server_port))

# here is your program

如果你调用fin你的程序,那么服务器就会关闭。

于 2013-10-24T18:50:59.447 回答
3

对上面用户的代码稍作修改:

import threading
try: 
  from http.server import HTTPServer, BaseHTTPRequestHandler # Python 3
except ImportError: 
  import SimpleHTTPServer
  from BaseHTTPServer import HTTPServer # Python 2
  from SimpleHTTPServer import SimpleHTTPRequestHandler as BaseHTTPRequestHandler
server = HTTPServer(('localhost', 0), BaseHTTPRequestHandler)
thread = threading.Thread(target = server.serve_forever)
thread.deamon = True
def up():
  thread.start()
  print('starting server on port {}'.format(server.server_port))
def down():
  server.shutdown()
  print('stopping server on port {}'.format(server.server_port))
于 2015-02-11T19:47:40.043 回答
2

这是该问题的封闭解决方案。适用于python 3。

import os
import threading
import webbrowser
from http.server import HTTPServer, SimpleHTTPRequestHandler


def simple_http_server(host='localhost', port=4001, path='.'):

    server = HTTPServer((host, port), SimpleHTTPRequestHandler)
    thread = threading.Thread(target=server.serve_forever)
    thread.deamon = True

    cwd = os.getcwd()

    def start():
        os.chdir(path)
        thread.start()
        webbrowser.open_new_tab('http://{}:{}'.format(host, port))
        print('starting server on port {}'.format(server.server_port))

    def stop():
        os.chdir(cwd)
        server.shutdown()
        server.socket.close()
        print('stopping server on port {}'.format(server.server_port))

    return start, stop

simple_http_server这将返回startstop功能

>>> start, stop = simple_http_server(port=4005, path='/path/to/folder')

您可以将其用作

>>> start()
starting server on port 4005

127.0.0.1 - - [14/Aug/2016 17:49:31] "GET / HTTP/1.1" 200 -

>>> stop()
stopping server on port 4005
于 2016-08-14T14:09:55.923 回答
2

这是我更喜欢的上下文风格版本,因为它会自动清理您可以指定要服务的目录:

from contextlib import contextmanager
from functools import partial
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from threading import Thread


@contextmanager
def http_server(host: str, port: int, directory: str):
    server = ThreadingHTTPServer(
        (host, port), partial(SimpleHTTPRequestHandler, directory=directory)
    )
    server_thread = Thread(target=server.serve_forever, name="http_server")
    server_thread.start()

    try:
        yield
    finally:
        server.shutdown()
        server_thread.join()


def usage_example():
    import time

    with http_server("127.0.0.1", 8087, "."):
        # now you can use the web server
        time.sleep(100)
于 2021-05-06T06:41:53.243 回答
1

我让它运行,但我很想知道这与上面用户的答案相比如何。在查看此处接受的答案后,我想出了这个。

import subprocess
import requests
import os
import signal
from time import sleep

print "Starting server..."
cmd = 'python -m SimpleHTTPServer'
pro = subprocess.Popen(cmd, shell=True, preexec_fn=os.setsid)

# Make sure server has a chance to start before making request.
sleep(1)

url = 'http://localhost:8000/index.html'
print "Testing request: ", url
r = requests.get(url)
print "Status code: ", r.status_code

os.killpg(pro.pid, signal.SIGTERM)
于 2013-10-24T23:34:11.833 回答
0

在我看来,我所做的是:

  1. 转到活动监视器
  2. 然后去网络
  3. 搜索单词“python”

(仅当您在 python 中运行 cmd/terminal 命令时,因为我认为在 cmd/terminal 中停止它的方法是 ctrl+c 或者只是退出 cmd/terminal)

注意:pid也在那里

  1. 退出进程“python”(如果没有,使用强制退出进程)
  2. 如果这在 cmd/终端中有效,那么你就完成了!享受~

希望这会有所帮助:D!

于 2019-11-24T14:57:26.773 回答
0

使用 Python 3.8

import http.server
import socketserver
import threading
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
server = socketserver.TCPServer(("", PORT), Handler)
thread = threading.Thread(target = server.serve_forever)
thread.daemon = True
thread.start()
于 2020-07-30T15:21:10.930 回答
0

我打开浏览器的解决方案:

文件:http.py

import SimpleHTTPServer
import SocketServer
import threading
import webbrowser
import platform
from socket import SOL_SOCKET,SO_REUSEADDR

class HTTPServer():

    def __init__(self,port=8000,url='http://localhost'):
        self.port = port
        self.thread = None
        self.httpd = None                
        self.run = False
        self.url = url

        os = platform.system()
        if os=='Linux':
            self.browser_path = "/usr/bin/google-chrome %s"            
        elif os == 'Windows':
            self.browser_path = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s"   
        else:
            print("Chrome not found!")


    def start(self):        
        self.run = True     
        self.httpd = SocketServer.TCPServer(("", self.port), SimpleHTTPServer.SimpleHTTPRequestHandler)
        self.httpd.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        self.thread = threading.Thread(target = self._serve)
        self.thread.start()
        webbrowser.get(str(self.browser_path)).open(self.url+":"+str(self.port)+"/")


    def _serve(self):        
        while self.run:
            self.httpd.handle_request()

    def stop(self):
        self.run = False
        self.httpd.server_close()

之后,只需运行:

from http import HTTPServer

server = HTTPServer()
server.start()

raw_input("Enter to close")

server.stop()
于 2015-09-03T16:57:41.477 回答