I'm working on a Python package that consists of a library module and two scripts that use the library. One of the scripts is a command-line tool printing out some text and the other a JSON API server. Both scripts also serve as examples for developers looking to use the library.

Given this situation I see three main audiences or use cases for the package:

  1. Library user: needs the main module. Might want access to the scripts for testing the module and as stubs and examples for their own code.

  2. CLI user: wants to run the CLI script every now and then. Doesn't need the API server, and probably doesn't care about access to the script source.

  3. API provider: same as CLI user, but with API server script. Might want the CLI script for quick testing.

Ideally the script users could also choose whether they want to run the scripts directly from a directory or from their $PATH.

How could I structure this properly in a directory tree and in one or more distribution packages (likely using setuptools)?

The current source layout is like this:

main_folder
    README
    setup.py
    mypackage
      __init__.py # contains the library functions
      mymodule.py # link to __init__.py for easy import in the scripts
      cli.py
      api_server.py
有帮助吗?

解决方案

Here's what I did now.

I browsed PyPI looking for similar packages, then took a look at wikidump's directory structure and its setup.py.

There I found out about the entry_points parameter which allows one to specify module functions that will be converted to scripts at build time. These scripts may also have extra dependencies.

To work with this I converted the respective __main__ blocks into named functions and marked those as entry points. The relevant block (all setuptools.setup() parameters) looks like this:

  [...]
  requires=['pyswisseph', 'numpy'],
  extras_require={'Flask':['flask']},
  entry_points={
      'console_scripts':
          ['cerridwen = cerridwen.cli:main',
           'cerridwen-server = cerridwen.api_server:main [Flask]']
  }
  [...]

Everyone gets the module and scripts, but the optional dependency will be installed only if the script that requires them is run for the first time. The script logic will also be installed as part of the main module so everyone can use their helper functions as needed.

As for having the scripts as examples, I intend to reference their github sources on the project's web site.

The directory structure was left in its original state.

I hope that helps someone else :)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top