使用Python中的AWS Lambda的字符串内容创建即时zip文件

时间:2016-08-01 01:59:29

标签: python amazon-web-services lambda zipfile

我有一个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创建的另一个zip文件完全相同。所以我知道lambda脚本没有错。

更新:我使用以下代码上传zip文件,该代码读取使用上述代码段创建的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创建的zipfile

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 

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

通过上面的信息,我能够启动内存中的解决方案。该zip文件的部署工作正常,但是我无法使用结果函数。出现错误:

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

我通过指定文件许可权使其起作用。

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

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

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()