12

In my Python application, I can distinguish between entry points (scripts) and what I think of as library code.

My instinct is to put the library code inside a package, and the scripts elsewhere importing from the package.

It is possible using setup.py to reference methods inside a package to use as entry-points, thereby having all Python code inside packages.

Which is preferable?

Note: this link discusses both options but doesn't really offer an opinion.

Edit: to give a more concrete example, I am reviewing some code which contains one package. There are forty modules inside it:

  • __init__.py
  • 11 'scripts'
  • 10 'library modules' used by those scripts
  • 18 test modules

This doesn't feel like it is using the capability of packages very well, but I can't put my finger on what exactly is wrong.

I appreciate that having tests in the same package was not in my original question.

asked Jan 28, 2016 at 16:47
2
  • What sorts of things will these "scripts" do? Commented Jan 28, 2016 at 22:48
  • Do you expect the scripts and the library to rev separately or do they need to be developed together? Commented Jan 29, 2016 at 12:13

3 Answers 3

8

Yes, this is possible and quite common for packages that serve as both command-line tools and imported libraries.

In setup.py, add a module's function as an entry point:

setuptools.setup(
 ...
 entry_points={'console_scripts': [
 'foo = my_package.some_module:main_func',
 ]},
 ...
)

To create a script named foo that calls the my_func function inside of my_package.some_module. Read more at https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation.

It is also a convention it to add:

#!/usr/bin/env python
...
if __name__ == '__main__':
 my_func()

to the modules that can be called as "scripts" where my_func is the function you'd like to call externally.


Here is an example of setup.py:

https://github.com/jacebrowning/gdm/blob/fa998167f5f6de64bc8bdfd8b9433870d79ef814/setup.py#L28-L31

and a callable module:

https://github.com/jacebrowning/gdm/blob/fa998167f5f6de64bc8bdfd8b9433870d79ef814/gdm/cli.py#L161-L162

answered Jan 28, 2016 at 22:33
3
  • I know, I said in my question that it's possible. The question is which method is preferable. Commented Jan 28, 2016 at 22:35
  • Preferable to whom? This method let's you share code in the case where you'd like to additionally make the entry points callable from Python. Commented Jan 28, 2016 at 22:52
  • I gave a more concrete example. Commented Jan 29, 2016 at 8:13
7

Two years later, I feel that I can answer my own question.

It is preferable to use the Setuptools entry_points method. This is described well in the Click documentation, and the main points are:

  • this works better on Windows
  • the Pythonpath is managed by Setuptools, so (for example) if your script is installed inside a virtualenv, you don't need to activate the virtualenv for it to work correctly
answered Jun 1, 2018 at 7:59
1

If you intend to have the library code be used by other packages, you need to separate it from the scripts. This is due to the way dependencies are declared in setup.py and requirements.txt (see here).

If the library code will only be used with these scripts, you can choose. I would choose to keep them together to keep things a little simpler

answered Jan 28, 2016 at 20:45

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.