#!/usr/bin/env python3 # -*- coding: utf-8 -*- from random import randint from http.server import ThreadingHTTPServer, HTTPServer, SimpleHTTPRequestHandler from signal import signal, SIGINT from socketserver import ThreadingMixIn, BaseServer, BaseRequestHandler from threading import Thread class HandlerExtractCode(SimpleHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(b"{ \"key\": \"value\" }") class BackendThreadHttpServer(ThreadingHTTPServer): def __init__(self, server_address, request_handler_class): super().__init__(server_address, request_handler_class) # properly close HttpServer and close ThreadMixIn with join client threads def server_close(self): # stop serve_forever infinite loop (This should be defined into HTTPServer.server_close method) BaseServer.shutdown(self) # # close TCP socket and more for future override into HTTPServer class # HTTPServer.server_close(self) # # join all process request threads # ThreadingMixIn.server_close(self) class BackendApplication(Thread): def __init__(self, handler, host: str = "0.0.0.0", port: int = 8080): super().__init__(target=self.application_endpoint) self.port: int = port self.httpServer = BackendThreadHttpServer((host, port), handler) def application_endpoint(self): print("serving at port", self.port) self.httpServer.serve_forever() def stop(self): print("stop listening at port", self.port) self.httpServer.server_close() def start_server(): def handle_sigint(signal_received, frame): print("stop server thread") application_endpoint.stop() print("wait server thread") application_endpoint.join() # create server to handle oauth callback request application_endpoint = BackendApplication(HandlerExtractCode, "127.0.0.1", 65534) # on sigint close server listen socket signal(SIGINT, handle_sigint) # start server handler into new thread application_endpoint.start() return application_endpoint if __name__ == "__main__": thread = start_server() thread.join() print("ended")