Tom Bar-Gal
Tom Bar-Gal

Reputation: 239

How to shut down python server

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

Answers (5)

Nabeel Ahmed
Nabeel Ahmed

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

naa-rasooa
naa-rasooa

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

Andr&#225;s Asz&#243;di
Andr&#225;s Asz&#243;di

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

ealfonso
ealfonso

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

SrGrace
SrGrace

Reputation: 326

Just use ^C (control+c) to shut down python server.

Upvotes: -3

Related Questions