2

I've almost finished developing a python package and have also written a basic setup.py using distutils:

#!/usr/bin/env python
#@author: Prahlad Yeri
#@description: Small daemon to create a wifi hotspot on linux
#@license: MIT
import cli

#INSTALL IT
from distutils.core import setup
setup(name='hotspotd',
    version='0.1',
    description='Small daemon to create a wifi hotspot on linux',
    license='MIT',
    author='Prahlad Yeri',
    author_email='prahladyeri@yahoo.com',
    url='https://github.com/prahladyeri/hotspotd',
    package_dir={'hotspotd': ''},
    packages=['hotspotd'],
    data_files=[('config',['run.dat'])],
    )

#CONFIGURE IT

Now this script works perfectly as I want. It installs the required files to the prefixed folder. For example, the below command:

sudo python setup.py install --prefix /opt

will install my entire package in:

/opt/lib/python2.7/site-packages/hotspotd

However, I want the major executable, hotspotd.py to be symlinked to an appropriate file in /usr/bin such as:

/usr/bin/hotspotd

So that the user can start my program by simply calling hotspotd start instead of indirectly invoking through python.

How can I achieve this by modifying the setup.py? If I just write the copying code at the end after the setup() call, it would be called each time. I just want it done when the program is being installed.

Prahlad Yeri
  • 3,567
  • 4
  • 25
  • 55

3 Answers3

4

Just use the scripts parameter like this:

#!/usr/bin/env python
#@author: Prahlad Yeri
#@description: Small daemon to create a wifi hotspot on linux
#@license: MIT
import cli

#INSTALL IT
from distutils.core import setup
setup(name='hotspotd',
    version='0.1',
    description='Small daemon to create a wifi hotspot on linux',
    license='MIT',
    author='Prahlad Yeri',
    author_email='prahladyeri@yahoo.com',
    url='https://github.com/prahladyeri/hotspotd',
    package_dir={'hotspotd': ''},
    packages=['hotspotd'],
    data_files=[('config',['run.dat'])],
    scripts=["scriptname"], # Here the Magic Happens
    )

#CONFIGURE IT

Now the file scriptname will be copied to /usr/bin/scriptname the shebang will be replaced by the python version calling the setup.py Script. So write your script wisely.

mjb4
  • 989
  • 1
  • 9
  • 14
2

Nowadays you should use console_scripts to make your script end up in /usr/bin. The format is:

from setuptools import setup

setup(
    ...
    console_scripts=[
        'hotspotd = hotspotd:my_main_func',
    ],
    ...
)
jmagnusson
  • 5,799
  • 4
  • 43
  • 38
  • OK. But I've achieved the same using `scripts=['hotspotd']`. What's the difference between `scripts` and `console_scripts`? – Prahlad Yeri Jun 03 '15 at 08:42
  • `scripts` should work as long as you use [distutils](https://docs.python.org/2/distutils/apiref.html?highlight=scripts) - which isn't exactly wrong - but [these days it's recommended to use setuptools](https://python-packaging-user-guide.readthedocs.org/en/latest/current.html), where you must use `console_scripts`. I've updated the example to include this import instead of `distutils.core.setup`. – jmagnusson Jun 03 '15 at 09:08
0

Entry points may now be specified in setuptools:

setup(
# other arguments here...
entry_points={
    'console_scripts': [
        'foo = my_package.some_module:main_func',
        'bar = other_module:some_func',
    ],
    'gui_scripts': [
        'baz = my_package_gui:start_func',
    ]
}

)

gerardw
  • 5,822
  • 46
  • 39