【问题标题】:How to add option with Click CLI and pass the option correctly into functions?如何使用 Click CLI 添加选项并将选项正确传递给函数?
【发布时间】:2020-07-30 16:00:20
【问题描述】:

我正在学习我的第一门编程课程,如果问题过于幼稚,请见谅。 我正在使用 Python Boto3 模块和“Click”库来构建管理 EC2 实例的命令行界面。 代码:

@click.group()
@cli.group('instances')
def instances():
    pass
@instances.command('list')
@click.option('--project', default=None,help='List instances by project tag, e.g. -project = <project name>')
def list_instances(project):
    'List EC2 instances'
    instances = filter_project_instances(project)
    for i in instances:
            print(', '.join((
            i.id,
            i.instance_type,
        )))
        return

@cli.group('volumes')
#Details of this 'volumes' command are omitted for simplification 

基本上,“单击”允许我使用命令(例如实例、卷)、子命令(列表)和选项(--project)来包装我的函数。 这样的命令行: shotty.py 实例列表 --project Valkyrie 可以列出标记为“Valkyrie”的实例

现在,我需要在此命令行中添加一个选项来指定我想用来登录的 AWS 配置文件。该配置文件是使用“aws configure --profile [profile name]”命令创建的(配置文件名称可以是 Dan、Kyle 等):

shotty.py --profile [配置文件名称] 实例列表

最初,我硬编码配置文件名称,并使用 sessionec2 作为任何其他函数都可以使用的全局变量。

import boto3
import botocore
import click

session = boto3.Session(profile_name='Dan')
ec2 = session.resource('ec2')

虽然实现了上述要求,但基于 'Click' 文档,我必须执行以下操作才能添加这样的 '--profile' 选项:

@click.group()
@click.option('--profile', default=None,help='Select the AWS profile')
def cli(profile):
   session = boto3.Session(profile_name=profile)
   ec2 = session.resource('ec2')

但现在,sessionec2 不再可用于其他功能。 这个 cli() 函数就像脚本的入口点,在 main() 函数中被撤销:

if __name__ == '__main__':
    cli()

我能想到的唯一方法是创建一个单独的函数

  def session(profile):
        session = boto3.Session(profile_name=profile)
        ec2 = session.resource('ec2')
        return ec2

但是现在这带来了另一个问题,我必须将 profile 作为参数添加到所有其他函数,例如

def filter_project_instances(project, profile):
        'Filter EC2 instances'
        ec2 = session(profile)
        instances = ec2.instances.all()
        return instances

这意味着我必须在这个 filter_project_instances 函数中以某种方式再次定义 profile。这对我来说没有多大意义。任何帮助,将不胜感激! 更新:我在发布之前查看了 global 关键字,但大多数搜索告诉我,拥有全局变量主要是一个糟糕设计的标志,所以我认为我缺少一些 python 来使它在这里工作????

【问题讨论】:

    标签: python amazon-ec2 click command-line-interface boto3


    【解决方案1】:

    经过试验,似乎最合适的解决方案是将我的 profile 变量设为全局变量

    @click.group()
    @click.option('--profile', default = None, help='Select the AWS profile')
    def cli(profile):
        "Shotty manages snapshots"
        session = boto3.Session(profile_name=profile)
        ec2_cli = session.resource('ec2')
        global ec2
        ec2 = ec2_cli
    

    虽然这种方法通常不受欢迎,但我一直在努力按照大多数人的建议将所有相关函数封装在一个类中 (How to share values between functions in Python?) 在这种情况下,这种全局变量解决方案似乎是最好的,因为它涉及的代码更改最少

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-13
      • 2021-01-30
      • 1970-01-01
      • 2021-09-24
      • 2020-05-10
      • 2011-10-25
      • 2013-02-05
      • 2013-03-08
      相关资源
      最近更新 更多