Twisted script problem

I wrote a Twisted bin file that was deployed to /usr/bin during application deployment, based on the Axiom example provided elsewhere on StackOverflow (I don’t remember where), the project can be found here .

My problem is that during the python setup.py install process, the installed bin file is different from the file from the Axiom package:

/ Usr / bin / axiom

 #!/code/venv/bin/python from axiom.scripts import axiomatic axiomatic.main() 

/ Usr / bin / myapp

 #!/code/venv/bin/python # EASY-INSTALL-DEV-SCRIPT: 'MyApp==0.0.1','myapp' __requires__ = 'MyApp==0.0.1' __import__('pkg_resources').require('MyApp==0.0.1') exec(compile(open(__file__).read(), __file__, 'exec')) 

and the latter does not work when called from bash shell: myapp start

I get the following error: unknow command myapp

If I use python setup.py develop instead of python setup.py install , everything works smoothly.


I have a small test application that starts the tcp service on port 1234:

  • the twistd finger command works , the service starts
  • fingerize start command (another name for the purpose, so as not to cause the wrong one) does not work

Here is the code:

bin / fingerize

 #!/usr/bin/python from finger import tap tap.main() 

twisted / plugins / finger_plugin.py

 from twisted.application.service import ServiceMaker Finger = ServiceMaker('Finger', 'finger.plugins', 'blah', 'finger') 

finger /plugins.py

 from twisted.application import internet from twisted.internet import endpoints from twisted.python import usage from twisted.internet import protocol class Options(usage.Options): """ """ def makeService(options): from twisted.internet import reactor endpoint = endpoints.TCP4ServerEndpoint(reactor, 1234) return internet.StreamServerEndpointService( endpoint, protocol.Factory()) 

finger /tap.py

 import sys from twisted.python import usage from twisted.scripts import twistd class Start(twistd.ServerOptions): run = staticmethod(twistd.run) def subCommands(self): raise AttributeError() subCommands = property(subCommands) def parseOptions(self, args): print(sys.argv) print(args) a = self.getArguments(args) print(a) sys.argv[1:] = a print(sys.argv) print('Starting finger service...') self.run() def getArguments(self, args): args.extend(['--pidfile', self.parent.pid()]) args.extend(['finger']) return args class Options(usage.Options): def subCommands(): def get(self): yield ('start', None, Start, 'Launch finger service') return get, subCommands = property(*subCommands()) def pid(self): return '/tmp/finger.pid' def main(argv=None): o = Options() try: o.parseOptions(argv) except usage.UsageError, e: raise SystemExit(str(e)) 

setup.py

 from setuptools import find_packages from setuptools import setup METADATA = dict( name='Finger', version='0.0.1', packages=find_packages(), scripts=['bin/fingerize'], install_requires=[ 'Twisted >= 15.5.0', ], include_package_data=True, zip_safe=False, ) setup(**METADATA) 

And when I call fingerize start , I get: /code/test/bin/fingerize: Unknown command: finger (test - virtualenv)

+5
source share
1 answer

Since you are using setuptools in your setup.py , you can use the new entry_points keyword, for example:

entry_points={ 'console_scripts': [ 'fingerize=finger.tap:main', ], },

instead of the keyword scripts .

Note that if python setup.py install runs in virtualenv, it puts the script in env/bin/fingerize (if your virtualenv env folder).

A good way to make such "python applications" available globally (for some deployment purposes), while their internal mechanics do not interfere with your python system applications, is to use pipsi ( pip install pipsi ) (made by the guy who designed the flask) . It is designed to expose only project executable files to the system and have everything else hidden in its own virtualenv.

You can learn more about how to write / configure / distribute python packages at packaging.python.org .

0
source

Source: https://habr.com/ru/post/1243663/


All Articles