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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With