Repository: Miserlou/Zappa

Issue:
slim_handler breaks file paths & read permission
<!--- Provide a general summary of the issue in the Title above -->
## Context
I'm attempting to read a small data file from the root project directory at runtime. It works locally and on lambda when slim_handler is false but fails on lambda when slim_handler is true.

After identifying that the paths are impacted during runtime, I updated the path to match the runtime environment (for debug purposes only). Unfortunately, it looks like read permission to the unzipped project is not granted because it throws an Errno 13, IO Error when attempting to read the file.

<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
<!--- Also, please make sure that you are running Zappa _from a virtual environment_ and are using Python 2.7 --> 

## Expected Behavior
File paths remain relative to development project & read permission is remains true.
<!--- Tell us what should happen -->

## Actual Behavior
File paths become relative to the handler. Read access not granted to projects unzipped by slim_handler
<!--- Tell us what happens instead -->

## Possible Fix
Not sure if this is fixable without a major change to the way slim_handler works. An update to the documentation explaining the issue and a method to solve it would be awesome.
<!--- Not obligatory, but suggest a fix or reason for the bug -->

## Steps to Reproduce
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug include code to reproduce, if relevant -->
1. Add a file to the root directory with some arbitrary text in it e.g. 
```shell
echo "text from file" > mytext.txt
```

2. Update the documentation's hello world example by appending the text from mytext.txt
```python
# my_app.py
from flask import Flask                                                                                                                                                                                     
app = Flask(__name__)                                                                                                                                                                                       
                                                                                                                                                                                                             
@app.route('/')                                                                                                                                                                                             
def hello():                                                                                                                                                                                                
    with open('mytext.txt', 'r') as w:                                                                                                                                                                      
        txt = w.read()                                                                                                                                                                                      
    return 'Hello, Zappa' + txt                                                                                                                                                                             
                                                                                                                                                                                                            
if __name__ == '__main__':                                                                                                                                                                                  
    app.run()      
```
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Zappa version used: 0.38.0
* Operating System and Python version: Ubuntu 16.04, Python 2.7.12
* Your `zappa_settings.py`: 
```javascript
{
    "dev": {
        "app_function": "my_app.app", 
        "s3_bucket": "zappa-test-dev-uid-0000121",
        "slim_handler": true,
        "debug" : true
    }
}
```

Thanks!


Discussion:
If you change 'mytext.txt' to '/tmp/mytext.txt' does it work?
Gets a IOError, Errno 2. 

Here are the logs:

[1488923423715] [INFO] 2017-03-07T21:50:23.715Z 112a9502-0380-11e7-a355-f9c608252a30 98.81.161.93 - - [07/Mar/2017:21:50:23 +0000] "GET / HTTP/1.1" 500 291 "" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/56.0.2924.76 Safari/537.36" 0/0.813
[1488923427294] [2017-03-07 21:50:27,294] ERROR in app: Exception on / [GET]
[1488923427294] Traceback (most recent call last):
[1488923427294] File "/tmp/pip-build-1bj4OE/flask/flask/app.py", line 1982, in wsgi_app
[1488923427294] File "/tmp/pip-build-1bj4OE/flask/flask/app.py", line 1614, in full_dispatch_request
[1488923427294] File "/tmp/pip-build-1bj4OE/flask/flask/app.py", line 1517, in handle_user_exception
[1488923427294] File "/tmp/pip-build-1bj4OE/flask/flask/app.py", line 1612, in full_dispatch_request
[1488923427294] File "/tmp/pip-build-1bj4OE/flask/flask/app.py", line 1598, in dispatch_request
[1488923427294] File "/tmp/zappa-test/my_app.py", line 6, in hello
[1488923427294] with open('/tmp/mytext.txt', 'r') as w:
[1488923427294] IOError: [Errno 2] No such file or directory: '/tmp/mytext.txt'
[1488923427294] [INFO] 2017-03-07T21:50:27.294Z 13444dd4-0380-11e7-a2e5-9f48dad31f31 98.81.161.93 - - [07/Mar/2017:21:50:27 +0000] "GET / HTTP/1.1" 500 291 "" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/56.0.2924.76 Safari/537.36" 0/0.851
Adding the URL friendly encoding of the root directory name (which I guess is the S3 bucket name?) after /tmp worked.

i.e.
/tmp/<directory name>/mytext.txt

Can you think of a way of updating references automatically? If not, let me know if you'd be willing to merge some additions to the README around slim_handler & I'll dig into it a bit more + submit a PR
We might able to just add a os.chdir('tmp/' + root_directory_name) in there
somewhere

On Tue, Mar 7, 2017 at 5:56 PM, Oliver Rice <notifications@github.com>
wrote:

> Adding the URL friendly encoding of the root directory name (which I guess
> is the S3 bucket name?) after /tmp worked.
>
> i.e.
> /tmp//mytext.txt
>
> Can you think of a way of updating references automatically? If not, let
> me know if you'd be willing to merge some additions to the README around
> slim_handler & I'll dig into it a bit more + submit a PR
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/Miserlou/Zappa/issues/702#issuecomment-284888055>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AAIi00_IWPp0bJsTN3IZTIfS2wVooWhoks5rjeCfgaJpZM4MWDey>
> .
>


Resolving patch:
diff --git a/zappa/handler.py b/zappa/handler.py
--- a/zappa/handler.py
+++ b/zappa/handler.py
@@ -168,6 +168,9 @@ def load_remote_project_zip(self, project_zip_path):
 
         # Add to project path
         sys.path.insert(0, project_folder)
+        
+        # Change working directory to project folder
+        os.chdir(project_folder)
         return True
 
     def load_remote_settings(self, remote_bucket, remote_file):


Test patch: