Reputation: 239
Used this code to run a python server:
import os
from http.server import SimpleHTTPRequestHandler, HTTPServer
os.chdir('c:/users/owner/desktop/tom/tomsEnyo2.5-May27')
server_address = ('', 8000)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
httpd.serve_forever()
How to make it stop?
Upvotes: 13
Views: 36068
Reputation: 19252
Your question is ambiguous - if your running the server via shell i.e. python myscript.py, simply press crtl + C
.
If you want to close it elegantly using code, you must decide on some condition, or point, or exception to call it shutdown. You can add a block and call httpd.shutdown()
- as HttpServer
itself is a SocketServer.TCPSServer
subclass:
The first class, HTTPServer, is a SocketServer.TCPServer subclass, and therefore implements the SocketServer.BaseServer interface. It creates and listens at the HTTP socket, dispatching the requests to a handler.
So the BaseServer
has a method shutdown()
, hence being a subclass HttpServer has it too.
for example:
import os
from http.server import SimpleHTTPRequestHandler, HTTPServer
os.chdir('c:/users/owner/desktop/tom/tomsEnyo2.5-May27')
server_address = ('', 8000)
try:
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
httpd.serve_forever()
except KeyboardInterrupt:
httpd.shutdown()
Helpful relevant question -
Upvotes: 15
Reputation: 11
My answer is very late but I ran into this problem recently. So here is my solution: create a class that handles tracking of start/stop of the server in processes:
from http.server import HTTPServer as StdHTTPServer
from http.server import SimpleHTTPRequestHandler
from multiprocessing import Process
from time import sleep
class HTTPServer(StdHTTPServer):
def __init__(
self,
hostname: str = "0.0.0.0",
port: int = 8080,
):
super().__init__((hostname, port), SimpleHTTPRequestHandler)
self.allow_reuse_address = True
self.serve_ps = None
def __enter__(self):
self.start_serve()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.stop_serve()
def start_serve(self):
"""Serve forever in a new process"""
self.serve_ps = Process(target=self.serve_forever)
self.serve_ps.start()
def stop_serve(self):
ps = Process(target=self.shutdown)
ps.start()
sleep(2)
self.serve_ps.kill()
self.serve_ps.join(timeout=1)
ps.kill()
ps.join(timeout=1)
self.server_close()
Then you can use start_serve
and stop_serve
to start/stop the server. Or use the context manager
with HTTPServer() as http_server:
# <code>
# server is closed when <code> finishes
pass
Upvotes: 1
Reputation: 9660
If you need the Python HTTP server in a unit test then it is advisable to run it in a separate thread and stop it from another one, like this:
import unittest
from threading import Thread
from http.server import HTTPServer
class TestWithHTTP(unittest.TestCase):
"""
My unit test that needs a HTTP server
NOTE: skeleton code
"""
def setUp(self):
# you need to provide the host, port and request handler class
self.myserver = HTTPServer((host, port), HandlerClass)
# start HTTP server in another thread
httpthread = Thread(target=self.myserver.serve_forever)
httpthread.start()
# ... any other setup operations ...
def test_something(self):
# ... your unit testing code ...
pass
def tearDown(self):
# shut down the server from yet another thread
killerthread = Thread(target = self.myserver.shutdown)
killerthread.start()
Upvotes: 2
Reputation: 7302
You can send a SIGTERM signal from the handler thread if you are ok with killing the whole process:
os.kill(os.getpid(), signal.SIGTERM)
Upvotes: 0