跳转到主要内容

包裹羊...达

项目描述

Fleece

日志记录

要开始使用Fleece与Lambda项目,您需要对其项目进行2个小更新。

  • 在您通常导入logging.get_loggerlogging.getLogger的地方,使用fleece.log.get_loggerfleece.log.getLogger

  • 在包含您主要Lambda处理器的文件中,在设置任何其他日志记录之前包含fleece.log.setup_root_logger()

这应该确保根日志记录器的所有处理程序都会被清理,并且有一个具有适当流处理器的处理程序。

重试日志记录调用

还提供了一个用于偶尔失败的日志记录处理器的重试包装器。此包装器在防止调用外部服务(如CloudWatch)的日志记录调用失败时崩溃非常有用。

例如,考虑以下使用watchtower的CloudWatch处理程序

logger.addHandler(
    watchtower.CloudWatchLogHandler(log_group='WORKER-POLL',
                                    stream_name=str(uuid.uuid4()),
                                    use_queues=False))

如果CloudWatch服务不可用,或者限制了客户端,这将导致日志记录调用引发异常,这可能会中断脚本。为了避免这种情况,可以将watchtower处理程序包装在RetryHandler中,如下所示

logger.addHandler(
    fleece.log.RetryHandler(
        watchtower.CloudWatchLogHandler(log_group='WORKER-POLL',
                                        stream_name=str(uuid.uuid4()),
                                        use_queues=False)))

在上面的示例中,失败的日志记录调用将使用指数退避算法进行最多5次重试,以越来越大的间隔进行重试。如果所有重试都失败,则默认情况下,日志记录调用将默默地放弃并返回,允许程序继续。有关自定义重试策略的信息,请参阅RetryHandler类的文档。

为每个日志事件记录请求ID

将API网关和/或Lambda请求ID包含在每个日志事件中可能非常有用,这样就可以轻松地跟踪有问题的请求。如果将fleece.log.inject_request_ids_into_environment装饰器应用于Lambda处理函数,则会在日志事件字典中添加一个api_request_id(仅当事件源为API网关时)和一个lambda_request_id属性。

boto3包装器

此项目包括fleece.boto3.client()fleece.boto3.resource()包装器,它们支持比boto默认的60秒更友好的格式设置超时。以下额外的参数可以接受以设置这些超时

  • connect_timeout:以秒为单位的套接字连接超时。
  • read_timeout:以秒为单位的套接字读取操作超时。
  • timeout:设置上述两个的超时便利超时。

为了方便,可以在启动时调用fleece.boto3.set_default_timeout()全局设置超时。全局设置的超时将应用于所有客户端,除非明确覆盖。通过set_default_timeout()函数设置的默认超时适用于所有线程,因此最好在启动时调用此函数,在生成任何其他线程之前。

以下代码是对原始boto3包编写的示例,它使用默认的60秒套接字超时

import boto3
# ...
lambda = boto3.client('lambda')

如果您想使用15秒超时,只需切换到fleece包装器即可

from fleece import boto3
boto3.set_default_timeout(15)
# ...
lambda = boto3.client('lambda')

您可以导入其他boto3属性,但只有client()resource()接受本节中记录的额外参数。

requests包装器

此项目还包括对requests包的包装器。使用fleece.requests时,提供了设置超时和重试的便利访问。

高级请求函数,如requests.get()requests.post(),接受以下参数

  • timeout:网络超时,或包含连接和读取超时的元组,以秒为单位。请注意,这是requests包中存在的功能。
  • retries:与该请求一起使用的重试机制。此参数可以是几种类型之一:如果是 None,则使用由 set_default_retries 函数安装的默认重试机制;如果是整数,则表示要使用的重试次数;如果是字典,则必须包含一个 urllib3 Retry 实例的参数。或者,此参数也可以是一个 Retry 实例。

Session 类也被封装。从该模块创建的会话实例也接受上述两个参数,并将它们传递给它发出的任何请求。

最后,还可以安装全局超时和重试默认值,这些默认值用于任何未明确指定它们的请求。这使得现有的代码在将导入指向此封装版本的请求后,可以利用重试和超时。下面是一个设置全局超时和重试的示例:

from fleece import requests

# 15 second timeout
requests.set_default_timeout(15)

# 5 retries with exponential backoff, also retry 429 and 503 responses
requests.set_default_retries(total=5, backoff_factor=1,
                             status_forcelist=[429, 503])

# the defaults above apply to any regular requests, no need to make
# changes to existing code.
r = requests.get('https://...')

# a request can override the defaults if desired
r = requests.put('https://...', timeout=25, retries=2)

# sessions are also supported
with requests.Session() as session:
    session.get('https://...')

X-Ray 集成

该项目还填补了在 AWS X-RayLambda 集成 中缺少的 Python 支持。

先决条件

  1. 请确保将以下权限添加到您的函数的 Lambda 执行角色中:xray:PutTraceSegmentsxray:PutTelemetryRecords
  2. 在 AWS 控制台中 Lambda 函数的“配置”选项卡上的“高级设置”下启用活动跟踪(或使用 update_function_configuration API 调用)。

功能

您可以使用 @trace_xray_subsegment 装饰器标记任何函数或方法以进行跟踪。您可以将装饰器应用于任意数量的函数和方法,生成的跟踪将正确嵌套。您必须装饰所有要跟踪的方法(例如,如果仅装饰您的处理函数,则不会跟踪它调用的其他函数)。

此模块还提供了 botorequests 的封装,以便任何 AWS API 调用或 HTTP 请求都会自动由 X-Ray 跟踪,但您必须显式允许此行为,通过调用 monkey_patch_botocore_for_xray 和/或 monkey_patch_requests_for_xray。最佳位置是在定义 Lambda 入口点的主处理模块中执行此操作。

快速示例(handler.py

from fleece import boto3
from fleece.xray import (monkey_patch_botocore_for_xray,
                         trace_xray_subsegment)

monkey_patch_botocore_for_xray()


@trace_xray_subsegment()
def lambda_handler(event, context):
    return get_user()


def get_user():
    # This function doesn't have to be decorated, because the API call to IAM
    # will be traced thanks to the monkey-patching.
    iam = boto3.client('iam')
    return iam.get_user()

注意:猴子补丁跟踪也将与上述封装一起工作。

Connexion 集成

关于 Connexion 的摘要(来自他们的项目页面)

Connexion 是一个基于 Flask 的框架,它自动处理基于您 API 的 OpenAPI 2.0 规范(以前称为 Swagger 规范)的 HTTP 请求,该规范以 YAML 格式描述。Connexion 允许您编写 Swagger 规范,然后将端点映射到您的 Python 函数;这使得它独特,因为许多工具基于您的 Python 代码生成规范。您可以详细描述您的 REST API;然后 Connexion 保证它会按您指定的那样工作。

它是您的 API Gateway API 规范和 Lambda 函数之间的完美粘合剂。Fleece 使使用 Connexion 变得非常容易。

from fleece.connexion import call_api
from fleece.log import get_logger

logger = get_logger(__name__)


def lambda_handler(event, context):
    return call_api(event, 'myapi', 'swagger.yml', logger)

您只需确保将 swagger.yml 文件包含在 Lambda 打包中。对于 API Gateway 集成,我们目前假设 yoke 定义的 请求模板

使用此集成的好处是能够在本地运行您的 API,只需将类似以下内容添加到您的 Lambda 处理程序中:

from fleece.connexion import get_connexion_app

[...]

if __name__ == '__main__':
    app = get_connexion_app('myapi', 'swagger.yml')
    app.run(8080)

Fleece CLI

Fleece 提供了一个有限的 CLI 功能,以帮助构建 Lambda 打包并在具有 Rackspace Fanatical AWS 账户凭据的 shell 环境中运行命令。CLI 功能默认不安装,但可以作为额外包安装。注意:使用 Fleece 构建包需要 Docker。

安装

pip install fleece[cli]

羊毛构建

usage: fleece build [-h] [--python36] [--rebuild]
                    [--requirements REQUIREMENTS]
                    [--dependencies DEPENDENCIES] [--target TARGET]
                    [--source SOURCE]
                    [--exclude [EXCLUDE [EXCLUDE ...]]]
                    service_dir

Simple Lambda builder.

positional arguments:
  service_dir           directory where the service is located (default: $pwd)

optional arguments:
  -h, --help            show this help message and exit
  --python36, -3        use Python 3.6 (default: Python 2.7)
  --rebuild             rebuild Python dependencies
  --requirements REQUIREMENTS, -r REQUIREMENTS
                        requirements.txt file with dependencies (default:
                        $service_dir/src/requirements.txt)
  --dependencies DEPENDENCIES, -d DEPENDENCIES
                        comma separated list of system dependencies
  --target TARGET, -t TARGET
                        target directory for lambda_function.zip (default
                        $service_dir/dist)
  --source SOURCE, -s SOURCE
                        source directory to include in lambda_function.zip
                        (default: $service_dir/src)
  --exclude [EXCLUDE [EXCLUDE ...]], -e [EXCLUDE [EXCLUDE ...]]
                        glob pattern to exclude

从服务的顶层目录构建lambda包

$ fleece build .

上述命令做出的假设是,服务的源代码在./src,需求文件在./src/requirements.txt,输出zip文件将写入到./dist。这些默认值可以通过--source--requirements--target选项分别更改。

构建过程将在基于Amazon Linux镜像的Docker容器中运行。如果需要在安装Python需求之前在容器中安装额外的依赖项,可以使用--dependencies选项提供。任何pip识别的环境变量,如PIP_INDEX_URL,都将传递到容器中。

羊毛运行

usage: fleece run [-h] [--username USERNAME] [--apikey APIKEY]
                  [--config CONFIG] [--account ACCOUNT]
                  [--environment ENVIRONMENT] [--role ROLE]
                  command

Run command in environment with AWS credentials from Rackspace FAWS API

positional arguments:
  command               Command to execute

optional arguments:
  -h, --help            show this help message and exit
  --username USERNAME, -u USERNAME
                        Rackspace username. Can also be set via RS_USERNAME
                        environment variable
  --apikey APIKEY, -k APIKEY
                        Rackspace API key. Can also be set via RS_API_KEY
                        environment variable
  --config CONFIG, -c CONFIG
                        Path to YAML config file with defined accounts and
                        aliases. Default is ./environments.yml
  --account ACCOUNT, -a ACCOUNT
                        AWS account number. Cannot be used with
                        `--environment`
  --environment ENVIRONMENT, -e ENVIRONMENT
                        Environment alias to AWS account defined in config
                        file. Cannot be used with `--account`
  --role ROLE, -r ROLE  Role name to assume after obtaining credentials from
                        FAWS API
# fleece run --username $username --apikey $apikey --account $account 'aws s3 ls'
2017-10-02 12:03:18 bucket1
2017-06-08 14:31:07 bucket2
2017-08-10 17:28:47 bucket3
2017-08-10 17:21:58 bucket4
2017-08-15 20:33:02 bucket5

您还可以设置一个环境文件以减少命令行标志。确保账户被引号包围,以确保它们不会被错误地解释为整数或八进制数。

# cat environments.yml
environments:
  - name: development
    account: '123456789012'
  - name: staging
    account: '123456789012'
    rs_username_var: MY_RS_USERNAME
    rs_apikey_var: MY_RS_APIKEY
  - name: testing
    account: '123456789012'
  - name: production
    account: '123456789012'
    role: LambdaDeployRole

# fleece run --username $username --apikey $apikey --environment testing 'aws s3 ls'
2017-10-02 12:03:18 bucket1
2017-06-08 14:31:07 bucket2
2017-08-10 17:28:47 bucket3
2017-08-10 17:21:58 bucket4
2017-08-15 20:33:02 bucket5

注意上面提供的staging环境示例,它提供了一个自定义的环境变量对,其中Rackspace用户名和API密钥来自该对。这些只有在凭证不是作为命令的一部分明确给出时才会使用。

羊毛配置

usage: fleece config [-h] [--config CONFIG] [--username USERNAME]
                     [--apikey APIKEY] [--environments ENVIRONMENTS]
                     {import,export,edit,render} ...

Configuration management

positional arguments:
  {import,export,edit,render}
                        Sub-command help
    import              Import configuration from stdin
    export              Export configuration to stdout
    edit                Edit configuration
    render              Render configuration for an environment

optional arguments:
  -h, --help            show this help message and exit
  --config CONFIG, -c CONFIG
                        Config file (default is config.yml)
  --username USERNAME, -u USERNAME
                        Rackspace username. Can also be set via RS_USERNAME
                        environment variable
  --apikey APIKEY, -k APIKEY
                        Rackspace API key. Can also be set via RS_API_KEY
                        environment variable
  --environments ENVIRONMENTS, -e ENVIRONMENTS
                        Path to YAML config file with defined accounts and
                        environment names. Defaults to ./environments.yml

fleece config命令有几个子命令,用于处理配置文件。有多个适用于所有命令的参数。

  • --config设置配置文件。这是一个包含配置的文件,格式适合提交到源控制(即,敏感变量是加密的)。
  • --username--apikey是Rackspace凭证,用于从FAWS获取临时AWS访问凭证。为了方便,这些可以设置为环境变量。
  • --environments是定义不同环境及其相关AWS账户的environments.yml文件。格式如fleece run命令中所述。

配置命令与两种类型的配置文件一起工作。config.yml文件是一个“关闭”配置文件,其中所有敏感值都是加密的。开发者通常不会编辑此文件,而是将其导出到一个临时的“开放”配置文件中,其中敏感变量以纯文本形式出现,以便编辑。一旦进行了更改,开放配置文件就会导入回关闭的config.yml

开放配置格式如下

stages:                                 # stage definitions
  prod:                                 # stage name
    environment: prod                   # environment associated with this stage
    key: prod-key-here                  # KMS key, ARN or name with or without the "alias/" prefix are all valid
  /.*/:                                 # regular expressions for custom stage names
    environment: dev
    key: dev-key-here
config:
  foo: bar                              # plain text variable
  password:                             # per-stage values, encrypted
    +dev: :encrypt:my-dev-password      # per-stage keys must have a "+" prefix so they are
    +prod: :encrypt:my-prod-password    # not taken as a nested dict
    +/.*/: :encrypt:my-custom-password
  nested:                               # nested dictionaries
    inner_var: value
    a_list:                             # list of dictionaries
      - username1:                      # per-stage values, without encryption
          +prod: bob-prod
          +/.*/: bob-dev
        password1:                      # per-stage values, encrypted
          +prod: :encrypt:bob-prod-pw
          +/.*/: :encrypt:bob-dev-pw
      - username2: user2
        password2:
          +prod: :encrypt:prod-pw2
          +/.*/: :encrypt:dev-pw2

stages部分定义了可用的阶段,以及它们与环境和KMS密钥的关联。环境必须在environments.yml中定义,以将阶段链接到AWS账户。KMS密钥可以给出为ARN或别名。别名可以带或不带alias/前缀。阶段名称可以明确给出,也可以作为正则表达式(用/包围)。当羊毛需要匹配其命令中给出的一个阶段名称时,它将首先尝试进行等式匹配,只有在失败时才会尝试基于正则表达式的阶段名称。正则表达式阶段名称按随机顺序评估,直到成功为止,因此避免正则表达式模式中的歧义很重要。

config部分是定义配置变量的地方。本节中的标准键/值对代表将提供给所有阶段的纯文本变量。可以通过将值设置为子字典,其中键是带有+前缀的阶段名称,为每个阶段提供变量值。也支持阶段名称的正则表达式模式。

任何需要加密的敏感变量都必须有每个阶段的值,并且这些值必须带有:encrypt:前缀,这样羊毛就知道在配置导入并存储到config.yml时加密它们。

可用的子命令有

羊毛配置导入

stdin读取源配置文件并写入config.yml文件。输入数据可以是YAML或JSON格式。

羊毛配置导出 [--json]

config.yml 的内容以开放格式写入 stdout 以便编辑。默认情况下,此命令输出 YAML 文件。使用 --json 以 JSON 格式输出。

fleece config edit [--json] [--editor EDITOR]

此命令将配置导出到临时文件,然后在此文件上启动文本编辑器(默认为 vi)。在编辑器关闭后,修改的文件将被重新导入。这是编辑配置的最便捷工作流程。

fleece config render [--environment] [--json] [--encrypt] [--python] [--parameter-store PARAMETER_STORE_PREFIX] [--ssm-kms-key SSM_KMS_KEY] <阶段>

将给定环境的配置变量写入 stdout 或上传到参数存储。有四种输出选项:YAML 明文(默认),JSON 明文(带有 --json),加密 JSON(带有 --encrypt)和加密 Python 模块(带有 --python)。

上传到 SSM 的参数默认加密,使用默认的 SSM 加密密钥。如果您想使用自定义 KMS 密钥来加密参数,请使用 --ssm-kms-key 选项。对于此值,您可以传入 KMS 密钥 ID、ARN、别名名称或别名 ARN。此功能使参数在部署时间从 SSM 复制到 Lambda 函数环境配置成为可能,并为该函数配置自定义 KMS 密钥以在运行时解密配置。

加密配置由需要解密和附加的加密缓冲区列表组成。此操作的输出是 JSON 明文配置。以下输出是 --python 的输出,其中包含解密和解码逻辑

ENCRYPTED_CONFIG = ['... encrypted blob here ...']
import base64
import boto3
import json

def load_config():
    config_json = ''
    kms = boto3.client('kms')
    for buffer in ENCRYPTED_CONFIG:
        r = kms.decrypt(CiphertextBlob=base64.b64decode(buffer.encode(
            'utf-8')))
        config_json += r['Plaintext'].decode('utf-8')
    return json.loads(config_json)

CONFIG = load_config()

如果将其保存为源目录中的 fleece_config.py,则可以使用

from fleece_config import CONFIG

如果指定了 --parameter-store,则下一个参数必须是用于上传到参数存储的所有变量的前缀。这应以斜杠开头。

例如,如果参数是 --parameter-store /super-service/some-id,并且配置中有一个名为 foo 的值,那么 fleece 将创建或覆盖一个名为 /super-service/some-id/foo 的安全字符串参数存储值,其值为 foo 的解密配置值。

所有值在保存到参数存储之前都转换为字符串。如果配置有嵌套字典,则将保存多个参数存储值(因此在上面的示例中,具有值为 innernested 字段将被保存为 /super-service/some-id/nested/inner)。

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

fleece-1.2.1.tar.gz (54.1 kB 查看哈希值)

上传时间 源代码

构建分发

fleece-1.2.1-py3-none-any.whl (52.4 kB 查看哈希值)

上传时间 Python 3

由以下提供支持