'Python's working directory when running with WSGI and Apache

I have a web application that, among other things, will query a database and create an Excel spreadsheet with the data. I need to save the spreadsheet to the server's disk before sending the file to the client machine. I'm using the Flask framework and openpyxl to generate the spreadsheet. Everything works fine when running on Flask's dev server, but the real server is Apache2 with WSGI. When I run it there, a "Permission Denied" error is raised when it tries to save the spreadsheet. I don't know what Python's working directory is when running in Apache/WSGI.

Is there a way, maybe in the WSGI config file, to change the working directory, or somehow control where it will save to? If possible, I'd like to use relative paths for saving (it makes the code more portable) which is why changing the working directory is the best solution.



Solution 1:[1]

You should not change working directory.

Use:

import os
here = os.path.dirname(__file__)

The variable here will then contain the directory where that code file is located. You can then construct absolute paths for things relative to that.

database = os.path.join(here, 'database.db')

Do note that the user your code runs under in Apache still needs read/write access to that directory.

As always, make sure you read the documentation. Relevant sections of documentation are:

Solution 2:[2]

I had a similar problem where I wanted to use a glob() with a relative path. It worked in my development environment but not on the server with mod_wsgi. I discovered here that there is a 'home=' option that you can add to the WSGIDaemonProcess directive to set the initial working directory of your application. You find that in the virtual host file (on my system in /etc/apache2/sites-available/mysite.conf)

Solution 3:[3]

While add a path to relative directory works, probably you need to change lot of code.

Change home from WSGIDaemonProcess works but you need to set one for each vhost

reset the cwd at beginning of your script:

here = os.path.dirname(__file__)
os.chdir(here)

for a quick workaround

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jay Christnach
Solution 3 albfan