dev 命令行参数调用_告别繁琐!像专家一样编写命令行界面

全文共6377字,预计学习时长19分钟

a14b835e889bd59928437c34bc7f8922.png

你是否渴望从菜鸟一跃成为专家?你是否需要一键解决包括撰写周报,提取,转换等重复的工作?

前者需要长年累月的积累和努力,后者今天就可以安排上!

众所周知,数据科学家每天需要处理许多相同且重复的工作。这可能包括撰写周报,提取,转换,加载(ETL)工作 或者是设置不同参数来训练模型。

通常每一次运行程序时,都会更改代码中的参数,最终获得一长串的Python脚本。小芯痛恨这些繁琐重复的工作。这就是小芯习惯于将脚本转换为可重复使用的命令行接口工具(CLI)的原因。这个习惯也让日常工作更加高效。最开始小芯使用Argparse,但效果并不理想,因为仍旧需要写一大堆丑陋的代码。

所以,为什么不能采取某种方式摆脱写大段大段代码的束缚,享受编译命令行接口工具的乐趣呢?

Click可以实现你心中的小九九。

那么,什么是Click?网络上是这么解释的:

Click致力于让编写命令行工具的过程变得快速且有趣,同时也防止由于无法实现预期的CLI API而导致的故障。

简直太棒了!

接下来,小芯将举例说明Click的基本功能和优势,手把手教你如何利用Click来构造Python CLIs。

希望大家能在阅读完这份学习指南后,可以在短时间里轻松写出专属CLI工具。

现在开始吧!

教程

在本教程中使用Click逐步构建了Python CLI。先从最基础开始,每一步,介绍关于Click 的一个新概念。除了Click,也使用Poetry来管理依赖项和包。

准备工作

首先,安装Poetry,此处使用pip来进行安装。

pip install poetry==0.12.7

接下来,使用Poetry来创建一个名为cli-tutorial的项目,将click和funcy添加为依赖项,并创建一个文件cli.py,用以下代码填充:

poetry new cli-tutorial

cd cli-tutorial

poetry add click funcy

# Create the file we will put in all our code

touch cli_tutorial/cli.py

已添加的funcy稍后再使用。现在,准备开始创建第一个CLI。

首个Click CLI

初始的CLI从磁盘读取CSV文件,对其进行处理(本教程不对此过程赘述),然后将结果存储在Excel文件中。输入文件和输出文件的路径都应该由用户配置。用户必须指定输入文件路径。指定输出文件路径是可选的,默认为output.xlsx。执行Click操作的代码为:

import click@click.command()

@click.option("--in", "-i", "in_file",required=True,

help="Path to csv file to beprocessed.",

)

@click.option("--out-file", "-o", default="./output.xlsx",

help="Path to excel file tostore the result.")

def process(in_file, out_file):

""" Processes theinput file IN and stores the result to

output file OUT.

"""

input = read_csv(in_file)

output = process_csv(input)

write_excel(output, out_file)if__name__ == "__main__":if __name__ =="__main__":

process()

这些代码是什么意思?

1.用click.command装饰从命令行调用的方法process。

2.使用click.option装饰器定义命令行参数。现在,在装饰过的函数中一定要谨慎地使用正确的参数名称。如果在click.option中添加不带破折号的字符串,则参数必须与该字符串匹配。--in和in_file就是这种情况。如果所有名称都包含前导破折号,则Click会使用最长的名称生成参数名称,并将所有非前导破折号转换为下划线。名称转换为小写形式。--out-file和out_file就是这种情况。

3.使用click.option的相应参数来配置所需的先决条件,例如默认值或所需参数。

4.在参数中添加帮助文本,当使用--help调用函数时会显示该文本。函数的文档字符串也将显示在此处。

5a008b54be81d3cdab0bdf7861a3c142.png

现在,可以采取多种方式调用CLI:

# Prints help

python -m cli_tutorial.cli --help

# Use single char -i for loading the file

python -m cli_tutorial.cli -i path/to/some/file.csv

# Specify both file with long name

python -m cli_tutorial.cli --in path/to/file.csv --out-file out.xlsx

太棒了,用Click创造出了第一个CLI!

276d5c085d4f7d1b7dd033e7765260fe.gif

请注意,read_csv,process_csv和write_excel尚未实现,但假定它们存在并且可以执行所需操作。

CLI也存在一个问题——将参数作为通用字符串传递。为什么这么说?因为这些字符串必须被解析为实际类型,否则可能会由于用户输入格式错误而失效。在示例中,使用路径尝试加载CSV文件。用户可以提供一个根本不代表路径的字符串。即使字符串格式正确,相应的文件也可能不存在,或者没有访问权限。自动验证输入、提前报错时解析输入,这些难道不正是我们想要的吗?最理想的是,如果所有这些操作的实现都无需编写大量代码。Click通过指定参数的类型来支撑这一想法。

类型规范

在示例CLI中,希望的是用户将有效路径传递给具有读取权限的现有文件。如果满足这些要求,便可以加载输入文件。此外,如果用户指定了输出文件路径,则该路径应为有效路径。可以通过将click.Path对象传递给click.option装饰器的type参数来执行所有操作。

@click.command()

@click.option("--in", "-i", "in_file",required=True,

help="Path to csv file to beprocessed.",

type=click.Path(exists=True,dir_okay=False, readable=True),

)

@click.option("--out-file", "-o",default="./output.csv",

help="Path to csv file to storethe result.",

type=click.Path(dir_okay=False),

)

def process(in_file, out_file):

""" Processes theinput file IN and stores the result to output

file OUT.

"""

input = read_csv(in_file)

output = process_csv(input)

write_csv(output, out_file)

...

Click.Path是Click提供的直接可用的多种类型之一。

布尔标识

Click提供的另一个有用功能是布尔标志。可能最著名的布尔标识是verbose标识。如果设置为true,那么工具将向终端输出很多信息。如果设置为false,则仅输出一些内容。以下是利用Click实现的代码:

from funcy import identity

...

@click.option('--verbose', is_flag=True, help="Verbose output")

def process(in_file, out_file, verbose):

""" Processes theinput file IN and stores the result to

output file OUT.

"""

print_func = print if verbose elseidentity print_func("We will startwith the input")

input = read_csv(in_file)

print_func("Next we procees thedata")

output = process_csv(input)

print_func("Finally, we dumpit")

write_excel(output, out_file)

只需要添加另一个click.option装饰器并设置is_flag = True。现在,要获取详细的输出,需要以下命令来调用CLI:

python -m cli_tutorial.cli -ipath/to/some/file.cs --verbose

功能切换

假设不仅要在本地存储process_csv的结果,而且还希望将其上传到服务器。 此外,不仅只有一个目标服务器,而且还存在一个开发,测试和生产的实例。可以通过不同的URL访问这三个实例。用户选择服务器的一种方式是传递完整的URL作为必须输入的参数。但是,这不仅容易出错,而且很繁琐。在这种情况下,小芯会使用功能切换来简化用户的操作。而这个过程最好通过代码来解释。

...

@click.option(

"--dev","server_url", help="Upload to dev server",

flag_value='https://dev.server.org/api/v2/upload',

)

@click.option(

"--test","server_url", help="Upload to test server",

flag_value='https://test.server.com/api/v2/upload',

)

@click.option(

"--prod","server_url", help="Upload to prod server",

flag_value='https://real.server.com/api/v2/upload',

default=True

)

def process(in_file, out_file, verbose, server_url):

""" Processes theinput file IN and stores the result to output

file OUT.

"""

print_func = print if verbose elseidentity

print_func("We will start withthe input")

input = read_csv(in_file)

print_func("Next we procees thedata")

output = process_csv(input)

print_func("Finally, we dumpit")

write_excel(output, out_file)

print_func("Upload it to theserver")

upload_to(server_url, output)

...

在这里为三个可能的服务器URL添加了三个click.option装饰器。重要的是,所有三个选项都具有相同的目标变量server_url。根据选择的选项,server_url的值等于flag_value中定义的相应值。可以通过添加--dev,--test或--prod作为参数,来选择其中之一。所以当运行以下命令时,

python -m cli_tutorial.cli -ipath/to/some/file.csv –test

server_url就等于“https://test.server.com/api/v2/upload”。如果未指定这三个标记中的任何一个,则Click会采用--dev的值,因为设置了default = True。

用户名及密码提示

ff9dba9e141812a9afb3c50eab70b57d.png

不知是不幸还是幸运,服务器是受到密码保护的。因此,上传文件需要提供用户名和密码。当然,可以将用户名和密码当做标准的click.option参数。但是密码会以纯文本形式出现在命令历史记录中,造成安全隐患。

希望有一个提示符,能让用户输入密码而不将密码回显终端,也不要将其存储在命令历史记录中。而对于用户名,也需要一个带有回显的简单提示符。知道如何使用Click就可以轻松地实现上述想法。以下是代码:

import os

...

@click.option('--user', prompt=True,

default=lambda:os.environ.get('USER', ''))

@click.password_option()

def process(in_file, out_file, verbose, server_url, user, password):

...

upload_to(server_url, output, user,password)

为单个参数添加提示符,需要设置prompt=True。每当用户未指定--user 参数时(用户也可以设置user参数),界面都会添加一个提示符。当在提示符下按Enter时,默认值将被使用。默认值是由函数确定的,这是Click提供的另一个便捷功能。

提示密码而不将其回显到终端并要求确认的情况十分普遍,Click还为此提供了一个专用的装饰器——password_option。值得注意的是,这个装饰器并不会阻止用户通过--password MYSECRETPASSWORD输入密码。这只会不让其这样做。

至此,已经构建了完整的CLI。在收工前,小芯想在下一部分中介绍最后的一个小技巧。

Poetry 脚本

最后一个小技巧,与Click无关,但仍然属于CLI的讨论范畴——创建Poetry脚本。使用Poetry脚本,可以创建可执行文件来从命令行调用Python函数,就像使用Setuptools脚本一样。具体是如何呢?首先,需要将以下代码添加到pyproject.toml文件中:

[tool.poetry.scripts]

your-wanted-name = 'cli_tutorial.cli:process'

your-wanted-name是模块cli_tutorial.cli中定义的process函数的别名。现在,可以通过以下代码调用

poetry run your-wanted-name -i./dummy.csv --verbose –dev

上述代码可以实现定义别名,举个例子,将多个CLI函数添加到同一文件。并且,不需要添加if __name__ == “__main__” 代码块。

结语

本文展示了如何使用Click 和 Poetry轻松构建CLI工具并提高工作效率。其实,这只是Click提供的功能的一小部分。Click还有许多其他功能,例如callbacks, nestedcommands, 和 choiceoptions。

如果有机会,小芯在不久后还会继续为大家带来相关文章,大家拭目以待吧~

c3fbd20fe4730dbb2ef501dff622fc09.gif
bfca4819f2869d50d50d91c9413e2481.png

留言点赞关注

我们一起分享AI学习与发展的干货

如转载,请后台留言,遵守转载规范

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值