Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read file in Django Management Command

Tags:

python

django

I'm trying to read credentials for the Google Sheets API using gspread. I wrote the following code:

class Command(BaseCommand):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def handle(self, *args, **kwargs):
        scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']

        credentials = ServiceAccountCredentials.from_json_keyfile_name('/static/json/spreadsheets.json', scope)

        gc = gspread.authorize(credentials)

        wks = gc.open("Where is the money Lebowski?").sheet1

        self.stdout.write(self.style.SUCCESS('Succesfully ran "sheets" command'))

Reading the file returns the following error:

FileNotFoundError: [Errno 2] No such file or directory: 'static/json/spreadsheets.json'

I tried multiple paths like:

  • '~/static/json/spreadsheets.json'
  • '/json/spreadsheets.json'
  • 'spreadsheets.json'

But none seem to work. Could anybody help me out here?

like image 925
Sander Bakker Avatar asked Aug 05 '26 11:08

Sander Bakker


1 Answers

When you use an absolute path, it is taken literally i.e. from starting from the root of the filesystem i.e. /.

When you use a relative path i.e. without / at start, it is resolved from the directory where script is invoked from, not where the script actually lies in the filesystem.

So when you invoke the Django management command via e.g. ./manage.py <command>, it looks for a path starting from the current directory of manage.py i.e. os.path.dirname('manage.py'). If you give the path as static/json/spreadsheets.json, the full path it looks for is:

os.path.join(
    os.path.abspath(os.path.dirname('manage.py')),
    '/static/json/spreadsheets.json'
)

So you need to make sure you have the spreadsheets.json file in the right directory. A better approach would be to use an absolute path for these kind of scenarios. If you're on GNU/Linux, you can use:

readlink -f static/json/spreadsheets.json

to get the absolute path.


Also, rather than hardcoding the file, you should take the file as an argument to the management command. Django management command uses argparse for argument parsing, so you can take a peek at the doc.

like image 186
heemayl Avatar answered Aug 08 '26 01:08

heemayl