Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to I create an entry point to a Conda package/application?

I am developing a Python application, and using Conda to distribute it and manage dependencies.

I have successfully run conda-build to wrap up my code into a .tar.bz2 file. I created a new conda environment, and tested installing the package. Everything works, and I am able to run my code this way.

What I am wondering is, how do I structure my package and/or Python code, so that I can run my script by simply typing with my conda environment active, rather than navigating to the folder where I developed the code?

For example, in this conda cheatsheet: https://conda.io/docs/_downloads/conda-cheatsheet.pdf, the fourth line from the top, "Run a package after install, example Spyder" the command to run is simply "spyder".

My Python program is launched from a single .py file, launch.py, but how do I let conda know which script to call? When I do now, it simply says "command not found".

This section in the metadata specification seems relevant: https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#entry-point

I tried setting that to "entry: python launch.py" in my meta.yaml, rebuilding and reinstalling, but that did not work and I am not sure where to go from here.

Any help would be tremendously appreciated, thank you.

Edit: After more digging, I may have found the answer, it seems I want to create an entry point as described here: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins Still trying to put it all together though.

like image 393
D. Lef Avatar asked Apr 30 '18 18:04

D. Lef


1 Answers

Let's say your package structure is something like

my_package/
├── my_package/
│   ├── __init__.py
|   ├── __main__.py
├── conda.recipe/
│   ├── meta.yaml
├── setup.py

The conda recipe in meta.yaml doesn't need to go in a conda.recipe folder, it's just convenient if you want to store the recipe with the rest of the code. Now, in __main__.py, you have some code that you want to call (this code could be in any module, __main__.py happens to be a convenient example because code in there is also executed if you run python -m my_package). The code in __main__.py might be like

import sys
# Import whatever else from your package or otherwise to run the code

def main(argv):
    # Process command line arguments, etc

if __name__ == '__main__':
    sys.exit(main())

Now, in your meta.yaml, you'll have something like:

package:
  name: my_package
  version: '1.0.0'

source:
  path: ..

build:
  number: 0
  script: python setup.py install --single-version-externally-managed --record=record.txt
  entry_points:
    - my_package_script = my_package.__main__:main

requirements:
  - ...

The key line is my_package_script = my_package.__main__:main. The syntax here is the same as for setup.py entry points:

script name = package name.module name:function name

So, in our example, we're using the main function from the __main__.py module in the my_package package.

For a complete example, you can take a look at my package here: https://github.com/bryanwweber/CanSen

like image 50
darthbith Avatar answered Sep 20 '22 23:09

darthbith