Twisted插件错误

时间:2016-03-21 11:24:04

标签: python twisted twistd

A创建了一个死的简单扭曲应用程序,它启动TCP协议并回显你在STDIN中输入的内容。

我现在正在尝试创建一个twistd插件,以便能够以这种方式运行我的应用:echo starttwistd -n echo

运行twistd -n echo时,一切都按预期工作,使用echo start命令时出现错误:/home/vagrant/.env/bld/bin/echo: Unknown command: echo

这是我的代码:

回声/ plugins.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.application import internet
from twisted.internet import endpoints
from twisted.internet.protocol import Factory
from twisted.python import usage

from echo.protocol import EchoProtocol


class Options(usage.Options):
    optParameters = [['port', 'p', 1234, 'Service port.']]


def makeService(options):
    from twisted.internet import reactor

    f = Factory()
    f.protocol = EchoProtocol

    ep = endpoints.TCP4ServerEndpoint(reactor, int(options['port']))
    return internet.StreamServerEndpointService(ep, f)

回声/ protocol.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.internet.protocol import Protocol


class EchoProtocol(Protocol):
    def dataReceived(self, data):
        self.transport.write('You entered: {data}'.format(data=data))

回声/ tap.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

from twisted.python import usage
from twisted.scripts import twistd


class Start(twistd.ServerOptions):
    def parseOptions(self, args):
        sys.argv[1:] = self.getArguments(args)
        print('Starting echo service...')
        twistd.run()

    def getArguments(self, args):
        args.extend(['--pidfile', self.parent.pid])
        args.extend(['_bld_echo'])
        return args


class Options(usage.Options):
    pid = '/tmp/echo.pid'
    subCommands = [['start', None, Start, 'Launch echo service.']]


def main(argv=None):
    o = Options()
    try:
        o.parseOptions(argv)
    except usage.UsageError, e:
        raise SystemExit(str(e))

扭曲/插件/ echo_plugin.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.application.service import ServiceMaker

Finger = ServiceMaker(
    'EchoServiceMaker',  # name
    'echo.plugins',  # module
    'Description blah-blah.',  # description
    '_plgn_echo')  # tapname

setup.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import find_packages
from setuptools import setup

setup(
    name='Echo',
    version='0.0.1',
    packages=find_packages(),
    entry_points={
        'console_scripts': [
            '_ep_echo=echo.tap:main',
        ],
    },
    install_requires=[
        'Twisted==16.0.0',
    ],
    include_package_data=True,
    zip_safe=False,)

这是我的virtualenv设置:

(bld)vagrant@/code/echo $ pip list
Echo (0.0.1)
pip (1.4.1)
setuptools (20.3.1)
Twisted (16.0.0)
wsgiref (0.1.2)
zope.interface (4.1.3)

我用 _ep _ _bld _ 为我的命令加前缀,因为我不确定在通过twistd调用程序或直接调用entry_point时调用了哪一个,但是我已经尝试过任何可能的组合而没有成功...

当我运行_ep_echo start时,我得到:

[twistd -help output...]

twistd reads a twisted.application.service.Application out of a file and runs
it.
Commands:
    conch            A Conch SSH service.
    dns              A domain name server.
    ftp              An FTP server.
    inetd            An inetd(8) replacement.
    mail             An email service
    manhole          An interactive remote debugger service accessible via
                     telnet and ssh and providing syntax coloring and basic line
                     editing functionality.
    manhole-old      An interactive remote debugger service.
    news             A news server.
    portforward      A simple port-forwarder.
    procmon          A process watchdog / supervisor
    socks            A SOCKSv4 proxy service.
    telnet           A simple, telnet-based remote debugging service.
    web              A general-purpose web server which can serve from a
                     filesystem or application resource.
    words            A modern words server
    xmpp-router      An XMPP Router server

/home/vagrant/.env/bld/bin/_ep_echo: Unknown command: _bld_echo

如果我将_bld_echo替换为_ep_echo,也是如此。

查看输出时有一点很奇怪:twistd没有注册echo子命令。

如果我运行twistd --help,我会:

twistd reads a twisted.application.service.Application out of a file and runs
it.
Commands:
    _plgn_echo       Description blah-blah.
    conch            A Conch SSH service.
    dns              A domain name server.
    ftp              An FTP server.
    inetd            An inetd(8) replacement.
    mail             An email service
    manhole          An interactive remote debugger service accessible via
                     telnet and ssh and providing syntax coloring and basic line
                     editing functionality.
    manhole-old      An interactive remote debugger service.
    news             A news server.
    portforward      A simple port-forwarder.
    procmon          A process watchdog / supervisor
    socks            A SOCKSv4 proxy service.
    telnet           A simple, telnet-based remote debugging service.
    web              A general-purpose web server which can serve from a
                     filesystem or application resource.
    words            A modern words server
    xmpp-router      An XMPP Router server

在那里你可以看到注册的echo命令。

这让我发疯了,关于这里有什么问题的想法?

请注意,我运行python setup.py install而不是python setup.py develop,后一个命令可以运行,但我不想在生产中运行

修改

在搜索了axiomatic start为什么工作而不是我的echo start后,我找到了原因,我从安装中删除了所有不需要的代码,在这里我发现了(我不认为这是解决方案) ,我很想听@glyph对此的回答)

Axiom Echo 之间的主要区别在于setup.py中的这一行:

packages=find_packages() + ['twisted.plugins']

我没有对+ ['twisted.plugins']添加packages line,现在它可以正常运行,但仍然会发生此错误:

Unexpected error while writing cache file
Traceback (most recent call last):
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/application/app.py", line 579, in parseOptions
    usage.Options.parseOptions(self, options)
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/python/usage.py", line 262, in parseOptions
    for (cmd, short, parser, doc) in self.subCommands:
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/application/app.py", line 596, in subCommands
    for plug in sorted(plugins, key=attrgetter('tapname')):
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/plugin.py", line 213, in getPlugins
    allDropins = getCache(package)
--- <exception caught here> ---
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/plugin.py", line 185, in getCache
    dropinPath.setContent(pickle.dumps(dropinDotCache))
exceptions.AttributeError: 'ZipPath' object has no attribute 'setContent'

该插件有效但我真的很想知道为什么我原来的安装方式不起作用......

1 个答案:

答案 0 :(得分:1)

感谢您对问题的详尽解释;我只用一个小调整就能完全重现它(在__init__.py内创建一个echo/以使其成为一个合适的包。)

首先,这是修复:

diff --git a/echo/tap.py b/echo/tap.py
index d23571f..8e1ea84 100644
--- a/echo/tap.py
+++ b/echo/tap.py
@@ -15,7 +15,7 @@ class Start(twistd.ServerOptions):

     def getArguments(self, args):
         args.extend(['--pidfile', self.parent.pid])
-        args.extend(['_bld_echo'])
+        args.extend(['_plgn_echo'])
         return args

这样做的原因在于,在编写这样的命令时,您正在执行的操作是包装Twisted插件的执行,这意味着合成命令的内容由args.extend构造的行是 Twisted插件的tapname ,与twistd命令行中的相同。

希望很清楚为什么这是_plgn_echo

我还要赞扬你添加这些前缀以清楚地理解哪个名称,特别是在代码的每个区域中都被引用。假设这个答案对你有意义,那么你在这里对代码的理解要比你在任何地方卡住echo时要好得多,即使它最初碰巧工作了: - )。 / p>