1

This may sound silly, but I just need to know how this is possible.

I have a python file 'hello.py' which accepts an argument using argParse.

The code is as below:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--message", type=str, required=True)
args = parser.parse_args()

message = args.message
print(f'Your message: {message}' )

The code works as expected when I run: python hello.py --message "Hi my name is Tony"

And I get the following as the output:

Your message: Hi my name is Tony

However, the requirement is that when I the command, I want to run it in such a way that python hello.py can be substituted to a unique command.

Want it in such a way that I could run this command hello from any directory. Kind of need it like an environment variable.

I want to make it a Python package, upload to pypi.org and after someone go a pip install, they should be able to run something like:

hello --message "Hi my name is Tony"

Does anyone know how to achieve this setup?

3
  • How about a .bat in Windows, or a shell script in *nix? Commented May 31, 2022 at 14:30
  • Yes, you need to make the file executable, provide an appropriate shebang at the top of the file, and make sure the file is saved (as hello, not hello.py) in a directory that is on your search path. This is operating-system dependent and not really a programming question. Commented May 31, 2022 at 16:22
  • I made the file an executable using Pyinstaller. Ran the command pyinstaller hello.py and it created some files and folders. I renamed the hello.py to 'hello'. But after I ran hello --message "Hii", It gave me an error stating that: bash: hello: command not found Commented May 31, 2022 at 17:19

4 Answers 4

3
+50

You can install your the command as an entry-point using setuptools (see setuptools Quickstart).

As a quick and flat solution to your case, you should have a directory (root) with the following files:

root
|    pyproject.toml
|    setup.cfg
|    hello.py

pyproject.toml:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

setup.cfg:

[options.entry_points]
console_scripts =
    hello = hello:main

hello.py:

import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--message", type=str, required=True)
    args = parser.parse_args()

    message = args.message
    print(f'Your message: {message}' )

Then, you can install the command by running: python -m pip install . (don't forget the .) from the root directory (you'll need pip installed of course).

After the installation, you should be able to run the command as you wanted: hello --message "Hi my name is Tony"

Sign up to request clarification or add additional context in comments.

1 Comment

This is what I was going to answer, but you took the lead. This is the most pythonic answer and the best one imo. Using this method you can even distribute your command line application later via pypi.
2

This is done differently in Unix-like systems and in Windows. Unix-like is easier.

Unix-like

There are four things you need to do:

  1. Rename your script to hello. (It will also work if you keep it as hello.py, but then you'll be calling it as hello.py --message "Hi my name is Tony").
  2. Give it permission to execute: chmod 755 hello.
  3. Add to it a "shebang line". The shebang line is a line that is the first of the script and starts with #!. This is not a Python feature but a Unix shell feature. For Python, this is just a comment. But the Unix shell looks into that line in order to determine what program it should use to run the file. Nowadays the safest shebang line for Python programs seems to be #!/usr/bin/env python3 because some systems by default don't have a "python" executable, they only have a "python3" executable.
  4. Put the file in a directory that is included in your "shell path". The shell path is the list of directories in which the shell looks for executable files. Run echo $PATH to see that list of directories (they are separated by colons). For example, when you type ls, the shell will search that list of directories, in order, until it finds an executable file with the name ls. In that particular example, it will usually find it in the /bin directory. For beginners, putting hello in /usr/local/bin is the best option in many Unix-like systems, like most GNU/Linux systems; that directory is for executable files added to the system through any way other than the system's package manager. For some Unix-like systems like Mac OS X, the appropriate directory might be different.

Beyond the beginner stage, you will want to use virtualenvs, and virtualenv demystified would be a good thing to read after this answer.

Windows

Windows does not provide an easy solution out of the box, so you need to use third-party solutions like pyinstaller, which create an .exe file, that typically contains a copy of the Python interpreter.

There is also a simpler solution. You can create a hello.bat file that executes your program. Assuming python.exe is in C:\Program Files\Python and that hello.py is in C:\Users\Alice, the contents of the file should be:

"C:\Program Files\Python\python.exe" "C:\Users\Alice\hello.py" %*

You can then put hello.bat in a directory that is in the system path, such as C:\Windows. Users don't need to type the whole hello.bat; like .exe files, you can omit the extension and just type hello.

The %* represents the arguments given to hello.bat, so if the user types in hello --message "Hi, I'm Tony", then the batch file will execute C:\...\python.exe C:\...\hello.py --message "Hi, I'm Tony".

PIP

Assuming that you already know how to create a package in PyPI, which is a whole another story, you can use the entry_points argument of setuptools.setup() to do what you want. (Again, I don't think it's easy to make that work in Windows.)

2 Comments

Can you give more info about setting this in windows? How to create the .exe and all?
It's not something that can be done in a couple of paragraphs. You need to read pyinstaller's documentation and then ask more specific questions. However I added a simpler Windows option in my answer.
0

Check out this post: https://gist.github.com/umangahuja1/51da3a453803f1f67f4eee5de129d4db

Essentially what you want to do is modify your script to tell the system it should use python path to run rather than shell. After that you turn permissions to make it executable and then run it.

Comments

-1

You can use sys to get the args

import sys

and then get the args like that:

args = sys.args()

when you run it, use:

py hello.py argument1 argument2

1 Comment

That's not actually the intention. I am already using argParse for that.

Your Answer

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.