我如何与AWS和Python建立理想的日常新闻通讯
#aws #python #cdk

我是一个沉重的Python用户。在过去的十年中,我基本上使用它每天都在做我的工作,因此,对Python生态系统中的新发展保持标签对我来说很有价值。出色的程序员一直在谈论有关黑客新闻,Reddit和Twitter上的新Python开发项目,因此我创建了每日新闻通讯,以收集所有三个平台的顶级Python故事。如果您想查看成品,可以在这里找到:compellingpython.com

秘密武器第一:与Docker的AWS Lambda

在lambda上使用Docker容器对我来说已经有些改变游戏规则,主要是因为在容器中添加额外的支持物品(Jinja HTML模板文件,软件包等)非常容易,而无需精心设计自定义构建系统。

发送每日电子邮件是AWS lambda的完美应用程序,因为它只需要一次调用,每天运行最多15分钟(使用128 MB的RAM)。这是每月大约6美分(是的,您读到正确的6美分 每月 ),这基本上是免费的。

使用Docker Lambdas,我要做的就是写一个看起来像这样的码头:

FROM public.ecr.aws/lambda/python:3.9

COPY requirements.txt .
RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

COPY hn.py reddit.py twitter.py article_processor.py app_handler.py ${LAMBDA_TASK_ROOT}/
COPY templates/ ${LAMBDA_TASK_ROOT}/templates/

CMD [ "app_handler.handler" ]

这将安装我在需求中指定的python软件包。 lambda容器处于入口点功能(app_handler.py文件中称为处理程序的函数。

我构建并将Docker容器推到ECR之后(可以在您的ECR回购中找到有关此的说明!),然后是时候将Docker Image部署到AWS CDK的Lambda。

秘密武器第二:AWS CDK

基础架构是如此宝贵,但如此乏味。过去,当是时候写Terraform或Cloudformation以模板来消除我的AWS资源,但在2019年,亚马逊发行了CDK,我总是会向内吟。 CDK支持Python,所以我现在可以在Python中写所有我的IAC,这是一种快乐! Python CDK代码转换为云形式(带有中间的打字稿步骤,稍后再详细介绍),因此所有状态信息都存在于AWS中,我可以在堆栈上使用漂移检测。我知道这是一个相对较新的工具,但令我惊讶的是,它没有更广泛地使用。

因此,构建新闻通讯的第一步是使用CDK部署了我在上面讨论的Docker Lambda。该lambda将从hacker News,Reddit和Twitter获取数据,过滤它,然后给我发送一封格式的电子邮件。

为了提供lambda以及IAM角色,这是我需要的所有CDK代码:

lambda_role = iam.Role(self, id="python-newsletter-lambda",
    role_name='PythonNewsletterRole',
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies= [
                iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaVPCAccessExecutionRole"),
                iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaBasicExecutionRole"),
                iam.ManagedPolicy.from_aws_managed_policy_name("AmazonS3FullAccess"),
                iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSESFullAccess"),
            ]
)

repo = ecr.Repository.from_repository_name(self, "NewsletterRepo", "python_newsletter")

newsletter_lambda = lambda_.DockerImageFunction(self,
    "PythonNewsletterLambda",
    code=lambda_.DockerImageCode.from_ecr(
        repository=repo,
        tag=os.environ["CDK_DOCKER_TAG"]
        ),
    role=lambda_role,
    timeout=Duration.minutes(15)
)

这里有三块:

  1. 产生IAM角色。在此示例中,我没有超级锁定,因为我为Lambda完整的S3访问和完整的SES(简单的电子邮件服务,在下一节中提供了更多信息)访问权限。您可以在此处生成自定义锁定政策,而不是使用AWS管理的策略。
  2. 创建对ECR存储库的引用。 ECR是亚马逊提供的Docker Image Repo服务。这是我将Docker图像推向本文第一部分中的回购。如果您是CDK的新手,我想指出的是,如果您是在引用现有资源,则应始终使用CDK文档中的From _*函数,以了解要使用的资源。在此处查看我在CDK ECR文档中所说的内容。
  3. 部署Docker Lambda。您可以看到我要做的就是指定我要部署的ECR存储库中的哪个图像标签(通过CDK_DOCKER_TAG环境变量),指定我创建的角色,并指定超时为15分钟。

就是这样!现在,当我运行cdk deploy时,我的lambda将通过所有适当的配置部署,如果我需要更改任何内容,我只需要重新运行cdk deploy即可。最后一步只是为了在EventBridge中使用CRON工作安排Lambda。

秘密武器第三:Python和AWS SES

好吧,我承认Python是最秘密的武器。但是,既然我已经描述了基础架构,那么您可能想知道这个神奇的小电子邮件订阅lambda功能中有什么。我将留下乏味的API电话,以从HN/Reddit/Twitter获取数据作为读者的练习,但我确实想简要谈论代码包的设计,尤其是发送电子邮件的方式。<<<<<<<<<<<<<<<< /p>

这是基本过程:

  • 首先,我抓住了前一天的社区API中的所有数据,并按upvotes进行排名。
  • 接下来,我从每个社区中获取有关Python的前3个帖子,并获取网页的完整HTML。
  • 解析页面的主要内容(并非总是可行),我将主文本发送到我的摘要算法(以后发布!)并获取文章的摘要。
  • 我将每个社区的前三篇文章都占据所有元数据,并使用它来填充Jinja2 HTML模板。
  • 最后,我使用AWS SES发送给我自己(以及我在“ clastellingpython.com”上注册的挑剔的朋友和同事)发送了HTML电子邮件!

ses (亚马逊的简单电子邮件服务)对于这样的应用程序来说是很棒的,因为它只是以编程方式发送散装电子邮件的最便宜方式。您每月可以免费发送62,000封电子邮件,此后每千美分10美分。十美元发送十万封电子邮件而不维护自己所有的SMTP基础架构是一项荒谬的交易。

有一些缺点,例如必须仔细管理您自己的可交付性指标和电子邮件列表(大多数其他托管电子邮件服务提供了这些内容),但是作为一个简单的电子邮件发送实用程序,我没有投诉。如果您想支付更多费用,您可以获得专用的IP,但是对于这样的有趣项目,我只使用SES免费提供的共享IP。

就是这样!那就是服务。整个新闻通讯的另一个方面我还没有讨论过,即电子邮件地址本身的集合和管理 - 我有一个单独的lambda功能,为此我可能会在以后写。现在,请注意并度过一个愉快的一周。