Мы создали очень простое приложение, которое запускает TCP-протокол и выводит то, что вы вводите в STDIN.
Теперь я пытаюсь создать плагин twistd
, чтобы иметь возможность запускать мое приложение следующим образом: echo start
или либо twistd -n echo
При запуске twistd -n echo
все работает как положено, при использовании команды echo start
получаю ошибку: /home/vagrant/.env/bld/bin/echo: Unknown command: echo
Вот мой код:
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)
echo/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))
echo/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'
Плагин работает, но мне бы очень хотелось узнать, почему мой первоначальный способ его установки не сработал...
echo/plugins/py
на самом деле относится кecho/plugins.py
? Я собираюсь отредактировать вопрос, чтобы отразить это. (Если нет: это ваша проблема. :)) - person Glyph   schedule 24.03.2016