[英]How do I kill SimpleHTTPServer from within a Python script?
我正在嘗試使用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)
這是我在做什么:
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
,則服務器將關閉。
對上面用戶的代碼稍作修改:
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))
這是問題的閉包解決方案。 適用於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
將返回start
和stop
函數
>>> 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
我讓它運行,但我很想知道這與上面用戶的答案相比如何。 在查看此處接受的答案后,我想出了這個。
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)
這是我更喜歡的上下文風格版本,因為它會自動清理並且您可以指定要提供的目錄:
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)
我打開瀏覽器的解決方案:
文件: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()
在我看來,我所做的是:
(僅當您在python中運行cmd/terminal命令時,因為我認為在cmd/terminal中停止它的方法是ctrl+c或直接退出cmd/terminal)
注意:pid也在那里
希望這會有所幫助:D!!
使用 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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.