【问题标题】:Creating an on-the-fly zip file from string content for AWS Lambda in Python在 Python 中为 AWS Lambda 的字符串内容创建动态 zip 文件
【发布时间】:2016-08-01 01:59:28
【问题描述】:

我有一个 Python 脚本,可以在 AWS 中创建一个 Lambda 脚本以及所有策略和触发器。我为此使用 python boto3 库。我为 lambda 即时创建 zip 文件,而不是从硬盘驱动器上传静态 zip 文件。我使用下面的这个简单代码来创建我的 zip 文件。它可以毫无问题地创建 zip 文件,我的 python 代码将此 zip 文件作为 lambda 脚本上传,我可以在 AWS 中查看我的 lambda 脚本而没有任何问题。但是当我运行我的 lambda 脚本时,它给了我找不到模块的错误,即使我可以清楚地看到模块名和文件名确实存在并且可以查看。

无法导入模块“xxxx”:没有名为 xxxx 的模块

在文件系统中,我双击此代码创建的 zip 文件,看到内容已创建,一切正常。

如果我绕过动态压缩并使用 WinZip 静态创建 zip 并让 Python 和 boto3 脚本的其余部分上传此文件,那么它就可以正常工作。

def CreateLambdaZip(self, fileName, fileContent):
    with zipfile.ZipFile('Lambda/' + fileName + '.zip', 'w') as myzipc:
        myzipc.writestr( fileName + '.py', fileContent)
        myzipc.close()

对于 zip 文件,我似乎跳过了 Aws Lambda 所需的一些特殊标头。有这种事吗?因为在文件系统中,由 Python 代码创建的 zip 文件与由 WinZip 创建的另一个文件完全相同。所以我知道 lambda 脚本没有任何问题。

更新:我正在使用以下代码上传 zip 文件,该代码读取使用上述 sn-p 创建的 zip 文件。

with open('Lambda/'+ fileName +'.zip', 'rb') as zipFile:
    func = boto3.client("Lambda").create_function(
                FunctionName=lambdaFunction,
                Runtime='python2.7',
                Role=role['Role']['Arn'],
                Handler= fileName + "." + functionName,
                Description=description,
                Timeout=10,
                MemorySize=256,
                Publish=True,
                Code={'ZipFile': zipFile.read()},
            )

当我使用 zipFile.read() 时,当我使用 WinZip 压缩它时,当我使用 Python 的模块压缩它时,我会为相同的内容获得 2 个不同的标题。 使用 Python 以编程方式创建的 Zip 文件

b'PK\x03\x04\x14\x00\x00\x00\x00\x00\xe4~\x01IO\x96J=Z\x07\x00\x00Z\x07\x00\x00\x19\x00\x00\x00schedule-ec2-snapshots.pyimport json\nimport boto3\nimport time\nfrom datetime import date, timedelta\n\nprint(\'Loading scheduled EC2 backup actions\')\n\ndef create_snapshots(event, context):\n    """\n    Lambda function that executes daily snapshots for the instances that

和由 WinZip 创建的压缩文件

b'PK\x03\x04\x14\x00\x02\x00\x08\x004X\xfcH\x88\x1f\xce\xb5&\x03\x00\x00b\x07\x00\x00\x19\x00\x00\x00schedule-ec2-snapshots.py\x8dU]k\xdb@\x10|7\xf4?,\nA\x12qL\xda\x06B\r~I\x93Bh\x9b\x87&\xf4E\x15\xe1\xac[\xdb\xd7HwBw2\t\xc1\xff\xbd{+\xeb\xcb.\xb4\n\xc4\xba\xdb\xd1\xec\xce\xdc\xae\xa4\x8a\xd2T\x0e~[\xa3\'\xaa\xb9_\x1ag>\xb6\x0b\xa7\n\x9c\xac*S\x80\x14\x0e\xfd\n\xf6\x11\xbf\x9er\\b\xee\xc4dRVJ\xbb(\xfcf\x84Tz\r6\xdb\xa0\xacs\x94p\xfb\xf9\x03,E\xf6\\\x97 

【问题讨论】:

  • 尝试从命令行解压文件。它写了什么?
  • 你如何上传这个 zip 存档,你正在使用什么/如何使用 cli 命令?
  • @b.b3rn4rd 我没有使用 CLI。我正在运行一个使用 boto3.client("lambda").create_function 的 py 脚本。更新了上面的代码
  • @KarenB 是的,这可能与您从 zipfile 中读取的内容有关。当我在调试时尝试读取 zip 文件时,我看到相同字符串内容的不同二进制内容。更新了上面的代码

标签: python amazon-web-services lambda zipfile


【解决方案1】:

通过以上信息,我能够启动内存解决方案。该 zip 文件的部署有效,但我无法使用生成的功能。出现错误:

Unable to import module '<function-name>': No module named <function-name>

我通过指定文件权限让它工作。

然后我使用 in-mem-zip 创建一个 AWS lambda 函数。

设置: file_map 是 full_path->file_bytes 的字典。 files 是完整路径的列表

def create_lambda_function(function_name, desc, role, handler, file_map, files)
    zip_contents = create_in_mem_zip_archive(file_map, files)

    result = lambda_code.create_function(
        FunctionName=function_name,
        Runtime="python2.7",
        Description=desc,
        Role=role,
        Handler=handler,
        Code={'ZipFile': zip_contents},
    )
    return result

def create_in_mem_zip_archive(file_map, files):
    buf = io.BytesIO()
    logger.info("Building zip file: " + str(files))
    with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zfh:
        for file_name in files:
            file_blob = file_map.get(file_name)
            if file_blob is None:
                logger.error("Missing file {} from files".format(file_name))
                continue
            try:
                info = zipfile.ZipInfo(file_name)
                info.date_time = time.localtime()
                info.compress_type = zipfile.ZIP_DEFLATED
                info.external_attr = 0777 << 16L  # give full access
                # info.external_attr = 0644 << 16L  # -r-wr--r--
                # info.external_attr = 0755 << 16L  # -rwxr-xr-x
                zfh.writestr(info, file_blob)
            except Exception as ex:
                logger.info("Error reading file: " + file_name + ", error: " + ex.message)
    buf.seek(0)
    return buf.read()

【讨论】:

    【解决方案2】:

    我遇到了与您完全相同的问题。我的解决方案是不要使用动态 zip 文件。创建一个真实的 zip 文件并将真实文件添加到其中,它就可以工作了。即使在 lambda 环境中,您也可以这样做,通过创建像“/tmp/yourfile.txt”这样的文件路径,您可以在 lambda 执行时创建临时真实文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 2022-01-10
      • 2022-11-04
      • 2012-04-20
      • 2017-01-21
      • 1970-01-01
      相关资源
      最近更新 更多