Thanks to visit codestin.com
Credit goes to github.com

Skip to content

yuanxiaoming8899/Zappa-cn

 
 

Repository files navigation

扎帕摇滚!

Zappa - 无服务器 Python

CI 覆盖范围 皮伊 松弛

关于

Zappa 拖鞋

匆忙?单击查看(现在有点过时)来自 Serverless SF 的幻灯片

Zappa使得在 AWS Lambda + API Gateway 上构建和部署无服务器、事件驱动的 Python 应用程序(包括但不限于 WSGI Web 应用程序)变得非常容易。将其视为 Python 应用程序的“无服务器”网络托管。这意味着无限扩展零停机零维护- 并且成本仅为当前部署的一小部分!

如果您有一个 Python Web 应用程序(包括 Django 和 Flask 应用程序),则非常简单:

$ pip install zappa
$ zappa init
$ zappa deploy
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

现在您无需服务器了!哇!

“无服务器”是什么意思?

好吧,所以仍然有一个服务器 - 但它只有40 毫秒的生命周期!在这种情况下,无服务器意味着“没有任何永久性基础设施”。

对于传统的 HTTP 服务器,服务器全天候 (24/7) 在线,一一处理传入的请求。如果传入请求的队列变得太大,某些请求将超时。借助 Zappa, Amazon API Gateway 为每个请求提供了自己的虚拟 HTTP“服务器”。AWS 自动处理水平扩展,因此任何请求都不会超时。然后,每个请求都会从 AWS Lambda 中的内存缓存调用您的应用程序,并通过 Python 的 WSGI 接口返回响应。当你的应用程序返回后,“服务器”就死掉了。

更好的是,使用 Zappa,您只需为您使用的服务器时间的毫秒数付费,因此它比 Linode 或 Heroku 等 VPS/PaaS 主机便宜很多数量级- 而且在大多数情况下,它是完全免费的。另外,无需担心负载平衡或保持服务器再次在线。

它非常适合使用 Flask 和 Bottle 等框架部署无服务器微服务,以及使用 Django 托管更大的 Web 应用程序和 CMS。或者,您可以使用任何您喜欢的 WSGI 兼容应用程序!您可能不需要更改现有的应用程序即可使用它,并且您不会被限制使用它。

Zappa 还允许您构建混合事件驱动的应用程序,每年可以扩展到数万亿个事件,而无需您付出额外的努力!您还可以获得免费的 SSL 证书全局应用程序部署API 访问管理自动安全策略生成预编译 C 扩展自动保温超大 Lambda 包以及许多其他独家功能

最后,Zappa非常易于使用。您可以使用开箱即用的单个命令来部署您的应用程序!

惊人的!

Zappa 演示 Gif

安装与配置

在开始之前,请确保您运行的是 Python 3.8/3.9/3.10/3.11/3.12,并且拥有有效的 AWS 账户并且AWS 凭证文件已正确安装。

Zappa可以通过 pip 轻松安装,如下所示:

$ pip install zappa
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

请注意,Zappa必须安装到您项目的虚拟环境中。虚拟环境名称不应与 Zappa 项目名称相同,否则可能会导致错误。

(如果您使用pyenv并且喜欢使用pyenv-virtualenv管理 virtualenv ,您只需调用pyenv local [your_venv_name]它就可以了。Conda用户应该在此处发表评论。)

接下来,您需要定义本地和服务器端设置。

运行初始设置/设置

Zappa可以使用以下命令自动为您设置部署设置init

$ zappa init
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

这将自动检测您的应用程序类型(Flask/Django - Pyramid 用户请参阅此处)并帮助您定义部署配置设置。完成初始化后,您的项目目录中将有一个名为zappa_settings.json的文件,用于定义基本部署设置。对于大多数 WSGI 应用程序来说,它可能看起来像这样:

{
    // The name of your stage
    "dev": {
        // The name of your S3 bucket
        "s3_bucket": "lambda",
    <span class="pl-c">// The modular python path to your WSGI application function.</span>
    <span class="pl-c">// In Flask and Bottle, this is your 'app' object.</span>
    <span class="pl-c">// Flask (your_module.py):</span>
    <span class="pl-c">// app = Flask()</span>
    <span class="pl-c">// Bottle (your_module.py):</span>
    <span class="pl-c">// app = bottle.default_app()</span>
    <span class="pl-s">"app_function"</span>: <span class="pl-s">"your_module.app"</span>
<span class="pl-kos">}</span>

}

  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

或者对于姜戈:

{
    "dev": { // The name of your stage
       "s3_bucket": "lambda", // The name of your S3 bucket
       "django_settings": "your_project.settings" // The python path to your Django settings.
    }
}
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

注:如果您是第一次使用 Zappa 部署 Django 应用程序,您可能需要阅读 Edgar Roman 的Django Zappa 指南

您可以根据需要定义任意多个阶段 - 我们建议有开发登台生产阶段

现在,您已准备好部署!

基本用法

初始部署

配置完设置后,您可以使用单个命令打包应用程序并将其部署到名为“生产”的阶段:

$ zappa deploy production
Deploying..
Your application is now live at: https://7k6anj0k99.execute-api.us-east-1.amazonaws.com/production

现在您的应用程序已上线!多么酷啊?!

为了解释发生了什么,当您调用 时deploy,Zappa 会自动将您的应用程序和本地虚拟环境打包到 Lambda 兼容的存档中,将任何依赖项替换为与 lambda 兼容的轮子版本,设置函数处理程序和必要的 WSGI 中间件,上传将存档保存到 S3,创建和管理必要的 Amazon IAM 策略和角色,将其注册为新的 Lambda 函数,创建新的 API 网关资源,为其创建 WSGI 兼容的路由,将其链接到新的 Lambda 函数,最后删除S3 存储桶中的存档。便利!

请注意,为执行 Lambda 创建的默认 IAM 角色和策略应用一组自由的权限。这些很可能不适合重要应用程序的生产部署。有关更多详细信息,请参阅用于执行的自定义 AWS IAM 角色和策略部分 。

更新

如果您的应用程序已经部署,您只需要上传新的Python代码,而不需要触及底层路由,您可以简单地:

$ zappa update production
Updating..
Your application is now live at: https://7k6anj0k99.execute-api.us-east-1.amazonaws.com/production

这会创建一个新存档,将其上传到 S3 并更新 Lambda 函数以使用新代码,但不会触及 API 网关路由。

Docker 工作流程

在0.53.0版本中,添加了使用 Docker 部署和更新 Lambda 函数的支持。

--docker-image-uri您可以使用zappa 命令的选项来deploy指定ECR 映像update。Zappa 期望构建镜像并将其推送到 Amazon ECR 存储库。

部署示例:

$ zappa deploy --docker-image-uri {AWS ACCOUNT ID}.dkr.ecr.{REGION}.amazonaws.com/{REPOSITORY NAME}:latest
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

更新示例:

$ zappa update --docker-image-uri {AWS ACCOUNT ID}.dkr.ecr.{REGION}.amazonaws.com/{REPOSITORY NAME}:latest
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

参考博文了解有关如何利用此功能以及何时需要的更多详细信息。

如果您为 Lambda 运行时使用自定义 Docker 映像(例如,如果您想要使用 Lambda 开箱即用尚不支持的较新版本的 Python)并且您想绕过 Python 版本检查,则可以设置一个环境变量来执行此操作:

$ export ZAPPA_RUNNING_IN_DOCKER=True
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

您还可以将其添加到您的 Dockerfile 中,如下所示:

ENV ZAPPA_RUNNING_IN_DOCKER=True
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

回滚

您还可以rollback通过提供要返回的修订数量来将部署的代码恢复到先前版本。例如,要回滚到 3 个版本之前部署的版本:

$ zappa rollback production -n 3
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

调度

Zappa 可用于轻松安排定期发生的功能。这提供了比 Celery 更好、免维护的替代品!这些函数将与您一起打包和部署,app_function并自动从处理程序中调用。只需在zappa_settings.json文件中列出您的函数和表达式,以使用cron 或rate 语法来安排它们:

{
    "production": {
       ...
       "events": [{
           "function": "your_module.your_function", // The function to execute
           "expression": "rate(1 minute)" // When to execute it (in cron or rate format)
       }],
       ...
    }
}

进而:

$ zappa schedule production

现在你的函数将每分钟执行一次!

如果你想取消这些,你可以简单地使用unschedule命令:

$ zappa unschedule production

现在您的预定活动规则已被删除。

请参阅示例了解更多详细信息。

高级调度

多重表达

有时,一个函数需要多个表达式来描述其调度。要设置多个表达式,只需在zappa_settings.json文件中列出您的函数以及使用cron 或rate 语法来调度它们的表达式列表:

{
    "production": {
       ...
       "events": [{
           "function": "your_module.your_function", // The function to execute
           "expressions": ["cron(0 20-23 ? * SUN-THU *)", "cron(0 0-8 ? * MON-FRI *)"] // When to execute it (in cron or rate format)
       }],
       ...
    }
}

这可用于处理因 UTC 时区在您当地时区的工作时间内跨越午夜而引起的问题。

应该注意的是,重叠表达式不会引发警告,并且应该进行检查,以防止重复触发函数。

残疾人活动

有时应该安排某个事件,但将其禁用。例如,也许一个事件应该只在生产环境中运行,而不是在沙箱中运行。您可能仍希望将其部署到沙箱,以确保在部署到生产之前您的表达式没有问题。

在这种情况下,您可以通过在事件定义中设置enabled为来禁用它运行:false

{
    "sandbox": {
       ...
       "events": [{
           "function": "your_module.your_function", // The function to execute
           "expression": "rate(1 minute)", // When to execute it (in cron or rate format)
           "enabled": false
       }],
       ...
    }
}

取消部署

如果您需要删除之前发布的 API Gateway 和 Lambda 函数,您可以简单地:

$ zappa undeploy production

在执行之前,系统会要求您进行确认。

如果您为 API Gateway 服务启用了 CloudWatch Logs 并且不想保留这些日志,则可以指定参数--remove-logs来清除 API Gateway 和 Lambda 函数的日志:

$ zappa undeploy production --remove-logs

包裹

如果您想构建应用程序包而不实际将其上传并注册为 Lambda 函数,则可以使用以下package命令:

$ zappa package production

如果您zip的设置中有回调callbacks,它也会被调用。

{
    "production": { // The name of your stage
        "callbacks": {
            "zip": "my_app.zip_callback"// After creating the package
        }
    }
}

您还可以使用以下命令指定包的输出文件名-o

$ zappa package production -o my_awesome_package.zip

Zappa 如何制作包装

Zappa 会自动将您的活动虚拟环境打包成可在 AWS Lambda 上顺利运行的包。

在此过程中,它将用 AWS Lambda 兼容版本替换任何本地依赖项。依赖项包含在此顺序中:

  • manylinux来自本地缓存的Lambda 兼容轮子
  • manylinuxPyPI 的Lambda 兼容轮
  • 来自活动虚拟环境的包
  • 来自本地项目目录的包

它还会跳过某些不必要的文件,并忽略任何 .py 文件(如果 .pyc 文件可用)。

此外,Zappa 还将自动设置正确的执行权限、配置包设置,并创建唯一的、可审核的包清单文件。

要进一步减小最终包文件的大小,您可以:

模板

与 类似package,如果您只需要 API Gateway CloudFormation 模板,请使用以下template命令:

$ zappa template production --l your-lambda-arn -r your-role-arn

请注意,在这种情况下,您必须提供自己的 Lambda ARN 和角色 ARN,因为它们可能不是为您创建的。

您可以使用 直接获取 JSON 输出--json,并使用 指定输出文件--output

地位

如果您需要查看部署和事件计划的状态,只需使用该status命令即可。

$ zappa status production

尾矿原木

您可以通过调用管理命令来查看部署的日志tail

$ zappa tail production

默认情况下,这将显示所有日志项。除了 HTTP 和其他事件之外,任何print已编辑stdoutstderr将显示在日志中的内容。

您可以使用该参数--http来过滤 HTTP 请求,该请求将采用 Apache 通用日志格式。

$ zappa tail production --http

同样,您可以执行相反的操作,仅显示非 HTTP 事件和日志消息:

$ zappa tail production --non-http

如果您不喜欢默认的日志颜色,可以使用 关闭它们--no-color

您还可以使用 限制尾部的长度--since,它接受一个简单的持续时间字符串:

$ zappa tail production --since 4h # 4 hours
$ zappa tail production --since 1m # 1 minute
$ zappa tail production --since 1mm # 1 month

您可以使用 过滤掉日志的内容--filter,如下所示:

$ zappa tail production --http --filter "POST" # Only show POST HTTP requests

请注意,这使用CloudWatch Logs 过滤器语法

要尾随日志而不跟随(在显示所请求日志的末尾后立即退出),请传递--disable-keep-open

$ zappa tail production --since 1h --disable-keep-open

远程函数调用

您可以随时使用该invoke命令直接执行应用程序中的任何功能。

例如,假设您在名为“my_app.py”的文件中有一个基本应用程序,并且您想要调用其中名为“my_function”的函数。部署应用程序后,您可以随时通过调用以下命令来调用该函数:

$ zappa invoke production my_app.my_function

所做的任何远程打印语句以及函数返回的值都将被打印到本地控制台。漂亮!

您还可以使用 直接调用可解释的 Python 3.8/3.9/3.10/3.11/3.12 字符串--raw,如下所示:

$ zappa invoke production "print(1 + 2 + 3)" --raw

例如,如果您想superuser在 VPC 中运行的 RDS 数据库(例如 Serverless Aurora)上创建第一个数据库,它会派上用场: $ zappa invoke staging "from django.contrib.auth import get_user_model; User = get_user_model(); User .objects.create_superuser('用户名', '电子邮件', '密码')" --raw

Django 管理命令

为了方便起见,Zappa 还可以使用该命令调用远程 Django 'manage.py' 命令manage。例如,要执行基本的 Django 状态检查:

$ zappa manage production showmigrations admin

显然,这只适用于正确定义设置的 Django 项目。

对于有自己的参数的命令,您还可以将命令作为字符串传递,如下所示:

$ zappa manage production "shell --version"

需要用户直接输入的命令(例如createsuperuser)应替换为使用 的命令zappa invoke <env> --raw

有关 Django 集成的更多信息,请查看zappa-django-utils项目。

SSL认证

可以使用自定义 SSL 证书、Let's Encrypt 证书和AWS Certificate Manager (ACM) 证书将 Zappa 部署到自定义域名和子域。

目前,其中最容易使用的是 AWS Certificate Manager 证书,因为它们是免费的、自我更新的,并且需要的工作量最少。

如下所述配置后,所有这些方法都使用相同的命令:

$ zappa certify

从 CI/CD 系统部署时,您可以使用:

$ zappa certify --yes

跳过确认提示。

使用 AWS Certificate Manager 部署到域

Amazon 提供了自己的 Let's Encrypt 的免费替代方案,称为AWS Certificate Manager (ACM)。要通过 Zappa 使用此服务:

  1. 在 AWS Certificate Manager 控制台中验证您的域。
  2. 在控制台中,选择弗吉尼亚北部 (us-east-1) 区域并为您的域或子域请求证书 ( sub.yourdomain.tld),或请求通配符域 ( *.yourdomain.tld)。
  3. 复制该证书的整个 ARN 并将其放置在 Zappa 设置中certificate_arn
  4. 在设置中设置您想要的域名domain
  5. 调用$ zappa certify以使用该证书创建并关联 API Gateway 分配。

使用 Let's Encrypt 证书部署到域(DNS 身份验证)

如果您想在具有免费 Let's Encrypt 证书并使用基于 Route 53 的 DNS 身份验证的域上使用 Zappa,您可以按照此便捷指南进行操作。

使用 Let's Encrypt 证书部署到域(HTTP 身份验证)

如果您想在具有使用 HTTP 身份验证的免费 Let's Encrypt 证书的域上使用 Zappa,您可以按照本指南进行操作。

但是,现在使用基于 Route 53 的 DNS 身份验证要容易得多,这将允许您通过单个命令使用 Let's Encrypt 证书$ zappa certify

使用您自己的 SSL 证书部署到域

  1. 第一步是创建自定义域并获取您的 SSL 证书/密钥/捆绑包。
  2. 确保您已domain在 Zappa 设置 JSON 中设置该设置 - 这将避免自定义域和 API 调用 URL 之间的基本路径映射出现问题,该 URL 会在 URI 中附加阶段名称
  3. 将 SSL 证书/密钥/包的路径分别添加到 Zappa 设置 JSON 中的certificatecertificate_key和设置certificate_chain
  4. 设置route53_enabled_false如果您计划使用自己的 DNS 提供商而不是 AWS Route53 托管区域,
  5. 使用 Zappa 部署或更新您的应用程序
  6. 运行$ zappa certify以上传您的证书并向您的 API 网关注册自定义域名。

响应 AWS 事件而执行

同样,您可以执行函数来响应 AWS 生态系统中发生的事件,例如 S3 上传、DynamoDB 条目、Kinesis 流、SNS 消息和 SQS 队列。

在您的zappa_settings.json文件中,定义您的事件源和您希望执行的函数。例如,这将your_module.process_upload_function响应my-bucketS3 存储桶中的新对象而执行。注意process_upload_function必须接受eventcontext参数。

{
    "production": {
       ...
       "events": [{
            "function": "your_module.process_upload_function",
            "event_source": {
                  "arn":  "arn:aws:s3:::my-bucket",
                  "events": [
                    "s3:ObjectCreated:*" // Supported event types: http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#supported-notification-event-types
                  ],
                  "key_filters": [{ // optional
                    "type": "suffix",
                    "value": "yourfile.json"
                  },
                  {
                    "type": "prefix",
                    "value": "prefix/for/your/object"
                  }]
               }
            }],
       ...
    }
}

进而:

$ zappa schedule production

现在,每次新上传的内容出现在您的存储桶中时,您的函数都会执行!

要访问应用程序上下文中的密钥信息,您需要process_upload_function如下所示:

import boto3
s3_client = boto3.client('s3')

def process_upload_function(event, context): """ Process a file upload. """

<span class="pl-c"># Get the uploaded file's information</span>
<span class="pl-s1">bucket</span> <span class="pl-c1">=</span> <span class="pl-s1">event</span>[<span class="pl-s">'Records'</span>][<span class="pl-c1">0</span>][<span class="pl-s">'s3'</span>][<span class="pl-s">'bucket'</span>][<span class="pl-s">'name'</span>] <span class="pl-c"># Will be `my-bucket`</span>
<span class="pl-s1">key</span> <span class="pl-c1">=</span> <span class="pl-s1">event</span>[<span class="pl-s">'Records'</span>][<span class="pl-c1">0</span>][<span class="pl-s">'s3'</span>][<span class="pl-s">'object'</span>][<span class="pl-s">'key'</span>] <span class="pl-c"># Will be the file path of whatever file was uploaded.</span>

<span class="pl-c"># Get the bytes from S3</span>
<span class="pl-s1">s3_client</span>.<span class="pl-en">download_file</span>(<span class="pl-s1">bucket</span>, <span class="pl-s1">key</span>, <span class="pl-s">'/tmp/'</span> <span class="pl-c1">+</span> <span class="pl-s1">key</span>) <span class="pl-c"># Download this file to writable tmp space.</span>
<span class="pl-s1">file_bytes</span> <span class="pl-c1">=</span> <span class="pl-en">open</span>(<span class="pl-s">'/tmp/'</span> <span class="pl-c1">+</span> <span class="pl-s1">key</span>).<span class="pl-en">read</span>()</pre><div class="zeroclipboard-container">
<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w" value="import boto3

s3_client = boto3.client('s3')

def process_upload_function(event, context): """ Process a file upload. """

# Get the uploaded file's information
bucket = event['Records'][0]['s3']['bucket']['name'] # Will be `my-bucket`
key = event['Records'][0]['s3']['object']['key'] # Will be the file path of whatever file was uploaded.

# Get the bytes from S3
s3_client.download_file(bucket, key, '/tmp/' + key) # Download this file to writable tmp space.
file_bytes = open('/tmp/' + key).read()" tabindex="0" role="button">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

同样,对于简单通知服务事件:

        "events": [
            {
                "function": "your_module.your_function",
                "event_source": {
                    "arn":  "arn:aws:sns:::your-event-topic-arn",
                    "events": [
                        "sns:Publish"
                    ]
                }
            }
        ]

您可以选择添加SNS 消息过滤器

        "events": [
            {
                "function": "your_module.your_function",
                "event_source": {
                    "arn":  "arn:aws:sns:::your-event-topic-arn",
                    "filters": {
                        "interests": ["python", "aws", "zappa"],
                        "version": ["1.0"]
                    },
                    ...
                }
            }
        ]

DynamoDBKinesis略有不同,因为它不是基于事件,而是从流中提取:

       "events": [
           {
               "function": "replication.replicate_records",
               "event_source": {
                    "arn":  "arn:aws:dynamodb:us-east-1:1234554:table/YourTable/stream/2016-05-11T00:00:00.000",
                    "starting_position": "TRIM_HORIZON", // Supported values: TRIM_HORIZON, LATEST
                    "batch_size": 50, // Max: 1000
                    "enabled": true // Default is false
               }
           }
       ]

SQS还从流中提取消息。此时,只有“Standard”队列可以触发lambda事件,而“FIFO”队列则不能。请仔细阅读 AWS 文档,因为一旦您的函数成功完成,Lambda 就会代表您调用 SQS DeleteMessage API。

       "events": [
           {
               "function": "your_module.process_messages",
               "event_source": {
                    "arn":  "arn:aws:sqs:us-east-1:12341234:your-queue-name-arn",
                    "batch_size": 10, // Max: 10. Use 1 to trigger immediate processing
                    "enabled": true // Default is false
               }
           }
       ]
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>

要配置 Lex Bot 的意图触发事件:

    "bot_events": [
        {
            "function": "lexbot.handlers.book_appointment.handler",
            "event_source": {
                "arn": "arn:aws:lex:us-east-1:01234123123:intent:TestLexEventNames:$LATEST", // optional. In future it will be used to configure the intent
                "intent":"intentName", // name of the bot event configured
                "invocation_source":"DialogCodeHook", // either FulfillmentCodeHook or DialogCodeHook
            }
        }
    ]

事件还可以采用关键字参数:

       "events": [
            {
                "function": "your_module.your_recurring_function", // The function to execute
                "kwargs": {"key": "val", "key2": "val2"},  // Keyword arguments to pass. These are available in the event
                "expression": "rate(1 minute)" // When to execute it (in cron or rate format)
            }
       ]

要获取关键字参数,您需要查看事件字典:

def your_recurring_function(event, context):
    my_kwargs = event.get("kwargs")  # dict of kwargs given in zappa_settings file

您可以在此处找到更多示例事件源

异步任务执行

Zappa 现在还提供在完全独立的 AWS Lambda 实例中无缝异步执行函数的能力!

例如,如果您有一个用于订购馅饼的 Flask API,您可以bake使用zappa.asynchronous.task装饰器在完全独立的 Lambda 实例中无缝调用您的函数,如下所示:

from flask import Flask
from zappa.asynchronous import task
app = Flask(__name__)

@task def make_pie(): """ This takes a long time! """ ingredients = get_ingredients() pie = bake(ingredients) deliver(pie)

@app.route('/api/order/pie') def order_pie(): """ This returns immediately! """ make_pie() return "Your pie is being made!"

<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w" value="from flask import Flask from zappa.asynchronous import task app = Flask(name)

@task def make_pie(): """ This takes a long time! """ ingredients = get_ingredients() pie = bake(ingredients) deliver(pie)

@app.route('/api/order/pie') def order_pie(): """ This returns immediately! """ make_pie() return "Your pie is being made!" " tabindex="0" role="button">

就是这样!您的 API 响应将立即返回,而该make_pie函数在完全不同的 Lambda 实例中执行。

当对 @task 修饰函数或 zappa.asynchronous.run 命令的调用发生在 Lambda 外部(例如您的本地开发环境)时,这些函数将立即在本地执行。zappa 异步功能仅在 Lambda 环境中或指定远程调用时才起作用。

捕获异常

在异步任务上放置 try.. except 块,如下所示:

@task
def make_pie():
    try:
        ingredients = get_ingredients()
        pie = bake(ingredients)
        deliver(pie)
    except Fault as error:
        """send an email"""
    ...
    return Response('Web services down', status=503)

将导致同一错误发送两次电子邮件。请参阅AWS 上的异步重试。要解决此副作用,并使故障处理程序仅执行一次,请将返回值更改为:

@task
def make_pie():
    try:
        """code block"""
    except Fault as error:
        """send an email"""
    ...
    return {} #or return True

任务来源

默认情况下,此功能使用直接 AWS Lambda 调用。您可以使用task_sns装饰器将 AWS Simple Notification Service 作为任务事件源,如下所示:

from zappa.asynchronous import task_sns
@task_sns

使用 SNS 还需要在您的 中进行以下设置zappa_settings

{
  "dev": {
    ..
      "async_source": "sns", // Source of async tasks. Defaults to "lambda"
      "async_resources": true, // Create the SNS topic to use. Defaults to true.
    ..
    }
}

这将自动创建并订阅您调用该命令时代码将使用的 SNS 主题zappa schedule

如果您需要跟踪您的调用,使用 SNS 还将返回消息 ID。

直接调用

您还可以通过将函数传递给 来在不使用装饰器的情况下使用此功能zappa.asynchronous.run,如下所示:

from zappa.asynchronous import run

run(your_function, args, kwargs) # Using Lambda run(your_function, args, kwargs, service='sns') # Using SNS

<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w" value="from zappa.asynchronous import run

run(your_function, args, kwargs) # Using Lambda run(your_function, args, kwargs, service='sns') # Using SNS" tabindex="0" role="button">

远程调用

默认情况下,Zappa 将使用 lambda 的当前函数名称和当前 AWS 区域。如果您希望使用不同的函数名称/区域调用 lambda 或从 lambda 外部调用 lambda,则必须指定 和 remote_aws_lambda_function_name参数remote_aws_region,以便应用程序知道要使用哪个函数和区域。例如,如果我们的披萨制作应用程序的某些部分必须驻留在 EC2 实例上,但我们希望在其自己的 Lambda 实例上调用 make_pie() 函数,我们将按如下方式执行:

@task(remote_aws_lambda_function_name='pizza-pie-prod', remote_aws_region='us-east-1')
def make_pie():
   """ This takes a long time! """
   ingredients = get_ingredients()
   pie = bake(ingredients)
   deliver(pie)

如果未使用这些 task() 参数,则 EC2 将在本地执行该函数。这些相同的 remote_aws_lambda_function_nameremote_aws_region参数也可以用在 zappa.asynchronous.run() 函数上。

限制

此功能存在以下限制:

  • 函数必须有一个干净的导入路径——即没有闭包、lambda 或方法。
  • args并且kwargs必须是 JSON 可序列化的。
  • JSON 序列化参数必须在 Lambda (256K) 或 SNS (256K) 事件的大小限制内。

所有这些代码仍然向后兼容非 Lambda 环境 - 它只是以阻塞方式执行并返回结果。

在VPC中运行任务

如果您在虚拟私有云 (VPC) 中运行 Zappa,则需要配置子网以允许 lambda 与 VPC 内的服务以及公共 Internet 进行通信。最小设置需要两个子网。

子网 a中:

  • 创建NAT
  • 创建互联网网关
  • 在路由表中,创建一条将 Internet 网关指向 0.0.0.0/0 的路由。

在子网-b中:

  • 放置您的 lambda 函数
  • 在路由表中创建一条指向subnet-a所属NAT到0.0.0.0/0的路由。

您可以将 lambda 放置在多个子网中,这些子网的配置方式与subnet-b相同,以实现高可用性。

一些有用的资源包括本教程其他教程AWS 文档页面

回应

可以捕获异步任务的响应。

Zappa 使用 DynamoDB 作为这些的后端。

要捕获响应,您必须配置async_response_tablein zappa_settings。这是 DynamoDB 表名称。然后,在用 装饰时@task,传递capture_response=True

异步响应被分配一个response_id. 它作为装饰器返回的LambdaAsyncResponse(或) 对象的属性返回。SnsAsyncResponse@task

例子:

from zappa.asynchronous import task, get_async_response
from flask import Flask, make_response, abort, url_for, redirect, request, jsonify
from time import sleep

app = Flask(name)

@app.route('/payload') def payload(): delay = request.args.get('delay', 60) x = longrunner(delay) return redirect(url_for('response', response_id=x.response_id))

@app.route('/async-response/<response_id>') def response(response_id): response = get_async_response(response_id) if response is None: abort(404)

<span class="pl-k">if</span> <span class="pl-s1">response</span>[<span class="pl-s">'status'</span>] <span class="pl-c1">==</span> <span class="pl-s">'complete'</span>:
    <span class="pl-k">return</span> <span class="pl-en">jsonify</span>(<span class="pl-s1">response</span>[<span class="pl-s">'response'</span>])

<span class="pl-en">sleep</span>(<span class="pl-c1">5</span>)

<span class="pl-k">return</span> <span class="pl-s">"Not yet ready. Redirecting."</span>, <span class="pl-c1">302</span>, {
    <span class="pl-s">'Content-Type'</span>: <span class="pl-s">'text/plain; charset=utf-8'</span>,
    <span class="pl-s">'Location'</span>: <span class="pl-en">url_for</span>(<span class="pl-s">'response'</span>, <span class="pl-s1">response_id</span><span class="pl-c1">=</span><span class="pl-s1">response_id</span>, <span class="pl-s1">backoff</span><span class="pl-c1">=</span><span class="pl-c1">5</span>),
    <span class="pl-s">'X-redirect-reason'</span>: <span class="pl-s">"Not yet ready."</span>,
}

@task(capture_response=True) def longrunner(delay): sleep(float(delay)) return {'MESSAGE': "It took {} seconds to generate this.".format(delay)}

<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w" value="from zappa.asynchronous import task, get_async_response from flask import Flask, make_response, abort, url_for, redirect, request, jsonify from time import sleep

app = Flask(name)

@app.route('/payload') def payload(): delay = request.args.get('delay', 60) x = longrunner(delay) return redirect(url_for('response', response_id=x.response_id))

@app.route('/async-response/<response_id>') def response(response_id): response = get_async_response(response_id) if response is None: abort(404)

if response['status'] == 'complete':
    return jsonify(response['response'])

sleep(5)

return &quot;Not yet ready. Redirecting.&quot;, 302, {
    'Content-Type': 'text/plain; charset=utf-8',
    'Location': url_for('response', response_id=response_id, backoff=5),
    'X-redirect-reason': &quot;Not yet ready.&quot;,
}

@task(capture_response=True) def longrunner(delay): sleep(float(delay)) return {'MESSAGE': "It took {} seconds to generate this.".format(delay)} " tabindex="0" role="button">

高级设置

您可以在本地设置中定义其他设置来更改 Zappa 的行为。使用这些需要您自担风险!

 {
    "dev": {
        "additional_text_mimetypes": [], // allows you to provide additional mimetypes to be handled as text when binary_support is true.
        "alb_enabled": false, // enable provisioning of application load balancing resources. If set to true, you _must_ fill out the alb_vpc_config option as well.
        "alb_vpc_config": {
            "CertificateArn": "your_acm_certificate_arn", // ACM certificate ARN for ALB
            "SubnetIds": [], // list of subnets for ALB
            "SecurityGroupIds": [] // list of security groups for ALB
        },
        "api_key_required": false, // enable securing API Gateway endpoints with x-api-key header (default False)
        "api_key": "your_api_key_id", // optional, use an existing API key. The option "api_key_required" must be true to apply
        "apigateway_enabled": true, // Set to false if you don't want to create an API Gateway resource. Default true.
        "apigateway_description": "My funky application!", // Define a custom description for the API Gateway console. Default None.
        "assume_policy": "my_assume_policy.json", // optional, IAM assume policy JSON file
        "attach_policy": "my_attach_policy.json", // optional, IAM attach policy JSON file
        "apigateway_policy": "my_apigateway_policy.json", // optional, API Gateway resource policy JSON file
        "async_source": "sns", // Source of async tasks. Defaults to "lambda"
        "async_resources": true, // Create the SNS topic and DynamoDB table to use. Defaults to true.
        "async_response_table": "your_dynamodb_table_name",  // the DynamoDB table name to use for captured async responses; defaults to None (can't capture)
        "async_response_table_read_capacity": 1,  // DynamoDB table read capacity; defaults to 1
        "async_response_table_write_capacity": 1,  // DynamoDB table write capacity; defaults to 1
        "aws_endpoint_urls": { "aws_service_name": "endpoint_url" }, // a dictionary of endpoint_urls that emulate the appropriate service.  Usually used for testing, for instance with `localstack`.
        "aws_environment_variables" : {"your_key": "your_value"}, // A dictionary of environment variables that will be available to your deployed app via AWS Lambdas native environment variables. See also "environment_variables" and "remote_env" . Default {}.
        "aws_kms_key_arn": "your_aws_kms_key_arn", // Your AWS KMS Key ARN
        "aws_region": "aws-region-name", // optional, uses region set in profile or environment variables if not set here,
        "binary_support": true, // Enable automatic MIME-type based response encoding through API Gateway. Default true.
        "callbacks": { // Call custom functions during the local Zappa deployment/update process
            "settings": "my_app.settings_callback", // After loading the settings
            "zip": "my_app.zip_callback", // After creating the package
            "post": "my_app.post_callback", // After command has executed
        },
        "cache_cluster_enabled": false, // Use APIGW cache cluster (default False)
        "cache_cluster_size": 0.5, // APIGW Cache Cluster size (default 0.5)
        "cache_cluster_ttl": 300, // APIGW Cache Cluster time-to-live (default 300)
        "cache_cluster_encrypted": false, // Whether or not APIGW Cache Cluster encrypts data (default False)
        "certificate": "my_cert.crt", // SSL certificate file location. Used to manually certify a custom domain
        "certificate_key": "my_key.key", // SSL key file location. Used to manually certify a custom domain
        "certificate_chain": "my_cert_chain.pem", // SSL certificate chain file location. Used to manually certify a custom domain
        "certificate_arn": "arn:aws:acm:us-east-1:1234512345:certificate/aaaa-bbb-cccc-dddd", // ACM certificate ARN (needs to be in us-east-1 region).
        "cloudwatch_log_level": "OFF", // Enables/configures a level of logging for the given staging. Available options: "OFF", "INFO", "ERROR", default "OFF".
        "cloudwatch_data_trace": false, // Logs all data about received events. Default false.
        "cloudwatch_metrics_enabled": false, // Additional metrics for the API Gateway. Default false.
        "cognito": { // for Cognito event triggers
            "user_pool": "user-pool-id", // User pool ID from AWS Cognito
            "triggers": [{
                "source": "PreSignUp_SignUp", // triggerSource from http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-pre-signup
                "function": "my_app.pre_signup_function"
            }]
        },
        "context_header_mappings": { "HTTP_header_name": "API_Gateway_context_variable" }, // A dictionary mapping HTTP header names to API Gateway context variables
        "cors": false, // Enable Cross-Origin Resource Sharing. Default false. If true, simulates the "Enable CORS" button on the API Gateway console. Can also be a dictionary specifying lists of "allowed_headers", "allowed_methods", and string of "allowed_origin"
        "dead_letter_arn": "arn:aws:<sns/sqs>:::my-topic/queue", // Optional Dead Letter configuration for when Lambda async invoke fails thrice
        "debug": true, // Print Zappa configuration errors tracebacks in the 500. Default true.
        "delete_local_zip": true, // Delete the local zip archive after code updates. Default true.
        "delete_s3_zip": true, // Delete the s3 zip archive. Default true.
        "django_settings": "your_project.production_settings", // The modular path to your Django project's settings. For Django projects only.
        "domain": "yourapp.yourdomain.com", // Required if you're using a domain
        "base_path": "your-base-path", // Optional base path for API gateway custom domain base path mapping. Default None. Not supported for use with Application Load Balancer event sources.
        "environment_variables": {"your_key": "your_value"}, // A dictionary of environment variables that will be available to your deployed app. See also "remote_env" and "aws_environment_variables". Default {}.
        "events": [
            {   // Recurring events
                "function": "your_module.your_recurring_function", // The function to execute (Pattern: [._A-Za-z0-9]+).
                "expression": "rate(1 minute)" // When to execute it (in cron or rate format)
            },
            {   // AWS Reactive events
                "function": "your_module.your_reactive_function", // The function to execute (Pattern: [._A-Za-z0-9]+).
                "event_source": {
                    "arn":  "arn:aws:s3:::my-bucket", // The ARN of this event source
                    "events": [
                        "s3:ObjectCreated:*" // The specific event to execute in response to.
                    ]
                }
            }
        ],
        "endpoint_configuration": ["EDGE", "REGIONAL", "PRIVATE"],  // Specify APIGateway endpoint None (default) or list `EDGE`, `REGION`, `PRIVATE`
        "exception_handler": "your_module.report_exception", // function that will be invoked in case Zappa sees an unhandled exception raised from your code
        "exclude": ["file.gz", "tests"], // A list of filename patterns to exclude from the archive (see `fnmatch` module for patterns).
        "exclude_glob": ["*.gz", "*.rar", "tests/**/*"], // A list of glob patterns to exclude from the archive. To exclude boto3 and botocore (available in an older version on Lambda), add "boto3*" and "botocore*".
        "extends": "stage_name", // Duplicate and extend another stage's settings. For example, `dev-asia` could extend from `dev-common` with a different `s3_bucket` value.
        "extra_permissions": [{ // Attach any extra permissions to this policy. Default None
            "Effect": "Allow",
            "Action": ["rekognition:*"], // AWS Service ARN
            "Resource": "*"
        }],
        "iam_authorization": false, // optional, use IAM to require request signing. Default false. Note that enabling this will override the authorizer configuration.
        "include": ["your_special_library_to_load_at_handler_init"], // load special libraries into PYTHONPATH at handler init that certain modules cannot find on path
        "authorizer": {
            "function": "your_module.your_auth_function", // Local function to run for token validation. For more information about the function see below.
            "arn": "arn:aws:lambda:<region>:<account_id>:function:<function_name>", // Existing Lambda function to run for token validation.
            "result_ttl": 300, // Optional. Default 300. The time-to-live (TTL) period, in seconds, that specifies how long API Gateway caches authorizer results. Currently, the maximum TTL value is 3600 seconds.
            "token_header": "Authorization", // Optional. Default 'Authorization'. The name of a custom authorization header containing the token that clients submit as part of their requests.
            "validation_expression": "^Bearer \\w+$", // Optional. A validation expression for the incoming token, specify a regular expression.
        },
        "keep_warm": true, // Create CloudWatch events to keep the server warm. Default true. To remove, set to false and then `unschedule`.
        "keep_warm_expression": "rate(4 minutes)", // How often to execute the keep-warm, in cron and rate format. Default 4 minutes.
        "lambda_description": "Your Description", // However you want to describe your project for the AWS console. Default "Zappa Deployment".
        "lambda_handler": "your_custom_handler", // The name of Lambda handler. Default: handler.lambda_handler
        "layers": ["arn:aws:lambda:<region>:<account_id>:layer:<layer_name>:<layer_version>"], // optional lambda layers
        "lambda_concurrency": 10, // Sets the maximum number of simultaneous executions for a function, and reserves capacity for that concurrency level. Default is None.
        "lets_encrypt_key": "s3://your-bucket/account.key", // Let's Encrypt account key path. Can either be an S3 path or a local file path.
        "log_level": "DEBUG", // Set the Zappa log level. Can be one of CRITICAL, ERROR, WARNING, INFO and DEBUG. Default: DEBUG
        "manage_roles": true, // Have Zappa automatically create and define IAM execution roles and policies. Default true. If false, you must define your own IAM Role and role_name setting.
        "memory_size": 512, // Lambda function memory in MB. Default 512.
        "ephemeral_storage": { "Size": 512 }, // Lambda function ephemeral_storage size in MB, Default 512, Max 10240
        "num_retained_versions":null, // Indicates the number of old versions to retain for the lambda. If absent, keeps all the versions of the function.
        "payload_compression": true, // Whether or not to enable API gateway payload compression (default: true)
        "payload_minimum_compression_size": 0, // The threshold size (in bytes) below which payload compression will not be applied (default: 0)
        "prebuild_script": "your_module.your_function", // Function to execute before uploading code
        "profile_name": "your-profile-name", // AWS profile credentials to use. Default 'default'. Removing this setting will use the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables instead.
        "project_name": "MyProject", // The name of the project as it appears on AWS. Defaults to a slugified `pwd`.
        "remote_env": "s3://my-project-config-files/filename.json", // optional file in s3 bucket containing a flat json object which will be used to set custom environment variables.
        "role_name": "MyLambdaRole", // Name of Zappa execution role. Default <project_name>-<env>-ZappaExecutionRole. To use a different, pre-existing policy, you must also set manage_roles to false.
        "role_arn": "arn:aws:iam::12345:role/app-ZappaLambdaExecutionRole", // ARN of Zappa execution role. Default to None. To use a different, pre-existing policy, you must also set manage_roles to false. This overrides role_name. Use with temporary credentials via GetFederationToken.
        "route53_enabled": true, // Have Zappa update your Route53 Hosted Zones when certifying with a custom domain. Default true.
        "runtime": "python3.12", // Python runtime to use on Lambda. Can be one of: "python3.8", "python3.9", "python3.10", "python3.11", or "python3.12". Defaults to whatever the current Python being used is.
        "s3_bucket": "dev-bucket", // Zappa zip bucket,
        "slim_handler": false, // Useful if project >50M. Set true to just upload a small handler to Lambda and load actual project from S3 at runtime. Default false.
        "settings_file": "~/Projects/MyApp/settings/dev_settings.py", // Server side settings file location,
        "tags": { // Attach additional tags to AWS Resources
            "Key": "Value",  // Example Key and value
            "Key2": "Value2",
            },
        "timeout_seconds": 30, // Maximum lifespan for the Lambda function (default 30, max 900.)
        "touch": true, // GET the production URL upon initial deployment (default True)
        "touch_path": "/", // The endpoint path to GET when checking the initial deployment (default "/")
        "use_precompiled_packages": true, // If possible, use C-extension packages which have been pre-compiled for AWS Lambda. Default true.
        "vpc_config": { // Optional Virtual Private Cloud (VPC) configuration for Lambda function
            "SubnetIds": [ "subnet-12345678" ], // Note: not all availability zones support Lambda!
            "SecurityGroupIds": [ "sg-12345678" ]
        },
        "xray_tracing": false // Optional, enable AWS X-Ray tracing on your lambda function.
    }
}

YAML 设置

如果您更喜欢 YAML 而不是 JSON,您也可以使用zappa_settings.yml,如下所示:

---
dev:
  app_function: your_module.your_app
  s3_bucket: your-code-bucket
  events:
  - function: your_module.your_function
    event_source:
      arn: arn:aws:s3:::your-event-bucket
      events:
      - s3:ObjectCreated:*

您还可以随时使用-s参数提供自定义设置文件,例如:

$ zappa deploy dev -s my-custom-settings.yml

同样,您可以提供一个zappa_settings.toml文件:

[dev]
  app_function = "your_module.your_app"
  s3_bucket = "your-code-bucket"

高级用法

保持服务器温暖

Zappa 将自动设置定期执行您的应用程序,以保持 Lambda 函数的正常运行。可以通过设置禁用此功能keep_warm

提供静态文件/二进制上传服务

Zappa 现在能够提供和接收二进制文件,如通过其 MIME 类型检测到的。

但是,一般来说,Zappa 是为运行应用程序代码而设计的,而不是为提供静态 Web 资产而设计的。如果您计划在 Web 应用程序中提供自定义静态资产(CSS/JavaScript/图像/等),您可能需要结合使用 AWS S3 和 AWS CloudFront。

您的 Web 应用程序框架可能能够自动为您处理此问题。对于 Flask,有Flask-S3,对于 Django,有Django-Storages

同样,您可能希望设计您的应用程序,以便静态二进制文件上传直接到 S3,然后触发您设置中定义的事件响应events!这就是无服务器思维!

启用 CORS

为 Zappa 应用程序启用 CORS(跨源资源共享)的最简单方法是在 Zappa 设置文件中设置corstrue更新,这相当于在 AWS API Gateway 控制台中按下“启用 CORS”按钮。默认情况下此功能处于禁用状态,但您可能希望为从其他域等访问的 API 启用它。

您还可以直接在应用程序中直接处理 CORS。您的 Web 框架可能会有一个扩展来执行此操作,例如django-cors-headersFlask-CORS。使用这些将使您的代码更加可移植。

大型项目

AWS 目前将 Lambda zip 大小限制为 50 MB。如果您的项目大于该值,请slim_handler: true在您的zappa_settings.json. 在这种情况下,您的胖应用程序包将被替换为仅包含处理程序的小型包。然后,处理程序文件在运行时从 S3 中拉取大型项目的其余部分!大型项目的初始负载可能会增加启动开销,但在热 lambda 函数上差异应该很小。请注意,这也会占用应用程序功能的存储空间。请注意,AWS支持/tmp512 - 10240 MB 范围内的自定义目录存储大小。如果您的项目大于默认的 512 MB,请使用ephemeral_storagein来调整您的需求。zappa_settings.json

启用 Bash 完成

可以通过将以下内容添加到 .bashrc 来启用 Bash 补全:

  eval "$(register-python-argcomplete zappa)"

register-python-argcomplete由 argcomplete Python 包提供。如果此软件包安装在 virtualenv 中,则必须在那里运行该命令。或者您可以执行:

activate-global-python-argcomplete --dest=-> 文件

该文件的内容应该来自于例如~/.bashrc。

在 API Gateway 上启用安全端点

API密钥

您可以使用该api_key_required设置为 API 网关的所有路由生成 API 密钥。流程如下:

  1. 部署/重新部署(更新不起作用)并记下已创建密钥的id
  2. 转到 AWS 控制台 > Amazon API Gateway 并
    • 选择“API Keys”并找到键值例如key_value
    • 选择“使用计划”,创建新的使用计划并链接 API 密钥和 Zappa 为您创建的 API
  3. 发送一个请求,您将键值作为标头传递,x-api-key以访问受限端点(例如使用curl:)curl --header "x-api-key: key_value"。请注意,如果没有 x-api-key 标头,您将收到 403。

身份管理政策

iam_authorization您可以通过将设置设置为来在 API 上启用基于 IAM(v4 签名)的授权true然后,您的 API 将需要签名请求,并且可以通过IAM 策略控制访问。未签名的请求将收到 403 响应,无权访问 API 的请求者也会收到 403 响应。启用此功能将覆盖授权者配置(见下文)。

API 网关 Lambda 授权者

如果您使用 Zappa 部署 API 端点,则可以利用API Gateway Lambda 授权程序来实现基于令牌的身份验证 - 您所需要做的就是提供一个函数来创建所需的输出,Zappa 会处理其余的事情。AWS 实验室蓝图示例是该功能的良好开端。

如果您想知道如何使用授权者,以下是一些潜在的用例:

  1. 调用 OAuth 提供商
  2. 内联解码 JWT 令牌
  3. 在自我管理的数据库(例如 DynamoDB)中查找

Zappa 可以配置为调用代码内的函数来进行授权,或者调用其他一些现有的 lambda 函数(它允许您在多个 lambda 之间共享授权者)。arn您可以通过指定或function_name中的值来控制行为authorizer

例如,要获取 Cognito 身份,请将其添加到zappa_settings.yaml

  context_header_mappings:
    user_id: authorizer.user_id

现在可以像这样在 Flask 中访问它:

from flask import request

@route('/hello') def hello_world: print(request.headers.get('user_id'))

<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w" value="from flask import request

@route('/hello') def hello_world: print(request.headers.get('user_id'))" tabindex="0" role="button">

Cognito 用户池授权者

您还可以通过添加以下内容来使用 AWS Cognito 用户池授权程序:

{
    "authorizer": {
        "type": "COGNITO_USER_POOLS",
        "provider_arns": [
            "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
        ]
    }
}

API网关资源策略

您还可以使用 API 网关资源策略。IP白名单示例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "1.2.3.4/32"
                    ]
                }
            }
        }
    ]
}

设置环境变量

本地环境变量

如果您想为部署阶段设置本地环境变量,您可以简单地在您的zappa_settings.json

{
    "dev": {
        ...
        "environment_variables": {
            "your_key": "your_value"
        }
    },
    ...
}

然后,您可以通过以下方式在应用程序中访问这些内容:

import os
your_value = os.environ.get('your_key')

如果您的项目需要了解部署到的环境类型,您还可以获取SERVERTYPE(AWS Lambda)、FRAMEWORK(Zappa)、PROJECT(您的项目名称) 和STAGE( devproduction等) 变量随时。

远程AWS环境变量

如果您想使用本机 AWS Lambda 环境变量,您可以使用aws_environment_variables配置设置。这些非常有用,因为您可以在运行时通过 AWS Lambda 控制台或 cli 轻松更改它们。它们对于存储敏感凭据和利用环境变量的 KMS 加密也很有用。

在开发过程中,您可以将 Zappa 定义的变量添加到本地运行的应用程序中,例如,使用以下内容(对于 Django,请管理.py)。

import json
import os

if os.environ.get('AWS_LAMBDA_FUNCTION_NAME') is None: # Ensures app is NOT running on Lambda json_data = open('zappa_settings.json') env_vars = json.load(json_data)['dev']['environment_variables'] os.environ.update(env_vars)

<clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w" value="import json import os

if os.environ.get('AWS_LAMBDA_FUNCTION_NAME') is None: # Ensures app is NOT running on Lambda json_data = open('zappa_settings.json') env_vars = json.load(json_data)['dev']['environment_variables'] os.environ.update(env_vars)" tabindex="0" role="button">

远程环境变量

您在 Zappa 外部设置的任何环境变量(通过 AWS Lambda 控制台或 cli)将保持运行时的原样update,除非它们也在 中aws_environment_variables,在这种情况下,远程值将被设置文件中的值覆盖。如果您使用 KMS 加密的 AWS 环境变量,则可以在aws_kms_key_arn设置中设置 KMS 密钥 ARN。在这种情况下,请确保您设置的值已加密。

注意:如果您依赖这些以及environment_variables,并且具有相同的键名称,那么 中 的键名称environment_variables将优先,因为它们被注入到 lambda 处理程序中。

远程环境变量(通过 S3 文件)

在 AWS 为 Lambda 引入本机环境变量(通过控制台和 cli)之前,S3 远程环境变量已添加到 Zappa。在走这条路线之前,请检查上述内容是否对您的用例更有意义。

如果您想使用远程环境变量来配置您的应用程序(这对于敏感凭证等内容特别有用),您可以创建一个文件并将其放置在您的 Zappa 应用程序可以访问的 S3 存储桶中。为此,请添加remote_env键添加到 zappa_settings 中,指向包含平面 JSON 对象的文件,以便每当新的 lambda 实例启动时,该对象上的每个键值对都将被设置为环境变量和值。

例如,为了确保您的应用程序可以访问数据库凭据而不将其存储在版本控制中,您可以使用连接字符串将文件添加到 S3,并使用配置设置将其加载到 lambda 环境中remote_env

super-secret-config.json(上传到 my-config-bucket):

{
    "DB_CONNECTION_STRING": "super-secret:database"
}

zappa_settings.json:

{
    "dev": {
        ...
        "remote_env": "s3://my-config-bucket/super-secret-config.json",
    },
    ...
}

现在在您的应用程序中您可以使用:

import os
db_string = os.environ.get('DB_CONNECTION_STRING')

API网关上下文变量

如果您想要将 API Gateway 上下文变量 ( http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html ) 映射到 HTTP 标头,您可以设置映射于zappa_settings.json

{
    "dev": {
        ...
        "context_header_mappings": {
            "HTTP_header_name": "API_Gateway_context_variable"
        }
    },
    ...
}

例如,如果您想要将 $context.identity.cognitoIdentityId 变量公开为 HTTP 标头 CognitoIdentityId,并将 $context.stage 公开为 APIStage,则需要:

{
    "dev": {
        ...
        "context_header_mappings": {
            "CognitoIdentityId": "identity.cognitoIdentityId",
            "APIStage": "stage"
        }
    },
    ...
}

捕获未处理的异常

默认情况下,如果代码中发生未处理的异常,Zappa 只会将堆栈跟踪打印到 CloudWatch 日志中。如果您希望使用外部报告工具来记录这些异常,则可以使用exception_handler配置选项。

zappa_settings.json:

{
    "dev": {
        ...
        "exception_handler": "your_module.unhandled_exceptions",
    },
    ...
}

该函数必须接受三个参数:异常、事件和上下文:

你的模块.py

def unhandled_exceptions(e, event, context):
    send_to_raygun(e, event)  # gather data you need and send
    return True # Prevent invocation retry

您的应用程序中可能仍然需要类似的异常处理程序,这只是捕获 Zappa/WSGI 层发生的异常(通常是基于事件的调用、错误配置的设置、错误的 Lambda 包和权限问题)的一种方法。

默认情况下,如果引发异常,AWS Lambda 将尝试重试基于事件(非 API 网关,例如 CloudWatch)的调用。但是,您可以通过返回 True 来防止这种情况,如上例所示,这样 Zappa 就不会重新引发未捕获的异常,从而阻止 AWS Lambda 重试当前调用。

使用自定义 AWS IAM 角色和策略

用于部署的自定义 AWS IAM 角色和策略

您可以通过定义设置来指定用于部署 Zappa 应用程序的本地profile_name配置文件,该设置将与您的 AWS 凭证文件中的配置文件相对应。

用于执行的自定义 AWS IAM 角色和策略

Zappa 创建的用于执行 Lambda 的默认 IAM 策略非常宽松。它授予对 CloudWatch、S3、Kinesis、SNS、SQS、DynamoDB 和 Route53 类型的所有资源的所有操作的访问权限;lambda:所有Lambda资源的InvokeFunction;放入所有 X-Ray 资源;以及对所有 EC2 资源的所有网络接口操作。虽然这允许大多数 Lambda 无需额外权限即可正常工作,但对于大多数持续集成管道或生产部署来说,这通常不是可接受的一组权限。相反,您可能需要手动管理您的 IAM 策略。

要手动定义 Lambda 执行角色的策略,您必须将manage_roles设置为 false 并在 Zappa 设置文件中定义role_namerole_arn 。

{
    "dev": {
        ...
        "manage_roles": false, // Disable Zappa client managing roles.
        "role_name": "MyLambdaRole", // Name of your Zappa execution role. Optional, default: <project_name>-<env>-ZappaExecutionRole.
        "role_arn": "arn:aws:iam::12345:role/app-ZappaLambdaExecutionRole", // ARN of your Zappa execution role. Optional.
        ...
    },
    ...
}

有关 Zappa 部署所需的最低策略要求的持续讨论可以在此处找到。管理这些权利的更强大的解决方案可能很快就会实施。

要将权限添加到默认 Zappa 执行策略,请使用以下extra_permissions设置:

{
    "dev": {
        ...
        "extra_permissions": [{ // Attach any extra permissions to this policy.
            "Effect": "Allow",
            "Action": ["rekognition:*"], // AWS Service ARN
            "Resource": "*"
        }]
    },
    ...
}

AWS X射线

Zappa 可以通过配置设置为您的函数启用AWS X-Ray支持:

{
    "dev": {
        ...
        "xray_tracing": true
    },
    ...
}

这将在 Lambda 函数上启用它,并允许您使用 X-Ray 检测代码。例如,使用 Flask:

from aws_xray_sdk.core import xray_recorder

app = Flask(name)

xray_recorder.configure(service='my_app_name')

@route('/hello') @xray_recorder.capture('hello') def hello_world: return 'Hello'

xray_recorder.configure(service='my_app_name')

@route('/hello') @xray_recorder.capture('hello') def hello_world: return 'Hello'" tabindex="0" role="button">

xray_recorder.begin_subsegment('subsegment_name')您可以使用捕获装饰器在函数周围或xray_recorder.end_subsegment()函数内创建子段。Python 的官方X-Ray 文档提供了有关如何在代码中使用它的更多信息。

请注意,您可以在代码中创建子段,但如果您尝试创建段,则会引发异常,因为它是由 lambda worker 创建的。这也意味着,如果您使用 Flask,则不得使用文档建议的 XRayMiddleware

全球可用的无服务器架构

全球 Zappa 拖鞋

单击查看伦敦 ServerlessConf 的幻灯片

在此init过程中,您将可以选择“全球”部署您的应用程序。这将允许您同时将应用程序部署到所有可用的 AWS 区域,以提供一致的全球速度、增强的冗余、数据隔离和法律合规性。您还可以选择仅部署到“主要”位置,即-1名称中包含的 AWS 区域。

要了解有关这些功能的更多信息,请参阅伦敦 ServerlessConf 的这些幻灯片。

提高 AWS 服务限制

AWS 开箱即用,为您的函数设置1000 个并发执行的限制。如果您开始违反这些限制,您可能会开始看到类似的错误ClientError: An error occurred (LimitExceededException) when calling the PutTargets.."或类似的内容。

为了避免这种情况,您可以向 Amazon 提交服务票证,将限制提高到您可能需要的数万个并发执行。这是亚马逊相当常见的做法,旨在防止您意外创建极其昂贵的错误报告。因此,在提高服务限制之前,请确保您没有任何恶意脚本,这些脚本可能会意外创建数万个您不想付费的并行执行。

死信队列

如果您想利用AWS Lambda 的死信队列功能,只需将键dead_letter_arn(值为完整的 ARN)添加到您的zappa_settings.json.

您必须已创建相应的 SNS/SQS 主题/队列,并且必须已为 Lambda 函数执行角色配置对 DLQ 资源的读取/发布/sendMessage 访问权限。

唯一的包裹ID

package_info.json为了监控不同的部署,应用程序包的根目录中提供了每个包的唯一 UUID 。您可以使用此信息或此文件的哈希值来执行以下操作:跟踪不同部署之间的错误、监控部署状态以及 Sentry 和 New Relic 等服务上的其他操作。该包裹将包含:

{
  "build_platform": "darwin",
  "build_user": "frank",
  "build_time": "1509732511",
  "uuid": "9c2df9e6-30f4-4c0a-ac4d-4ecb51831a74"
}

应用程序负载均衡器事件源

Zappa 可用于处理由应用程序负载均衡器 (ALB) 触发的事件。这在某些情况下很有用:

  • 由于 API Gateway 在超时前有 30 秒的硬限制,因此您可以使用 ALB 来处理运行时间较长的请求。
  • API网关按请求计费;因此,高吞吐量服务的成本可能会变得过高。如果您预计 Lambda 会有大量流量,那么 ALB 定价模型在财务上更有意义。
  • ALB 可以放置在 VPC 内,这对于私有终端节点来说可能比使用 API Gateway 的私有模型(使用 AWS PrivateLink)更有意义。

与 API Gateway 一样,Zappa 可以自动为您配置 ALB 资源。您需要将以下内容添加到您的zappa_settings

"alb_enabled": true,
"alb_vpc_config": {
    "CertificateArn": "arn:aws:acm:us-east-1:[your-account-id]:certificate/[certificate-id]",
    "SubnetIds": [
        // Here, you'll want to provide a list of subnets for your ALB, eg. 'subnet-02a58266'
    ],
    "SecurityGroupIds": [
        // And here, a list of security group IDs, eg. 'sg-fbacb791'
    ]
}

有关使用 ALB 作为 Lambda 事件源的更多信息,请参阅此处

重要提示:目前,Zappa 将为一个负载均衡器提供一个 lambda,这意味着base_path当前不支持与 ALB 配置一起使用。

端点配置

API网关可以配置为只能在VPC中访问。为了启用此功能;配置您的 VPC 以支持API 网关,然后设置endpoint_configurationPRIVATE设置资源策略。关于此的注释;如果您使用的是专用端点,Zappa 将无法判断 API 在部署或更新时是否返回成功的状态代码,因此您必须手动检查它以确保您的设置正常工作。

有关端点配置选项的完整列表,请参阅API Gateway EndpointConfiguration 文档

私有 API 网关配置示例

zappa_settings.json:

{
    "dev": {
        ...
        "endpoint_configuration": ["PRIVATE"],
        "apigateway_policy": "apigateway_resource_policy.json",
        ...
    },
    ...
}

apigateway_resource_policy.json:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpc": "{{vpcID}}" // UPDATE ME
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*"
        }
    ]
}

冷启动(实验性)

Lambda 可能会提供比冷启动初始化期间配置的额外资源。设置INSTANTIATE_LAMBDA_HANDLER_ON_IMPORT=True为在导入时实例化 lambda 处理程序。这是一项实验性功能 - 如果启动时间很关键,请考虑使用预置并发。

扎帕指南

扎帕在媒体上

使用 Zappa 的网站

你用的是扎帕吗?让我们知道,我们将在这里列出您的网站!

相关项目

  • Mackenzie - AWS Lambda 感染工具包
  • NoDB - 一个基于 S3 的简单、无服务器、Pythonic 对象存储。
  • zappa-cms - 一个小型的无服务器 CMS,适合忙碌的黑客。工作正在进行中。
  • zappa-django-utils - 帮助 Django 部署的实用命令。
  • 烧瓶询问 - 用于构建 Amazon Alexa 应用程序的框架。使用 Zappa 进行部署。
  • zappa-file-widget - 一个 Django 插件,用于支持 Zappa 上 Django 中的二进制文件上传。
  • zops - 使用 Zappa 进行团队和持续集成的实用程序。
  • cookiecutter-mobile-backend - 一个cookiecutter支持 Zappa 和 S3 上传的 Django 项目。
  • zappa-examples - Flask、Django、图像上传等等!
  • zappa-hug-example - 使用 Zappa 的 Hug 应用程序示例.
  • Zappa Docker Image - 基于 Lambda Docker 的用于在本地运行 Zappa 的 Docker 映像。
  • zappa-dashing - 使用 Zappa 和 CloudWatch 监控您的 AWS 环境(运行状况/指标).
  • s3env - 通过 CLI 操作 S3 存储桶中的远程 Zappa 环境变量键/值 JSON 对象文件。
  • zappa_resize_image_on_fly - 使用 Flask、Zappa、Pillow 和 OpenCV-python 动态调整图像大小。
  • zappa-ffmpeg - 在 lambda 内运行 ffmpeg 以进行无服务器转换。
  • gdrive-lambda - 将 json 数据传递到 csv 文件,供在整个组织中使用 Gdrive 的最终用户使用。
  • travis-build-repeat - 重复 TravisCI 构建以避免过时的测试结果.
  • wunderskill-alexa-skill - 用于添加到奇妙清单的 Alexa 技能.
  • xrayvision - 将 AWS X-Ray 与 Zappa 结合使用的实用程序和包装器.
  • terraform-aws-zappa - 用于创建 VPC、RDS 实例、ElastiCache Redis 和 CloudFront Distribution 以与 Zappa 一起使用的 Terraform 模块.
  • zappa-sentry - 与 Zappa 和 Sentry 集成
  • IOpipe - 监控、分析和分析您的 Zappa 应用程序。

黑客

Zappa 远远超出了 Lambda 和 API Gateway 的预期处理范围。因此,这里有很多技巧可以让它发挥作用。其中一些包括但不限于..

  • 使用 VTL 将正文、标头、方法、参数和查询字符串映射为 JSON,然后将其转换为有效的 WSGI。
  • 将响应代码附加到响应主体,对整个内容进行 Base64 编码,将其用作正则表达式来路由响应代码,在 VTL 中解码主体,并将响应主体映射到该主体。
  • 将多个 cookie打包并Base58编码为单个 cookie,因为我们只能映射一种。
  • 强制“Set-Cookie”的大小写排列,以便同时返回多个标头。
  • 将 cookie 设置 301/302 响应转换为 HTML 重定向的 200 响应,因为我们无法在重定向上设置标头。

贡献

非常欢迎您的贡献!

请在提交补丁之前提交讨论票。Pull 请求应该有针对性master,并且如果合并,Zappa 应该处于“可交付”状态。

如果您要添加大量新代码,请在 PR 中包含功能测试。对于 AWS 调用,我们使用该库,您可以在其 README 中placebo学习如何使用该库。一旦您打开拉取请求,测试套件将由Travis CI运行。

请包含 GitHub 问题或拉取请求 URL,其中包含与您的更改相关的讨论作为代码中的注释(示例)。这极大地有助于项目的可维护性,因为它使我们能够追溯用例并解释决策。同样,请确保您满足拉取请求模板中列出的所有要求。

请随意处理任何未处理的请求,尤其是任何标有“需要帮助”标签的请求。如果您遇到困难或想进一步讨论某个问题,请加入我们的 Slack 频道,在这里您会发现一个由聪明而有趣的人组成的社区,他们正在努力解决难题。 Zappa Slack 自动邀请

Zappa 并不打算遵守 PEP8,隔离您的提交,以便通过 linter 所做的更改来更改功能。

使用本地存储库

要使用 git HEAD,您可能无法使用pip install -e . 相反,您应该将存储库克隆到您的计算机,然后pip install /path/to/zappa/repo复制ln -s /path/to/zappa/repo/zappa zappa到您的本地项目中。

About

无服务器 Python

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 99.6%
  • Other 0.4%