I'm trying to create a Windows SMTP server in Python that uses the aiosmtpd library, which provides a multithreaded controller that listens on a TCP port for connections.
This code works perfectly:
from aiosmtpd.controller import Controller
class CustomSMTPServer:
# Proof of concept
async def handle_DATA(self, server, session, envelope):
print(f'> Incoming mail from \'{envelope.mail_from}\'')
return '250 OK'
if __name__ == '__main__':
controller = Controller(CustomSMTPServer(), hostname='127.0.0.1', port=25)
controller.start()
# I would like to wait for CTRL+C instead of ENTER
input(f'SMTP listening on port {controller.port}. Press ENTER to exit.\n')
# ... and stopping the controller after the key has been pressed
controller.stop()
I would like to modify it such as it doesn't wait for ENTER but for CTRL+C instead, without using a while True endless loop because this would eat CPU. It would be great to not use a lot of libraries imports, if possible.
Is there anything better than using time.sleep(1) inside the loop, as the aiosmtpd.controller is already running in its thread and the main thread is not doing anything useful, apart from waiting for CTRL+C?
You can use the signal module to catch the SIGINT (Ctrl+C) signal and stop the dispatcher. Here is an example:
Now the program will wait for the SIGINT signal instead of ENTER and will stop when the user presses Ctrl+C. The stop_controller function will be called when a signal is received and will stop the controller. The signal.pause() function waits for any signal, but does not consume CPU resources until a signal is received.