AWS Lambda-在运行时从S3动态导入python模块

时间:2019-10-07 06:04:52

标签: amazon-s3 aws-lambda python-import

我有几十个python模块,每个模块都有一个通用方法(例如: run(params)),但是实现方式不同。我也有一个AWS Lambda,它将需要从那些模块之一中调用该方法。根据该lambda的输入选择哪个模块。

似乎我可以通过使用Lambda中的Layers来实现。 但是,如果我对所有这些模块使用一层,则可能会看到版本控制方面的问题。如果需要更新一个模块,则需要重新部署该层,这可能会给其他模块带来意想不到的更改。 如果我为每个模块使用一层,那么将要管理的层太多。

我想到了将每个模块放入一个单独的zip文件中,并将这些zip文件放入S3位置。然后,我的lambda将动态地从S3中读取所需的zip文件并执行。

这种方法可行吗?

====================

我当前的解决方案是拥有这样的东西:

def read_python_script_from_zip(bucket: str, key: str, script_name: str) -> str:
    s3 = boto3.resource('s3')

    raw = s3.Object(bucket, key).get()['Body'].read()
    zf = zipfile.ZipFile(io.BytesIO(raw), "r")
    scripts = list(filter(lambda f: f.endswith(f"/{script_name}.py"), zf.namelist()))
    if len(scripts) == 0:
        raise ModuleNotFoundError(f"{script_name} not found.")
    if len(scripts) > 1:
        raise ModuleNotFoundError(f"{script_name} is ambiguous.")

    source = zf.read(scripts[0])

    mod = ModuleType(script_name, '')
    exec(source, mod.__dict__)

    return mod

read_python_script_from_zip(source_bucket, source_key, module_name).run(params)

看起来让我复杂的是,希望有一种更简单的方法。

1 个答案:

答案 0 :(得分:0)

您可以尝试将每个模块打包为一个单独的分发包,这样可以分别对它们进行版本控制。但是,creating a Python distribution package并不像您希望的那么简单,特别是如果您要将其发布到S3上托管的私有存储库中。