31

How to open a file in the parent directory in python in AppEngine?

I have a python file module/mod.py with the following code

f = open('../data.yml')
z = yaml.load(f)
f.close()

data.yml is in the parent dir of module. The error I get is

IOError: [Errno 13] file not accessible: '../data.yml'

I am using AppEngine SDK 1.3.3.

Is there a work around for this?

GeekTantra
  • 11,580
  • 6
  • 41
  • 55

5 Answers5

52

The open function operates relative to the current process working directory, not the module it is called from. If the path must be module-relative, do this:

import os.path
f = open(os.path.dirname(__file__) + '/../data.yml')
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 6
    In my opinion, it would be better if, instead of concatenating the filename, you used "os.path.join" For instance: open(os.path.join(os.path.dirname(__file__), os.pardir, 'data.yml')) – ThatsAMorais Sep 17 '15 at 04:32
  • Yes. But make sure to use \__file\__ instead of file – sthiers Jul 18 '16 at 09:44
  • 1
    Alternatively, make sure to wrap `code` in back-quotes. – Marcelo Cantos Jul 18 '16 at 11:15
  • This doesnt work for me. It looks for a path with /../ component. Error is FileNotFoundError: [Errno 2] No such file or directory: '/brownie/scripts/../brownie-config.yml' – tonisives Dec 29 '21 at 07:40
11

Having encountered this question and not being satisfied with the answer, I ran across a different solution. It took the following to get what I wanted.

  1. Determine the current directory using os.path.dirname:

    current_directory = os.path.dirname(__file__)

  2. Determine the parent directory using os.path.split:

    parent_directory = os.path.split(current_directory)[0] # Repeat as needed

  3. Join parent_directory with any sub-directories:

    file_path = os.path.join(parent_directory, 'path', 'to', 'file')

  4. Open the file:

    open(file_path)

Combined together:

open(os.path.join(os.path.split(os.path.dirname(__file__))[0], 'path', 'to', 'file')
ThatsAMorais
  • 659
  • 8
  • 16
5

alternative solution

You can also use the sys module to get the current working directory.
Thus, another alternative to do the same thing would be:

import sys
f = open(sys.path[0] + '/../data.yml')
anjandash
  • 797
  • 10
  • 21
1

I wrote a little function called get_parent_directory() which might help getting the path of the parent directory:

import sys
def get_parent_directory():
    list = sys.path[0].split('/')[:-1]
    return_str = ''
    for element in list:
        return_str += element + '/'
    return return_str.rstrip('/')
  • 1
    It is more correct to use `os.path.dirname` or similar specialized functions and doesn't reinvent them by yourself. Also more correct way to join strings will be `'/'.join(list)` – ont.rif Aug 20 '21 at 14:37
0

@ThatsAmorais answer in a function

import os

def getParent(path: str, levels=1) -> str:
    """
    @param path: starts without /
    @return: Parent path at the specified levels above.
    """
    current_directory = os.path.dirname(__file__)

    parent_directory = current_directory
    for i in range(0, levels):
        parent_directory = os.path.split(parent_directory)[0]

    file_path = os.path.join(parent_directory, path)
    return file_path
tonisives
  • 1,962
  • 1
  • 18
  • 17