Forums

Importing custom module and python system path

My web app seems to be breaking when I import a custom module. I think this has something to do with the python system path. For some reason, it can't find my file containing my API keys. I've read various threads about similar problems. However, I haven't been able to determine what is necessary to correct this. While my original version of the code works on my machine if I download my code from GitHub and try to run that version I get a similar error. I've researched the python system path but I feel as if I'm overlooking something. Any help is appreciated thanks.

2018-04-05 20:45:59,050: Error running WSGI application
2018-04-05 20:45:59,058: FileNotFoundError: [Errno 2] No such file or directory: 'api_file.txt'
2018-04-05 20:45:59,058:   File "/var/www/gcmatt_pythonanywhere_com_wsgi.py", line 81, in <module>
2018-04-05 20:45:59,058:     from src.app import app as application  # noqa
2018-04-05 20:45:59,058: 
2018-04-05 20:45:59,058:   File "/home/gcmatt/capstone/src/app.py", line 3, in <module>
2018-04-05 20:45:59,058:     from src.models.search import Search
2018-04-05 20:45:59,059: 
2018-04-05 20:45:59,059:   File "/home/gcmatt/capstone/src/models/search.py", line 6, in <module>
2018-04-05 20:45:59,059:     with open(api_file, 'r') as file:

[edit by admin: formatting]

I think this is related to the working directory of your code rather than the Python system path. If you're accessing the API key file using a filename like "mykeys.txt", then the file will be looked for in whichever directory your code happens to be running in. When you run the code locally on your machine, this will be whatever directory you've used cd to navigate to before starting the serve, whereas when you run it on PythonAnywhere it will be the directory specified as the working directory on the "Web" page.

There are two solutions:

  1. Set the working directory appropriately on the "Web" page.
  2. (Slightly better) if the file is in a specific location relative to the code that's trying to load it, you can use the __file__ magic Python variable to get the current filename, the the various os.path functions to construct a path relative to that. For example:
    import os
    script_path = os.path.dirname(os.path.abspath( __file__ ))
    api_file = os.path.join(script_path, "mykeys.txt")
    

I have to working directory on the Web page set correctly I believe. The app still won't deploy. I attempted the second solution, I'm not sure if I implemented it correctly. This code goes into the wsgi file correct? The only thing I have been able to do to get the app not crash is to remove the import of my search function from my app.py file. Which makes the app useless. So either the code cannot find the path to the src.models directory or I haven't managed to set the path for api_file.txt correctly.

No, that code goes where you're trying to load the api_file in search.py. The module is being found and imported correctly, but when it's imported, it can't find the api_file because you're using a relative directory or because the file doesn't actually exist.

I can use this to find the file path. I can for example print the file type of api_file or the location but when I try to read the file I get a file not file not found error.

So if I do this, for example, the first half of the code functions but the second half breaks.

api_file = 'api_file.txt' print(api_file) print(type(api_file)) open(api_file, 'r')

script_path = os.path.dirname(os.path.abspath( file )) keys = os.path.join(script_path, "api_file.txt")

print(keys) print(type(keys)) open(keys, 'r')

I've gotten this to run on the web. Still maybe a little confused about abspath but thanks for all your help.

Glad you worked it out.