Jeff Triplett, Lacey Williams He 发布的文章

学习一下 Python 世界里最广泛使用的 ChatOps 库:每个都能做什么,如何使用。

ChatOps 是基于会话导向而进行的开发。其思路是你可以编写能够对聊天窗口中的某些输入进行回复的可执行代码。作为一个开发者,你能够用 ChatOps 从 Slack 合并拉取请求,自动从收到的 Facebook 消息中给某人分配支持工单,或者通过 IRC 检查开发状态。

在 Python 世界,最为广泛使用的 ChatOps 库是 Opsdroid 和 Errbot。在这个月的 Python 专栏,让我们一起聊聊使用它们是怎样的体验,它们各自适用于什么方面以及如何着手使用它们。

Opsdroid

Opsdroid 是一个相对年轻的(始于 2016)Python 开源聊天机器人库。它有着良好的开发文档,不错的教程,并且包含能够帮助你对接流行的聊天服务的插件。

它内置了什么

库本身并没有自带所有你需要上手的东西,但这是故意的。轻量级的框架鼓励你去运用它现有的连接器(Opsdroid 所谓的帮你接入聊天服务的插件)或者去编写你自己的,但是它并不会因自带你所不需要的连接器而自贬身价。你可以轻松使用现有的 Opsdroid 连接器来接入:

  • 命令行
  • Cisco Spark
  • Facebook
  • GitHub
  • Matrix
  • Slack
  • Telegram
  • Twitter
  • Websocket

Opsdroid 会调用使聊天机器人能够展现它们的“技能”的函数。这些技能其实是异步 Python 函数,并使用 Opsdroid 叫做“匹配器”的匹配装饰器。你可以设置你的 Opsdroid 项目,来使用同样从你设置文件所在的代码中的“技能”。你也可以从外面的公共或私人仓库调用这些“技能”。

你同样可以启用一些现存的 Opsdroid “技能”,包括 seen —— 它会告诉你聊天机器人上次是什么时候看到某个用户的,以及 weather —— 会将天气报告给用户。

最后,Opdroid 允许你使用现存的数据库模块设置数据库。现在 Opdroid 支持的数据库包括:

  • Mongo
  • Redis
  • SQLite

你可以在你的 Opdroid 项目中的 configuration.yaml 文件设置数据库、技能和连接器。

Opsdroid 的优势

Docker 支持:从一开始 Opsdroid 就打算在 Docker 中良好运行。在 Docker 中的指导是它 安装文档 中的一部分。使用 Opsdroid 和 Docker Compose 也很简单:将 Opsdroid 设置成一种服务,当你运行 docker-compose up 时,你的 Opsdroid 服务将会开启你的聊天机器人也将就绪。

version: "3"

services:
  opsdroid:
    container_name: opsdroid
    build:
      context: .
      dockerfile: Dockerfile

丰富的连接器: Opsdroid 支持九种像 Slack 和 Github 等从外部接入的服务连接器。你所要做的一切就是在你的设置文件中启用那些连接器,然后把必须的口令或者 API 密匙传过去。比如为了启用 Opsdroid 以在一个叫做 #updates 的 Slack 频道发帖,你需要将以下代码加入你设置文件的 connectors 部分:

 - name: slack
    api-token: "this-is-my-token"
    default-room: "#updates"

在设置 Opsdroid 以接入 Slack 之前你需要添加一个机器人用户

如果你需要接入一个 Opsdroid 不支持的服务,在文档里有有添加你自己的连接器的教程。

相当不错的文档: 特别是对于一个在积极开发中的新兴库来说,Opsdroid 的文档十分有帮助。这些文档包括一篇带你创建几个不同的基本技能的教程。Opsdroid 在技能连接器数据库,以及匹配器方面的文档也十分清晰。

它所支持的技能和连接器的仓库为它的技能提供了富有帮助的示范代码。

自然语言处理: Opsdroid 的技能里面能使用正则表达式,但也同样提供了几个包括 Dialogflowluis.aiRecast.AI 以及 wit.ai 的 NLP API。

Opsdroid 可能的不足

Opsdroid 对它的一部分连接器还没有启用全部的特性。比如说,Slack API 允许你向你的消息添加颜色柱、图片以及其他的“附件”。Opsdroid Slack 连接器并没有启用“附件”特性,所以如果那些特性对你来说很重要的话,你需要编写一个自定义的 Slack 连接器。如果连接器缺少一个你需要的特性,Opsdroid 将欢迎你的贡献。文档中可以使用更多的例子,特别是对于预料到的使用场景。

示例用法

from opsdroid.matchers import match_regex
import random


@match_regex(r'hi|hello|hey|hallo')
async def hello(opsdroid, config, message):
    text = random.choice(["Hi {}", "Hello {}", "Hey {}"]).format(message.user)
    await message.respond(text)

hello/\_\_init\_\_.py

connectors:
  - name: websocket

skills:
  - name: hello
    repo: "https://github.com/<user_id>/hello-skill"

configuration.yaml

Errbot

Errbot 是一个功能齐全的开源聊天机器人。Errbot 发行于 2012 年,并且拥有人们从一个成熟的项目能期待的一切,包括良好的文档、优秀的教程以及许多帮你连入现有的流行聊天服务的插件。

它内置了什么

不像采用了较轻量级方式的 Opsdroid,Errbot 自带了你需要可靠地创建一个自定义机器人的一切东西。

Errbot 包括了对于本地 XMPP、IRC、Slack、Hipchat 以及 Telegram 服务的支持。它通过社区支持的后端列出了另外十种服务。

Errbot 的优势

良好的文档: Errbot 的文档成熟易读。

动态插件架构: Errbot 允许你通过和聊天机器人交谈安全地安装、卸载、更新、启用以及禁用插件。这使得开发和添加特性十分简便。感谢 Errbot 的颗粒性授权系统,出于安全意识这所有的一切都可以被锁闭。

当某个人输入 !help,Errbot 使用你的插件的文档字符串来为可获取的命令生成文档,这使得了解每行命令的作用更加简便。

内置的管理和安全特性: Errbot 允许你限制拥有管理员权限的用户列表,甚至细粒度访问控制。比如说你可以限制特定用户或聊天房间访问特定命令。

额外的插件框架: Errbot 支持钩子、回调、子命令、webhook、轮询以及其它更多特性。如果那些还不够,你甚至可以编写动态插件。当你需要基于在远程服务器上的可用命令来启用对应的聊天命令时,这个特性十分有用。

自带测试框架: Errbot 支持 pytest,同时也自带一些能使你简便测试插件的有用功能。它的“测试你的插件”的文档出于深思熟虑,并提供了足够的资料让你上手。

Errbot 可能的不足

以 “!” 开头: 默认情况下,Errbot 命令发出时以一个惊叹号打头(!help 以及 !hello)。一些人可能会喜欢这样,但是另一些人可能认为这让人烦恼。谢天谢地,这很容易关掉。

插件元数据 首先,Errbot 的 Hello World 插件示例看上去易于使用。然而我无法加载我的插件,直到我进一步阅读了教程并发现我还需要一个 .plug 文档,这是一个 Errbot 用来加载插件的文档。这可能比较吹毛求疵了,但是在我深挖文档之前,这对我来说都不是显而易见的。

示例用法

import random
from errbot import BotPlugin, botcmd

class Hello(BotPlugin):

    @botcmd
    def hello(self, msg, args):
        text = random.choice(["Hi {}", "Hello {}", "Hey {}"]).format(message.user)
        return text

hello.py

[Core]
Name = Hello
Module = hello

[Python]
Version = 2+

[Documentation]
Description = Example "Hello" plugin

hello.plug

你用过 Errbot 或 Opsdroid 吗?如果用过请留下关于你对于这些工具印象的留言。


via: https://opensource.com/article/18/3/python-chatops-libraries-opsdroid-and-errbot

作者:Jeff Triplett, Lacey Williams Henschel 译者:tomjlw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

用 Click、Docopt 和 Fire 库写你自己的命令行应用。

有时对于某项工作来说一个命令行工具就足以胜任。命令行工具是一种从你的 shell 或者终端之类的地方交互或运行的程序。GitCurl 就是两个你也许已经很熟悉的命令行工具。

当你有一小段代码需要在一行中执行多次或者经常性地被执行,命令行工具就会很有用。Django 开发者执行 ./manage.py runserver 命令来启动他们的网络服务器;Docker 开发者执行 docker-compose up 来启动他们的容器。你想要写一个命令行工具的原因可能和你一开始想写代码的原因有很大不同。

对于这个月的 Python 专栏,我们有 3 个库想介绍给希望为自己编写命令行工具的 Python 使用者。

Click

Click 是我们最爱的用来开发命令行工具的 Python 包。其:

  • 有一个富含例子的出色文档
  • 包含说明如何将命令行工具打包成一个更加易于执行的 Python 应用程序
  • 自动生成实用的帮助文本
  • 使你能够叠加使用可选和必要参数,甚至是 多个命令
  • 有一个 Django 版本( django-click )用来编写管理命令

Click 使用 @click.command() 去声明一个函数作为命令,同时可以指定必要和可选参数。

# hello.py
import click 

@click.command()
@click.option('--name', default='', help='Your name')
def say_hello(name):
    click.echo("Hello {}!".format(name))

if __name__ == '__main__':
    say_hello()

@click.option() 修饰器声明了一个 可选参数 ,而 @click.argument() 修饰器声明了一个 必要参数。你可以通过叠加修饰器来组合可选和必要参数。echo() 方法将结果打印到控制台。

$ python hello.py --name='Lacey'
Hello Lacey!

Docopt

Docopt 是一个命令行工具的解析器,类似于命令行工具的 Markdown。如果你喜欢流畅地编写应用文档,在本文推荐的库中 Docopt 有着最好的格式化帮助文本。它不是我们最爱的命令行工具开发包的原因是它的文档犹如把人扔进深渊,使你开始使用时会有一些小困难。然而,它仍是一个轻量级的、广受欢迎的库,特别是当一个漂亮的说明文档对你来说很重要的时候。

Docopt 对于如何格式化文章开头的 docstring 是很特别的。在工具名称后面的 docsring 中,顶部元素必须是 Usage: 并且需要列出你希望命令被调用的方式(比如:自身调用,使用参数等等)。Usage: 需要包含 helpversion 参数。

docstring 中的第二个元素是 Options:,对于在 Usages: 中提及的可选项和参数,它应当提供更多的信息。你的 docstring 的内容变成了你帮助文本的内容。

"""HELLO CLI

Usage:
    hello.py
    hello.py <name>
    hello.py -h|--help
    hello.py -v|--version

Options:
    <name>  Optional name argument.
    -h --help  Show this screen.
    -v --version  Show version.
"""

from docopt import docopt

def say_hello(name):
    return("Hello {}!".format(name))


if __name__ == '__main__':
    arguments = docopt(__doc__, version='DEMO 1.0')
    if arguments['<name>']:
        print(say_hello(arguments['<name>']))
    else:
        print(arguments)

在最基本的层面,Docopt 被设计用来返回你的参数键值对。如果我不指定上述的 name 调用上面的命令,我会得到一个字典的返回值:

$ python hello.py
{'--help': False,
 '--version': False,
 '<name>': None}

这里可看到我没有输入 helpversion 标记并且 name 参数是 None

但是如果我带着一个 name 参数调用,say_hello 函数就会执行了。

$ python hello.py Jeff
Hello Jeff!

Docopt 允许同时指定必要和可选参数,且各自有着不同的语法约定。必要参数需要在 ALLCAPS<carets> 中展示,而可选参数需要单双横杠显示,就像 --like。更多内容可以阅读 Docopt 有关 patterns 的文档。

Fire

Fire 是谷歌的一个命令行工具开发库。尤其令人喜欢的是当你的命令需要更多复杂参数或者处理 Python 对象时,它会聪明地尝试解析你的参数类型。

Fire 的 文档 包括了海量的样例,但是我希望这些文档能被更好地组织。Fire 能够处理 同一个文件中的多条命令、使用 对象 的方法作为命令和 分组 命令。

它的弱点在于输出到控制台的文档。命令行中的 docstring 不会出现在帮助文本中,并且帮助文本也不一定标识出参数。

import fire


def say_hello(name=''):
    return 'Hello {}!'.format(name)


if __name__ == '__main__':
    fire.Fire()

参数是必要还是可选取决于你是否在函数或者方法定义中为其指定了一个默认值。要调用命令,你必须指定文件名和函数名,比较类似 Click 的语法:

$ python hello.py say_hello Rikki
Hello Rikki!

你还可以像标记一样传参,比如 --name=Rikki

额外赠送:打包!

Click 包含了使用 setuptools 打包 命令行工具的使用说明(强烈推荐按照说明操作)。

要打包我们第一个例子中的命令行工具,将以下内容加到你的 setup.py 文件里:

from setuptools import setup

setup(
    name='hello',
    version='0.1',
    py_modules=['hello'],
    install_requires=[
        'Click',
    ],
    entry_points='''
        [console_scripts]
        hello=hello:say_hello
    ''',
)

任何你看见 hello 的地方,使用你自己的模块名称替换掉,但是要记得忽略 .py 后缀名。将 say_hello 替换成你的函数名称。

然后,执行 pip install --editable 来使你的命令在命令行中可用。

现在你可以调用你的命令,就像这样:

$ hello --name='Jeff'
Hello Jeff!

通过打包你的命令,你可以省掉在控制台键入 python hello.py --name='Jeff' 这种额外的步骤以减少键盘敲击。这些指令也很可能可在我们提到的其他库中使用。


via: https://opensource.com/article/18/5/3-python-command-line-tools

作者:Jeff TriplettLacey Williams Hensche 选题:lujun9972 译者:hoppipolla- 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出