Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting full path from the relative path with Argparse

I am writing a small command line utility for my script and I can't figure out how to properly get the full path from the argument.

Here's what I mean.

parser = ArgumentParser()
parser.add_argument("-src",
                    required = True, help="path to some folder")
args = parser.parse_args()
print(args.src)

If the user pass the full path, e.g. "/home/username/projectname/folder", everything is fine.

But if the user runs the script from let's say "projectname" folder and pass the relative path "./folder" I get exactly the same string "./folder" while parsing the arguments instead of the full path "/home/username/projectname/folder".

So, I have been wondering if there is some kind of inbuilt functionality in Argparse that allows to get the full path from the relative path?

like image 841
Denis Avatar asked Mar 20 '19 09:03

Denis


People also ask

How do I give path to Argparse?

One can ensure the path is a valid directory with something like: import argparse, os def dir_path(string): if os. path. isdir(string): return string else: raise NotADirectoryError(string) parser = argparse.

How do you pass a file path as an argument in Python?

To use it, you just pass a path or filename into a new Path() object using forward slashes and it handles the rest: Notice two things here: You should use forward slashes with pathlib functions. The Path() object will convert forward slashes into the correct kind of slash for the current operating system.

What does Argparse ArgumentParser ()?

The argparse module provides a convenient interface to handle command-line arguments. It displays the generic usage of the program, help, and errors. The parse_args() function of the ArgumentParser class parses arguments and adds value as an attribute dest of the object.

What is Metavar in Argparse Python?

Metavar: It provides a different name for optional argument in help messages.


Video Answer


2 Answers

To add onto Tryph's answer, you can specify the type parameter in the argument declaration. It can take any callable that takes a single string argument and returns the converted value:

parser.add_argument("-src",
                    required=True,
                    help="path to some folder",
                    type=os.path.abspath)

This returns a string with the absolute path, you could specify your own function as well:

def my_full_path(string):
    script_dir = os.path.dirname(__file__)
    return  os.path.normpath(os.path.join(script_dir, string))


parser = ArgumentParser()
parser.add_argument("-src",
                    required=True,
                    help="path to some folder",
                    type=my_full_path)
like image 28
Alex Avatar answered Oct 20 '22 07:10

Alex


EDIT: The Alex's answer shows how to make argparse manage relative-to-absolute path conversion by simply filling the add_argument's type parameter.


I do not think argparse provides such feature but you can achieve it using os.path.abspath:

abs_src = os.path.abspath(args.src)

Keep in mind that this will make an absolute path by concatenating the working directory with the relative path. Thus the path is considered relative to working directory.


If you want to make the path relative to the script directory, you can use os.path.dirname on the __file__ variable and os.path.join to build an absolute path from a path relative to your Python script:

script_dir = os.path.dirname(__file__)
abs_src = os.path.join(script_dir, args.src)

Finally, since joined path can contain tokens such as . and .., you can "prettify" your built path with os.path.normpath:

abs_path = os.path.normpath(os.path.join(script_dir, args.src))
like image 147
Tryph Avatar answered Oct 20 '22 07:10

Tryph