Repository: Miserlou/Zappa

Issue:
Problems with django management commands
First of all, thanks for Zappa. I haven't been able to use it properly so far (see below), but I'm pretty sure once I get past these initial problems I'll be using it heavily.

I'm probably doing something very silly, as I'm not being able to run the migrations for the default django project with the default app.

``` sh
$ zappa manage dev migrate

Zappa Event: {u'raw_command': u'migrate'}
name 'migrate' is not defined: NameError
Traceback (most recent call last):
  File "/var/task/handler.py", line 476, in lambda_handler
    return LambdaHandler.lambda_handler(event, context)
  File "/var/task/handler.py", line 208, in lambda_handler
    raise ex
NameError: name 'migrate' is not defined
```

The other manage commands seem to be failing as well

``` sh
$ zappa manage dev "shell --version"

Zappa Event: {u'raw_command': u'shell --version'}
name 'shell' is not defined: NameError
Traceback (most recent call last):
  File "/var/task/handler.py", line 476, in lambda_handler
    return LambdaHandler.lambda_handler(event, context)
  File "/var/task/handler.py", line 208, in lambda_handler
    raise ex
NameError: name 'shell' is not defined
```

and

``` sh
$ zappa manage dev showmigrations admin

Zappa Event: {u'raw_command': u'showmigrations admin'}
invalid syntax (<string>, line 1): SyntaxError
Traceback (most recent call last):
  File "/var/task/handler.py", line 476, in lambda_handler
    return LambdaHandler.lambda_handler(event, context)
  File "/var/task/handler.py", line 208, in lambda_handler
    raise ex
  File "<string>", line 1
    showmigrations admin
                       ^
SyntaxError: invalid syntax

```

The django page is up, and I can see the admin login page (the only url that is configured by default).

My virtual environment

``` sh
$ cat requirements.txt 
base58==0.2.3
boto3==1.4.1
botocore==1.4.62
click==6.6
Django==1.10.2
docutils==0.12
futures==3.0.5
hjson==2.0.2
jmespath==0.9.0
kappa==0.6.0
lambda-packages==0.10.0
pkg-resources==0.0.0
placebo==0.8.1
python-dateutil==2.5.3
python-slugify==1.2.1
PyYAML==3.12
requests==2.11.1
s3transfer==0.1.9
six==1.10.0
tqdm==4.8.4
troposphere==1.8.2
Unidecode==0.4.19
Werkzeug==0.11.11
wsgi-request-logger==0.4.6
zappa==0.27.1
```



Discussion:
I was using the version 0.27.1, the one installed via pip. Using the current master b42b719f4359b279fa4c332bca1c0137edcee8d0 I get a different error:

``` sh
$ zappa manage dev migrate
Oh no! An error occurred! :(

==============

Traceback (most recent call last):
  File "/home/jnlaia/tests/zappa/venv/local/lib/python2.7/site-packages/zappa/cli.py", line 1458, in handle
    sys.exit(cli.handle())
  File "/home/jnlaia/tests/zappa/venv/local/lib/python2.7/site-packages/zappa/cli.py", line 207, in handle
    self.dispatch_command(command, environment)
  File "/home/jnlaia/tests/zappa/venv/local/lib/python2.7/site-packages/zappa/cli.py", line 255, in dispatch_command
    if len(command_env) < 2:
NameError: global name 'command_env' is not defined

==============
```

There are many `command_env` around line 255 in `zappa/cli.py` that are not defined, and should be replaced by `self.vargs['command_env']`.
This will fix the current bug, and will allow one to reproduce the original error.

I've found a work around in zappa/cli.py Line 664

```
        if raw_python == 'manage':
            command = {'manage': function_name}
        elif raw_python:
            command = {'raw_command': function_name}
        else:
            command = {'command': function_name} # This is really a string
```

 I'll try and get a PR up soon

I've made a workaround as well. The origin of the problem is the one you are mentioning, but if you notice, the function invoke in which that code is sitting takes as an argument a boolean, whereas it is being called with a completely different argument (a string 'manage'). I don't think it is a good practice to have a variable in a function that can be either a string or a boolean, depending on where it was called.

My workaround was basically adding a new argument to this invoke function called command, that would default to None.

In any case, I think some of the come in this file is quite fragile, and it should be made more robust and elegant... and maintainable.


Resolving patch:
diff --git a/zappa/cli.py b/zappa/cli.py
--- a/zappa/cli.py
+++ b/zappa/cli.py
@@ -269,7 +269,7 @@ def dispatch_command(self, command, environment):
             else:
                 command = command_tail[0] # ex: zappa manage dev showmigrations admin
 
-            self.invoke(command, "manage")
+            self.invoke(command, command="manage")
 
         elif command == 'tail': # pragma: no cover
             self.tail()
@@ -655,16 +655,17 @@ def unschedule(self):
             )
 
 
-    def invoke(self, function_name, raw_python=False):
+    def invoke(self, function_name, raw_python=False, command=None):
         """
         Invoke a remote function.
         """
 
         # Invoke it!
+        key = command if command is not None else 'command'
         if raw_python:
             command = {'raw_command': function_name}
         else:
-            command = {'command': function_name} # This is really a string
+            command = {key: function_name} # This is really a string
 
         # Can't use hjson
         import json as json


Test patch: