如何使用Python在无服务器的环境中正确共享代码? [英] How to share code in serverless with Python properly?

查看:44
本文介绍了如何使用Python在无服务器的环境中正确共享代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到使用Python进行健壮的无服务器开发的最佳方法.该项目使用无服务器框架分为多个服务,并在monorepo中进行版本控制.这是我想要的结构:

I'm trying to find the best approach for robust serverless development with Python. The project is divided into multiple services using the serverless framework and versioned in a monorepo. Here's the structure I'd like to have:

  • service_1/
    • serverless.yml
    • handler.py
    • serverless.yml
    • handler.py
    • module_a.py
    • module_b.py

    module_a和module_b包含共享逻辑,这两个服务都应该可用.到目前为止,我发现了两种方法:将共享代码包装在可安装的程序包中,然后通过pip将其注入服务或提供共享代码作为一层.两种解决方案都有缺陷,最重要的是不可能快速开发应用程序,因为任何更改都需要点子.我注意到这个问题已在Node.js中解决,并且有许多关于Python的未解之谜.

    module_a and module_b comprise shared logic, which should be available for both services. So far I've found 2 approaches: wrap shared code in an installable package and inject it to services via pip or provide shared code as a layer. Both solutions have flaws, most importantly it's impossible to rapidly develop the app because any change requires pip. I've noticed this problem is solved in Node.js and there are many unanswered questions about Python.

    插件-serverless-package-common,它似乎可以解决此问题问题,但它看起来并不像是优先选择的方法.

    There is the plugin - serverless-package-common, which seems to tackle this issue, however, it doesn't look like a go-first approach.

    我感谢任何形式的帮助.

    I appreciate any form of help.

    推荐答案

    也许您可以考虑使用Lambda层.您可以在此处找到快速指南:链接.

    Maybe you can consider to use Lambda layer. You can find a quick guide here: link.

    让我给你一个简单的例子.此示例有两个无服务器项目-具有共享代码的 library 和具有服务代码的 service .

    Let me give you a simple example. This example has two serverless projects - library which has shared code and service which has service codes.

    1. -该项目应具有以下文件结构.您在此项目的根目录中有 serverless.yml ,另一个目录将作为模块导出.当将lambda与python结合使用时, python 将被链接,并让lambda查找您的模块.
    1. library - This project should have below file structure. You have serverless.yml in the root of this project and another folder which will be export as a module. python will be linked and let lambda find your module when you use lambda with python.

    ./
    └ serverless.yml
    └ common/
        └ python/
            └ Common.py
    

    serverless.yml-如您所见,文件夹 common 在此明确声明要导出.请注意,层名称 Common 已在资源中重用,并且无服务器框架会自动将其与资源引用匹配.

    serverless.yml - As you can see, folder common is explicitly declared here to be exported. Beware that layer name Common is re-used in resources and serverless framework will automatically match this with resource reference.

    service: library
      provider:
        name: aws
        runtime: python3.7
        stage: dev
        region: ap-northeast-1
      layers:
        Common:
          path: common
      resources:
        Outputs:
          CommonLayerExport:
            Value:
              Ref: CommonLambdaLayer
            Export:
              Name: CommonLambdaLayer
    

    common/python/Common.py( printException 是将在另一个项目中使用的共享函数的示例)

    common/python/Common.py (printException is an example of shared function which will be used in another project)

    import sys
    import traceback
    import os
    
    def printException(exception, writer=None):
        if writer is None:
          writer = print
        top = traceback.extract_tb(sys.exc_info()[2])[-1]
        writer(", ".join([type(exception).__name__, str(sys.exc_info()[1]), os.path.basename(top[0]), str(top[1])]))
    

    1. 服务serverless.yml-如您所见,每个函数都应包含层,并且您可以使用CloudFormation参考来引用特定层.
    1. service serverless.yml - As you can see, layers should be included per each functions and you can refer to a specific layer with CloudFormation reference.

    service: layer-test
      provider:
        name: aws
        region: ap-northeast-1
        runtime: python3.7
        stage: dev
      functions:
        exceptionExample:
          handler: handler.func
          layers:
            - ${cf:library-dev.CommonLayerExport}
          events:
            - http:
                path: exceptionExample
                method: get
    

    handler.py-现在,我们可以轻松地从共享层导入共享模块.

    handler.py - Now we can easily import shared module from shared layer.

    import json
    import Common
    
    def func(event, context):
        try:
            1/0 # just to raise an exception and test the shared function
        except Exception as e:
            Common.printException(e)
    
        response = {
            "statusCode": 200,
        }
        return response
    

    您应该注意的一件事是,由于lambda层不打包导入的模块,因此您也应该导入层中在服务中使用的模块.

    One thing you should be careful is that as lambda layer does not pack imported modules, you should import modules which is used by your layer in your services as well.

    这篇关于如何使用Python在无服务器的环境中正确共享代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆