使用pyramid_mailer和apscheduler发送定时邮件

4

我尝试让它工作,但一定有更好的方法,欢迎任何建议。

我正在尝试在我的Python金字塔应用程序中使用pyramid_mailer(存储在.ini文件中的设置)和apscheduler设置计划发送定时邮件。

我还使用SQLAlchemyJobStore,以便在应用程序重新启动时可以重新启动作业。

jobstores = {
    'default': SQLAlchemyJobStore(url='mysql://localhost/lgmim')
}
scheduler = BackgroundScheduler(jobstores=jobstores)

@view_config(route_name='start_email_schedule')
def start_email_schedule(request):
    # add the job and start the scheduler
    scheduler.add_job(send_scheduled_email, 'interval', [request], weeks=1)
    scheduler.start()

    return HTTPOk()

def send_scheduled_email(request):

    # compile message and recipients
    # send mail  
    send_mail(request, subject, recipients, message)

def send_mail(request, subject, recipients, body):

    mailer = request.registry['mailer']
    message = Message(subject=subject,
                  recipients=recipients,
                  body=body)

    mailer.send_immediately(message, fail_silently=False)

我已经做到这一步了,现在出现了一个错误,可能是因为无法pickle请求。

PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

使用pyramid.threadlocal.get_current_registry().settings可以在第一次获取邮件服务,但之后会报错。建议不要在任何情况下使用该方法。

还有其他的方法吗?

1个回答

3
通常情况下,由于request对象包含对诸如打开的套接字和其他生命对象的引用,因此您无法将其保存为pickle对象。
在这里有一些有用的模式:

  • 您可以在数据库中预生成电子邮件ID,然后通过调度程序传递ID(int、UUID)。

  • 您可以生成模板上下文(JSON dict),然后通过调度程序传递该上下文,并在工作进程内呈现模板。

  • 您可以在调度程序内执行所有数据库提取和相关操作,并且不传递任何参数。

具体而言,在调度程序内部生成虚假的request对象的问题可以通过以下方式解决:

from pyramid import scripting
from pyramid.paster import bootstrap

def make_standalone_request():
    bootstrap_env = bootstrap("your-pyramid-config.ini")
    app = bootstrap_env["app"]
    pyramid_env = scripting.prepare(registry=bootstrap_env["registry"])
    request = pyramid_env["request"]

    # Note that request.url will be always dummy,
    # so if your email refers to site URL, you need to 
    # resolve request.route_url() calls before calling the scheduler
    # or read the URLs from settings

    return request

这里可以找到更多相关的灵感(免责声明:我是作者)。


谢谢,这真的很有帮助。不过你的链接好像有问题。 - Niel
修复了链接。被浏览器自动填充坑了。 - Mikko Ohtamaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接