Reputation: 33
I want to build an application, say it's called helloworld, with a command line interface in python. My application as multiple nested modules and a top level module main.py.
Say the layout is :
helloworld/
helloworld/
__init__.py
module1/
module2/
module3/
setup.py
main.py
At this point, once my project is installed I can run it using
#> python path/to/helloworld/main.py arg1 arg2 arg3
I want to be able to interact with the program using commands such as :
#> helloworld arg1 arg2 arg3
, in a similar manner as for example, the Flask framework comes with a command line application I can use with #> flask run
.
I looked around and found questions suggesting using a shebang. As far as I can tell, this is not what I want.
I want a self contained application I can install using pip and then launch directly without any reference to the python interpreter.
How should I go about this ?
EDIT
It is an important requirement to me that the package can be installed using pip and the command line interface is immediately available. Shebangs/fiddling manually with the path/creating an additional shell script do not solve my problem.
Upvotes: 1
Views: 2816
Reputation: 820
I know this has already been answered, but just in case someone comes across this in the future..
Here's what worked for a new package I'm developing after reading up on this from many different sources.
tldr; use setuptools
and add your command as a console_scripts
option under [options.entry_points]
in setup.cfg
.
You will also need some other fields in setup.cfg
or setup.py
for package discovery to work. Check out the setuptools docs for that.
Example entry point:
[options.entry_points]
console_scripts =
mycmd = mypackage.mymodule:myfunc
For local development, you can install the package in editable (development) mode with pip install -e .
which will allow you to test the command as if you pip intall
ed it.
Alternatively, you could create a __main__.py
that initializes your module when you run python -m mypackage
from the root.
from mypackage import app
if __name__ == '__main__':
app.main()
I personally opted for both. Usually your main.py
(or app.py
in my example) belongs in your package not project level dir. Then you would create __main__.py
there as well.
Upvotes: 1
Reputation: 577
There's an explanation here of how to tell setuptools to add a script to the Python Scripts-folder during the pip installation. You can then make that script be for example a bat-file that calls your Python-script. In that way you achieve both that you do not need to write .py
for your script to run, and that it happens automatically.
Upvotes: 1
Reputation: 887
You should add main.py to your PATH. What happens when you are running flask run
is that your teminal looks up the command flask in PATH and runs the program that it is pointing to. You could see it as a kind of shortcut to the program Flask.
By adding your program to your PATH, you can tell the computer that if you type helloworld
in your terminal, the terminal should run /my/path/to/helloworld.py
.
I don't know what OS you are on, so here are links for most common OS on how to add a PATH variable.
Edit: After you gave more explanation, setuptools
is what you are looking for. Please look at this reference to see how to use it.
Upvotes: 1