最小smtpd处理程序
snails的Python项目详细描述
有时候你想写一个愚蠢的电子邮件处理程序。
适用于:低容量、最小解析、与传统的基于电子邮件的系统交互
不适合:大容量、生产使用、100%符合RFC
需要python 3.7+
pip install snails
用法
importsnailsdefhandle(msg:snails.Message)->None:print(f"To: {msg['to']}")print(f"From: {msg['from']}")print("Subject: {msg['subject']}")forpinmsg.get_payload():print(p.get_payload(decode=True))# run and block until ctrl + csnails.serve(handle,"127.0.0.1",10025)# or, call start/stop yourselfmailbox=snails.Mailbox(handle,"127.0.0.1",10025)mailbox.start()
启用TLS
importsslimportsnailsdefhandle(msg:bytes)->None:...# TODOssl_context=ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)ssl_context.load_cert_chain("cert.pem","key.pem")mailbox=snails.Mailbox(handle,"::",25,ssl_context=ssl_context)
消息分析
当新请求到达时,snails将把信封传递给解析器函数。你可以提供这个 解析器本身,或者让snails根据处理程序的类型注释推断解析器。
蜗牛为以下类型提供解析器:
- bytes
- aiosmtpd.smtp.Envelope(别名为snails.Envelope)
- email.message.Message(别名为snails.Message)
大多数情况下,使用注释就足够了:
defhandle(x:bytes):withopen("out.log","wb")asf:f.write(x)defhandle(x:snails.Envelope):withopen("out.log","wb")asf:f.write(x.content)defhandle(x:snails.Message):withopen("out.log","wb")asf:f.write(x.as_bytes())
您还可以定义自己的解析器:
defparse(e:snails.Envelope)->dict:as_str=e.content.decode()return{}# TODO your parsingdefhandle(x:dict):...# TODO use the dict parsed abovemailbox=snails.Mailbox(handle,"::",25,parser=parse)
异步邮箱
处理程序和解析器都可以是异步函数;默认情况下,snails包装所有同步函数。
importsnailsasyncdefparse(e:snails.Envelope)->dict:as_str=e.content.decode()return{}# TODO your parsingasyncdefhandle(x:dict):res=awaitsome_db_call(...)mailbox=snails.Mailbox(handle,"::",25,parser=parse)
其他
- 您可以从处理程序返回字符串,例如"250 OK"或内置的snails.SMTP_250。
- 使用Mailbox.start和Mailbox.stop
- 用cleanup_at_exit=True调用snails.serve,以确保调用Mailbox.stop。 当解释器关闭时(默认启用)
- 使用block=True调用snails.serve以阻止调用Mailbox.start后的执行(默认情况下已启用)。 您可以通过发送sigint或ctrl+c来停止服务器。