Repository: Miserlou/Zappa

Issue:
Drop support for Python versions < 3.6
Python 2.x is now end of life and will no longer receive updates.

##  Context

Python 2.x and 3.{4, 5} are either no longer supported or don't have official AWS Lambda runtimes.

Some additional references in favor of this change:

- [Python Clock - Lapsed](https://pythonclock.org/)
- [Python 3 Statement](https://python3statement.org/)
- [Pandas drops Python 2 support - July 2019](https://pandas.pydata.org/#v0-25-0-final-july-18-2019)
- [NumPy drops Python 2 support - Proposed January 2019](https://numpy.org/neps/nep-0014-dropping-python2.7-proposal.html)
- [Pytest drops Python 2 support](https://pytest.readthedocs.io/en/latest/py27-py34-deprecation.html)
- [PEP-373 - 2.7 Lifecycle](https://www.python.org/dev/peps/pep-0373/)

## Possible Fix
I propose we add a deprecation notice in the next patch for 0.49.x and increment the minor (`0.49.0` -> `0.50.0`), dropping support for Python versions `< 3.6` by setting python min requirement, removing six/compat support, and convert relevant code to Python 3.6+.



Discussion:
So, this has been done more by accident than I would have liked, as 0.49 doesn't work on 2.7 and that was missed it on the preparation of the release. As nobody is thinking of going back, I'll update the README and Changelog to note that 0.48.2 was the lst one with 2.7 support. Sorry for the unexpected update.

Resolving patch:
diff --git a/zappa/cli.py b/zappa/cli.py
--- a/zappa/cli.py
+++ b/zappa/cli.py
@@ -154,8 +154,8 @@ def get_stage_setting(stage, extended_stages=None):
         settings = get_stage_setting(stage=self.api_stage)
 
         # Backwards compatible for delete_zip setting that was more explicitly named delete_local_zip
-        if u'delete_zip' in settings:
-            settings[u'delete_local_zip'] = settings.get(u'delete_zip')
+        if 'delete_zip' in settings:
+            settings['delete_local_zip'] = settings.get('delete_zip')
 
         settings.update(self.stage_config_overrides)
 
@@ -1499,9 +1499,9 @@ def tabular_print(title, value):
             event_dict = {}
             rule_name = rule['Name']
             event_dict["Event Rule Name"] = rule_name
-            event_dict["Event Rule Schedule"] = rule.get(u'ScheduleExpression', None)
-            event_dict["Event Rule State"] = rule.get(u'State', None).title()
-            event_dict["Event Rule ARN"] = rule.get(u'Arn', None)
+            event_dict["Event Rule Schedule"] = rule.get('ScheduleExpression', None)
+            event_dict["Event Rule State"] = rule.get('State', None).title()
+            event_dict["Event Rule ARN"] = rule.get('Arn', None)
             status_dict['Events'].append(event_dict)
 
         if return_json:
@@ -1569,7 +1569,7 @@ def init(self, settings_file="zappa_settings.json"):
             raise ClickException("This project already has a " + click.style("{0!s} file".format(settings_file), fg="red", bold=True) + "!")
 
         # Explain system.
-        click.echo(click.style(u"""\n███████╗ █████╗ ██████╗ ██████╗  █████╗
+        click.echo(click.style("""\n███████╗ █████╗ ██████╗ ██████╗  █████╗
 ╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
   ███╔╝ ███████║██████╔╝██████╔╝███████║
  ███╔╝  ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
diff --git a/zappa/handler.py b/zappa/handler.py
--- a/zappa/handler.py
+++ b/zappa/handler.py
@@ -361,7 +361,7 @@ def handler(self, event, context):
 
         # This is the result of a keep alive, recertify
         # or scheduled event.
-        if event.get('detail-type') == u'Scheduled Event':
+        if event.get('detail-type') == 'Scheduled Event':
 
             whole_function = event['resources'][0].split('/')[-1].split('-')[-1]
 
@@ -440,7 +440,7 @@ def handler(self, event, context):
             return result
 
         # This is an API Gateway authorizer event
-        elif event.get('type') == u'TOKEN':
+        elif event.get('type') == 'TOKEN':
             whole_function = self.settings.AUTHORIZER_FUNCTION
             if whole_function:
                 app_function = self.import_module_and_get_function(whole_function)


Test patch:
diff --git a/tests/tests.py b/tests/tests.py
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -479,54 +479,54 @@ def test_wsgi_event(self):
         # }
 
         event = {
-            u'body': None,
-            u'resource': u'/',
-            u'requestContext': {
-                u'resourceId': u'6cqjw9qu0b',
-                u'apiId': u'9itr2lba55',
-                u'resourcePath': u'/',
-                u'httpMethod': u'GET',
-                u'requestId': u'c17cb1bf-867c-11e6-b938-ed697406e3b5',
-                u'accountId': u'724336686645',
-                u'identity': {
-                    u'apiKey': None,
-                    u'userArn': None,
-                    u'cognitoAuthenticationType': None,
-                    u'caller': None,
-                    u'userAgent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
-                    u'user': None,
-                    u'cognitoIdentityPoolId': None,
-                    u'cognitoIdentityId': None,
-                    u'cognitoAuthenticationProvider': None,
-                    u'sourceIp': u'50.191.225.98',
-                    u'accountId': None,
+            'body': None,
+            'resource': '/',
+            'requestContext': {
+                'resourceId': '6cqjw9qu0b',
+                'apiId': '9itr2lba55',
+                'resourcePath': '/',
+                'httpMethod': 'GET',
+                'requestId': 'c17cb1bf-867c-11e6-b938-ed697406e3b5',
+                'accountId': '724336686645',
+                'identity': {
+                    'apiKey': None,
+                    'userArn': None,
+                    'cognitoAuthenticationType': None,
+                    'caller': None,
+                    'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
+                    'user': None,
+                    'cognitoIdentityPoolId': None,
+                    'cognitoIdentityId': None,
+                    'cognitoAuthenticationProvider': None,
+                    'sourceIp': '50.191.225.98',
+                    'accountId': None,
                     },
-                u'stage': u'devorr',
+                'stage': 'devorr',
                 },
-            u'queryStringParameters': None,
-            u'httpMethod': u'GET',
-            u'pathParameters': None,
-            u'headers': {
-                u'Via': u'1.1 6801928d54163af944bf854db8d5520e.cloudfront.net (CloudFront)',
-                u'Accept-Language': u'en-US,en;q=0.5',
-                u'Accept-Encoding': u'gzip, deflate, br',
-                u'CloudFront-Is-SmartTV-Viewer': u'false',
-                u'CloudFront-Forwarded-Proto': u'https',
-                u'X-Forwarded-For': u'50.191.225.98, 204.246.168.101',
-                u'CloudFront-Viewer-Country': u'US',
-                u'Accept': u'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
-                u'Upgrade-Insecure-Requests': u'1',
-                u'Host': u'9itr2lba55.execute-api.us-east-1.amazonaws.com',
-                u'X-Forwarded-Proto': u'https',
-                u'X-Amz-Cf-Id': u'qgNdqKT0_3RMttu5KjUdnvHI3OKm1BWF8mGD2lX8_rVrJQhhp-MLDw==',
-                u'CloudFront-Is-Tablet-Viewer': u'false',
-                u'X-Forwarded-Port': u'443',
-                u'User-Agent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
-                u'CloudFront-Is-Mobile-Viewer': u'false',
-                u'CloudFront-Is-Desktop-Viewer': u'true',
+            'queryStringParameters': None,
+            'httpMethod': 'GET',
+            'pathParameters': None,
+            'headers': {
+                'Via': '1.1 6801928d54163af944bf854db8d5520e.cloudfront.net (CloudFront)',
+                'Accept-Language': 'en-US,en;q=0.5',
+                'Accept-Encoding': 'gzip, deflate, br',
+                'CloudFront-Is-SmartTV-Viewer': 'false',
+                'CloudFront-Forwarded-Proto': 'https',
+                'X-Forwarded-For': '50.191.225.98, 204.246.168.101',
+                'CloudFront-Viewer-Country': 'US',
+                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
+                'Upgrade-Insecure-Requests': '1',
+                'Host': '9itr2lba55.execute-api.us-east-1.amazonaws.com',
+                'X-Forwarded-Proto': 'https',
+                'X-Amz-Cf-Id': 'qgNdqKT0_3RMttu5KjUdnvHI3OKm1BWF8mGD2lX8_rVrJQhhp-MLDw==',
+                'CloudFront-Is-Tablet-Viewer': 'false',
+                'X-Forwarded-Port': '443',
+                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
+                'CloudFront-Is-Mobile-Viewer': 'false',
+                'CloudFront-Is-Desktop-Viewer': 'true',
                 },
-            u'stageVariables': None,
-            u'path': u'/',
+            'stageVariables': None,
+            'path': '/',
             }
 
         request = create_wsgi_request(event)
@@ -572,7 +572,7 @@ def test_wsgi_logging(self):
         #     "query": {}
         # }
 
-        event = {u'body': None, u'resource': u'/{proxy+}', u'requestContext': {u'resourceId': u'dg451y', u'apiId': u'79gqbxq31c', u'resourcePath': u'/{proxy+}', u'httpMethod': u'GET', u'requestId': u'766df67f-8991-11e6-b2c4-d120fedb94e5', u'accountId': u'724336686645', u'identity': {u'apiKey': None, u'userArn': None, u'cognitoAuthenticationType': None, u'caller': None, u'userAgent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:49.0) Gecko/20100101 Firefox/49.0', u'user': None, u'cognitoIdentityPoolId': None, u'cognitoIdentityId': None, u'cognitoAuthenticationProvider': None, u'sourceIp': u'96.90.37.59', u'accountId': None}, u'stage': u'devorr'}, u'queryStringParameters': None, u'httpMethod': u'GET', u'pathParameters': {u'proxy': u'asdf1/asdf2'}, u'headers': {u'Via': u'1.1 b2aeb492548a8a2d4036401355f928dd.cloudfront.net (CloudFront)', u'Accept-Language': u'en-US,en;q=0.5', u'Accept-Encoding': u'gzip, deflate, br', u'X-Forwarded-Port': u'443', u'X-Forwarded-For': u'96.90.37.59, 54.240.144.50', u'CloudFront-Viewer-Country': u'US', u'Accept': u'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', u'Upgrade-Insecure-Requests': u'1', u'Host': u'79gqbxq31c.execute-api.us-east-1.amazonaws.com', u'X-Forwarded-Proto': u'https', u'X-Amz-Cf-Id': u'BBFP-RhGDrQGOzoCqjnfB2I_YzWt_dac9S5vBcSAEaoM4NfYhAQy7Q==', u'User-Agent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:49.0) Gecko/20100101 Firefox/49.0', u'CloudFront-Forwarded-Proto': u'https'}, u'stageVariables': None, u'path': u'/asdf1/asdf2'}
+        event = {'body': None, 'resource': '/{proxy+}', 'requestContext': {'resourceId': 'dg451y', 'apiId': '79gqbxq31c', 'resourcePath': '/{proxy+}', 'httpMethod': 'GET', 'requestId': '766df67f-8991-11e6-b2c4-d120fedb94e5', 'accountId': '724336686645', 'identity': {'apiKey': None, 'userArn': None, 'cognitoAuthenticationType': None, 'caller': None, 'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:49.0) Gecko/20100101 Firefox/49.0', 'user': None, 'cognitoIdentityPoolId': None, 'cognitoIdentityId': None, 'cognitoAuthenticationProvider': None, 'sourceIp': '96.90.37.59', 'accountId': None}, 'stage': 'devorr'}, 'queryStringParameters': None, 'httpMethod': 'GET', 'pathParameters': {'proxy': 'asdf1/asdf2'}, 'headers': {'Via': '1.1 b2aeb492548a8a2d4036401355f928dd.cloudfront.net (CloudFront)', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'X-Forwarded-Port': '443', 'X-Forwarded-For': '96.90.37.59, 54.240.144.50', 'CloudFront-Viewer-Country': 'US', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Upgrade-Insecure-Requests': '1', 'Host': '79gqbxq31c.execute-api.us-east-1.amazonaws.com', 'X-Forwarded-Proto': 'https', 'X-Amz-Cf-Id': 'BBFP-RhGDrQGOzoCqjnfB2I_YzWt_dac9S5vBcSAEaoM4NfYhAQy7Q==', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:49.0) Gecko/20100101 Firefox/49.0', 'CloudFront-Forwarded-Proto': 'https'}, 'stageVariables': None, 'path': '/asdf1/asdf2'}
 
         environ = create_wsgi_request(event, trailing_slash=False)
         response_tuple = collections.namedtuple('Response', ['status_code', 'content'])
@@ -581,39 +581,39 @@ def test_wsgi_logging(self):
         le = common_log(environ, response, response_time=False)
 
     def test_wsgi_multipart(self):
-        #event = {u'body': u'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS03Njk1MjI4NDg0Njc4MTc2NTgwNjMwOTYxDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9Im15c3RyaW5nIg0KDQpkZGQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tNzY5NTIyODQ4NDY3ODE3NjU4MDYzMDk2MS0tDQo=', u'headers': {u'Content-Type': u'multipart/form-data; boundary=---------------------------7695228484678176580630961', u'Via': u'1.1 38205a04d96d60185e88658d3185ccee.cloudfront.net (CloudFront)', u'Accept-Language': u'en-US,en;q=0.5', u'Accept-Encoding': u'gzip, deflate, br', u'CloudFront-Is-SmartTV-Viewer': u'false', u'CloudFront-Forwarded-Proto': u'https', u'X-Forwarded-For': u'71.231.27.57, 104.246.180.51', u'CloudFront-Viewer-Country': u'US', u'Accept': u'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', u'User-Agent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0', u'Host': u'xo2z7zafjh.execute-api.us-east-1.amazonaws.com', u'X-Forwarded-Proto': u'https', u'Cookie': u'zappa=AQ4', u'CloudFront-Is-Tablet-Viewer': u'false', u'X-Forwarded-Port': u'443', u'Referer': u'https://xo8z7zafjh.execute-api.us-east-1.amazonaws.com/former/post', u'CloudFront-Is-Mobile-Viewer': u'false', u'X-Amz-Cf-Id': u'31zxcUcVyUxBOMk320yh5NOhihn5knqrlYQYpGGyOngKKwJb0J0BAQ==', u'CloudFront-Is-Desktop-Viewer': u'true'}, u'params': {u'parameter_1': u'post'}, u'method': u'POST', u'query': {}}
+        #event = {'body': 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS03Njk1MjI4NDg0Njc4MTc2NTgwNjMwOTYxDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9Im15c3RyaW5nIg0KDQpkZGQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tNzY5NTIyODQ4NDY3ODE3NjU4MDYzMDk2MS0tDQo=', 'headers': {'Content-Type': 'multipart/form-data; boundary=---------------------------7695228484678176580630961', 'Via': '1.1 38205a04d96d60185e88658d3185ccee.cloudfront.net (CloudFront)', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'CloudFront-Is-SmartTV-Viewer': 'false', 'CloudFront-Forwarded-Proto': 'https', 'X-Forwarded-For': '71.231.27.57, 104.246.180.51', 'CloudFront-Viewer-Country': 'US', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0', 'Host': 'xo2z7zafjh.execute-api.us-east-1.amazonaws.com', 'X-Forwarded-Proto': 'https', 'Cookie': 'zappa=AQ4', 'CloudFront-Is-Tablet-Viewer': 'false', 'X-Forwarded-Port': '443', 'Referer': 'https://xo8z7zafjh.execute-api.us-east-1.amazonaws.com/former/post', 'CloudFront-Is-Mobile-Viewer': 'false', 'X-Amz-Cf-Id': '31zxcUcVyUxBOMk320yh5NOhihn5knqrlYQYpGGyOngKKwJb0J0BAQ==', 'CloudFront-Is-Desktop-Viewer': 'true'}, 'params': {'parameter_1': 'post'}, 'method': 'POST', 'query': {}}
 
         event = {
-            u'body': u'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS03Njk1MjI4NDg0Njc4MTc2NTgwNjMwOTYxDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9Im15c3RyaW5nIg0KDQpkZGQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tNzY5NTIyODQ4NDY3ODE3NjU4MDYzMDk2MS0tDQo=',
-            u'resource': u'/',
-            u'requestContext': {
-                u'resourceId': u'6cqjw9qu0b',
-                u'apiId': u'9itr2lba55',
-                u'resourcePath': u'/',
-                u'httpMethod': u'POST',
-                u'requestId': u'c17cb1bf-867c-11e6-b938-ed697406e3b5',
-                u'accountId': u'724336686645',
-                u'identity': {
-                    u'apiKey': None,
-                    u'userArn': None,
-                    u'cognitoAuthenticationType': None,
-                    u'caller': None,
-                    u'userAgent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
-                    u'user': None,
-                    u'cognitoIdentityPoolId': None,
-                    u'cognitoIdentityId': None,
-                    u'cognitoAuthenticationProvider': None,
-                    u'sourceIp': u'50.191.225.98',
-                    u'accountId': None,
+            'body': 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS03Njk1MjI4NDg0Njc4MTc2NTgwNjMwOTYxDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9Im15c3RyaW5nIg0KDQpkZGQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tNzY5NTIyODQ4NDY3ODE3NjU4MDYzMDk2MS0tDQo=',
+            'resource': '/',
+            'requestContext': {
+                'resourceId': '6cqjw9qu0b',
+                'apiId': '9itr2lba55',
+                'resourcePath': '/',
+                'httpMethod': 'POST',
+                'requestId': 'c17cb1bf-867c-11e6-b938-ed697406e3b5',
+                'accountId': '724336686645',
+                'identity': {
+                    'apiKey': None,
+                    'userArn': None,
+                    'cognitoAuthenticationType': None,
+                    'caller': None,
+                    'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
+                    'user': None,
+                    'cognitoIdentityPoolId': None,
+                    'cognitoIdentityId': None,
+                    'cognitoAuthenticationProvider': None,
+                    'sourceIp': '50.191.225.98',
+                    'accountId': None,
                     },
-                u'stage': u'devorr',
+                'stage': 'devorr',
                 },
-            u'queryStringParameters': None,
-            u'httpMethod': u'POST',
-            u'pathParameters': None,
-            u'headers': {u'Content-Type': u'multipart/form-data; boundary=---------------------------7695228484678176580630961', u'Via': u'1.1 38205a04d96d60185e88658d3185ccee.cloudfront.net (CloudFront)', u'Accept-Language': u'en-US,en;q=0.5', u'Accept-Encoding': u'gzip, deflate, br', u'CloudFront-Is-SmartTV-Viewer': u'false', u'CloudFront-Forwarded-Proto': u'https', u'X-Forwarded-For': u'71.231.27.57, 104.246.180.51', u'CloudFront-Viewer-Country': u'US', u'Accept': u'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', u'User-Agent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0', u'Host': u'xo2z7zafjh.execute-api.us-east-1.amazonaws.com', u'X-Forwarded-Proto': u'https', u'Cookie': u'zappa=AQ4', u'CloudFront-Is-Tablet-Viewer': u'false', u'X-Forwarded-Port': u'443', u'Referer': u'https://xo8z7zafjh.execute-api.us-east-1.amazonaws.com/former/post', u'CloudFront-Is-Mobile-Viewer': u'false', u'X-Amz-Cf-Id': u'31zxcUcVyUxBOMk320yh5NOhihn5knqrlYQYpGGyOngKKwJb0J0BAQ==', u'CloudFront-Is-Desktop-Viewer': u'true'},
-            u'stageVariables': None,
-            u'path': u'/',
+            'queryStringParameters': None,
+            'httpMethod': 'POST',
+            'pathParameters': None,
+            'headers': {'Content-Type': 'multipart/form-data; boundary=---------------------------7695228484678176580630961', 'Via': '1.1 38205a04d96d60185e88658d3185ccee.cloudfront.net (CloudFront)', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'CloudFront-Is-SmartTV-Viewer': 'false', 'CloudFront-Forwarded-Proto': 'https', 'X-Forwarded-For': '71.231.27.57, 104.246.180.51', 'CloudFront-Viewer-Country': 'US', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0', 'Host': 'xo2z7zafjh.execute-api.us-east-1.amazonaws.com', 'X-Forwarded-Proto': 'https', 'Cookie': 'zappa=AQ4', 'CloudFront-Is-Tablet-Viewer': 'false', 'X-Forwarded-Port': '443', 'Referer': 'https://xo8z7zafjh.execute-api.us-east-1.amazonaws.com/former/post', 'CloudFront-Is-Mobile-Viewer': 'false', 'X-Amz-Cf-Id': '31zxcUcVyUxBOMk320yh5NOhihn5knqrlYQYpGGyOngKKwJb0J0BAQ==', 'CloudFront-Is-Desktop-Viewer': 'true'},
+            'stageVariables': None,
+            'path': '/',
             }
 
         environ = create_wsgi_request(event, trailing_slash=False)
@@ -623,37 +623,37 @@ def test_wsgi_multipart(self):
 
     def test_wsgi_without_body(self):
         event = {
-            u'body': None,
-            u'resource': u'/',
-            u'requestContext': {
-                u'resourceId': u'6cqjw9qu0b',
-                u'apiId': u'9itr2lba55',
-                u'resourcePath': u'/',
-                u'httpMethod': u'POST',
-                u'requestId': u'c17cb1bf-867c-11e6-b938-ed697406e3b5',
-                u'accountId': u'724336686645',
-                u'identity': {
-                    u'apiKey': None,
-                    u'userArn': None,
-                    u'cognitoAuthenticationType': None,
-                    u'caller': None,
-                    u'userAgent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
-                    u'user': None,
-                    u'cognitoIdentityPoolId': None,
-                    u'cognitoIdentityId': None,
-                    u'cognitoAuthenticationProvider': None,
-                    u'sourceIp': u'50.191.225.98',
-                    u'accountId': None,
+            'body': None,
+            'resource': '/',
+            'requestContext': {
+                'resourceId': '6cqjw9qu0b',
+                'apiId': '9itr2lba55',
+                'resourcePath': '/',
+                'httpMethod': 'POST',
+                'requestId': 'c17cb1bf-867c-11e6-b938-ed697406e3b5',
+                'accountId': '724336686645',
+                'identity': {
+                    'apiKey': None,
+                    'userArn': None,
+                    'cognitoAuthenticationType': None,
+                    'caller': None,
+                    'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:48.0) Gecko/20100101 Firefox/48.0',
+                    'user': None,
+                    'cognitoIdentityPoolId': None,
+                    'cognitoIdentityId': None,
+                    'cognitoAuthenticationProvider': None,
+                    'sourceIp': '50.191.225.98',
+                    'accountId': None,
                     },
-                u'stage': u'devorr',
+                'stage': 'devorr',
                 },
-            u'queryStringParameters': None,
-            u'httpMethod': u'POST',
-            u'pathParameters': None,
-            u'headers': {u'Via': u'1.1 38205a04d96d60185e88658d3185ccee.cloudfront.net (CloudFront)', u'Accept-Language': u'en-US,en;q=0.5', u'Accept-Encoding': u'gzip, deflate, br', u'CloudFront-Is-SmartTV-Viewer': u'false', u'CloudFront-Forwarded-Proto': u'https', u'X-Forwarded-For': u'71.231.27.57, 104.246.180.51', u'CloudFront-Viewer-Country': u'US', u'Accept': u'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', u'User-Agent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0', u'Host': u'xo2z7zafjh.execute-api.us-east-1.amazonaws.com', u'X-Forwarded-Proto': u'https', u'Cookie': u'zappa=AQ4', u'CloudFront-Is-Tablet-Viewer': u'false', u'X-Forwarded-Port': u'443', u'Referer': u'https://xo8z7zafjh.execute-api.us-east-1.amazonaws.com/former/post', u'CloudFront-Is-Mobile-Viewer': u'false', u'X-Amz-Cf-Id': u'31zxcUcVyUxBOMk320yh5NOhihn5knqrlYQYpGGyOngKKwJb0J0BAQ==', u'CloudFront-Is-Desktop-Viewer': u'true'},
-            u'stageVariables': None,
-            u'path': u'/',
-            u'isBase64Encoded': True
+            'queryStringParameters': None,
+            'httpMethod': 'POST',
+            'pathParameters': None,
+            'headers': {'Via': '1.1 38205a04d96d60185e88658d3185ccee.cloudfront.net (CloudFront)', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'CloudFront-Is-SmartTV-Viewer': 'false', 'CloudFront-Forwarded-Proto': 'https', 'X-Forwarded-For': '71.231.27.57, 104.246.180.51', 'CloudFront-Viewer-Country': 'US', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0', 'Host': 'xo2z7zafjh.execute-api.us-east-1.amazonaws.com', 'X-Forwarded-Proto': 'https', 'Cookie': 'zappa=AQ4', 'CloudFront-Is-Tablet-Viewer': 'false', 'X-Forwarded-Port': '443', 'Referer': 'https://xo8z7zafjh.execute-api.us-east-1.amazonaws.com/former/post', 'CloudFront-Is-Mobile-Viewer': 'false', 'X-Amz-Cf-Id': '31zxcUcVyUxBOMk320yh5NOhihn5knqrlYQYpGGyOngKKwJb0J0BAQ==', 'CloudFront-Is-Desktop-Viewer': 'true'},
+            'stageVariables': None,
+            'path': '/',
+            'isBase64Encoded': True
             }
 
         environ = create_wsgi_request(event, trailing_slash=False)
@@ -1807,7 +1807,7 @@ def test_flask_logging_bug(self):
             environ = create_wsgi_request(event)
             app = flask.Flask(__name__)
             with app.request_context(environ):
-                app.logger.error(u"This is a test")
+                app.logger.error("This is a test")
                 log_output = sys.stderr.getvalue()
                 if sys.version_info[0] < 3:
                     self.assertNotIn(
diff --git a/tests/tests_middleware.py b/tests/tests_middleware.py
--- a/tests/tests_middleware.py
+++ b/tests/tests_middleware.py
@@ -84,160 +84,160 @@ def simple_app(environ, start_response):
     def test_wsgi_authorizer_handling(self):
         # With user
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': None,
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': None,
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u'authorizer': {
-                    u'principalId': u'user1'
+            'requestContext': {
+                'authorizer': {
+                    'principalId': 'user1'
                 }
             },
-            u'query': {}
+            'query': {}
         }
 
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False)
-        self.assertEqual(environ['REMOTE_USER'], u'user1')
+        self.assertEqual(environ['REMOTE_USER'], 'user1')
 
         # With empty authorizer, should not include REMOTE_USER
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': None,
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': None,
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u'authorizer': {
-                    u'principalId': u''
+            'requestContext': {
+                'authorizer': {
+                    'principalId': ''
                 }
             },
-            u'query': {}
+            'query': {}
         }
 
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False)
-        user = environ.get('REMOTE_USER', u'no_user')
-        self.assertEqual(user, u'no_user')
+        user = environ.get('REMOTE_USER', 'no_user')
+        self.assertEqual(user, 'no_user')
 
         # With missing authorizer, should not include REMOTE_USER
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': None,
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': None,
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {},
-            u'query': {}
+            'requestContext': {},
+            'query': {}
         }
 
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False)
-        user = environ.get('REMOTE_USER', u'no_user')
-        self.assertEqual(user, u'no_user')
+        user = environ.get('REMOTE_USER', 'no_user')
+        self.assertEqual(user, 'no_user')
 
         # With empty authorizer, should not include REMOTE_USER
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': None,
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': None,
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u'authorizer': {}
+            'requestContext': {
+                'authorizer': {}
             },
-            u'query': {}
+            'query': {}
         }
 
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False)
-        user = environ.get('REMOTE_USER', u'no_user')
-        self.assertEqual(user, u'no_user')
+        user = environ.get('REMOTE_USER', 'no_user')
+        self.assertEqual(user, 'no_user')
 
     def test_wsgi_map_context_headers_handling(self):
 
         # Validate a single context value mapping is translated into a HTTP header
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': None,
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': None,
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u'authorizer': {
-                    u'principalId': u'user1'
+            'requestContext': {
+                'authorizer': {
+                    'principalId': 'user1'
                 },
 
             },
-            u'query': {}
+            'query': {}
         }
 
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False,
                                       context_header_mappings={'PrincipalId': 'authorizer.principalId'})
-        self.assertEqual(environ['HTTP_PRINCIPALID'], u'user1')
+        self.assertEqual(environ['HTTP_PRINCIPALID'], 'user1')
 
         # Validate multiple mappings with an invalid mapping
         # Invalid mapping should be ignored
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': None,
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': None,
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u"resourceId": u"123456",
-                u"apiId": u"1234567890",
-                u"resourcePath": u"/{proxy+}",
-                u"httpMethod": u"POST",
-                u"requestId": u"c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
-                u"accountId": u"123456789012",
-                u"identity": {
-                    u"userAgent": u"Custom User Agent String",
-                    u"cognitoIdentityPoolId": u"userpoolID",
-                    u"cognitoIdentityId": u"myCognitoID",
-                    u"sourceIp": u"127.0.0.1",
+            'requestContext': {
+                "resourceId": "123456",
+                "apiId": "1234567890",
+                "resourcePath": "/{proxy+}",
+                "httpMethod": "POST",
+                "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
+                "accountId": "123456789012",
+                "identity": {
+                    "userAgent": "Custom User Agent String",
+                    "cognitoIdentityPoolId": "userpoolID",
+                    "cognitoIdentityId": "myCognitoID",
+                    "sourceIp": "127.0.0.1",
                 },
                 "stage": "prod"
             },
-            u'query': {}
+            'query': {}
         }
 
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
@@ -246,79 +246,79 @@ def test_wsgi_map_context_headers_handling(self):
                                                                'APIStage': 'stage',
                                                                'InvalidValue': 'identity.cognitoAuthenticationType',
                                                                'OtherInvalid': 'nothinghere'})
-        self.assertEqual(environ['HTTP_COGNITOIDENTITYID'], u'myCognitoID')
-        self.assertEqual(environ['HTTP_APISTAGE'], u'prod')
+        self.assertEqual(environ['HTTP_COGNITOIDENTITYID'], 'myCognitoID')
+        self.assertEqual(environ['HTTP_APISTAGE'], 'prod')
         self.assertNotIn('HTTP_INVALIDVALUE', environ)
         self.assertNotIn('HTTP_OTHERINVALID', environ)
 
     def test_should_allow_empty_query_params(self):
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': {},
-            u'multiValueQueryStringParameters': {},
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'httpMethod': 'GET',
+            'queryStringParameters': {},
+            'multiValueQueryStringParameters': {},
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u"resourceId": u"123456",
-                u"apiId": u"1234567890",
-                u"resourcePath": u"/{proxy+}",
-                u"httpMethod": u"POST",
-                u"requestId": u"c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
-                u"accountId": u"123456789012",
-                u"identity": {
-                    u"userAgent": u"Custom User Agent String",
-                    u"cognitoIdentityPoolId": u"userpoolID",
-                    u"cognitoIdentityId": u"myCognitoID",
-                    u"sourceIp": u"127.0.0.1",
+            'requestContext': {
+                "resourceId": "123456",
+                "apiId": "1234567890",
+                "resourcePath": "/{proxy+}",
+                "httpMethod": "POST",
+                "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
+                "accountId": "123456789012",
+                "identity": {
+                    "userAgent": "Custom User Agent String",
+                    "cognitoIdentityPoolId": "userpoolID",
+                    "cognitoIdentityId": "myCognitoID",
+                    "sourceIp": "127.0.0.1",
                 },
                 "stage": "prod"
             },
-            u'query': {}
+            'query': {}
         }
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False)
-        self.assertEqual(environ['QUERY_STRING'], u'')
+        self.assertEqual(environ['QUERY_STRING'], '')
 
     def test_should_handle_multi_value_query_string_params(self):
         event = {
-            u'httpMethod': u'GET',
-            u'queryStringParameters': {},
-            u'multiValueQueryStringParameters': {
+            'httpMethod': 'GET',
+            'queryStringParameters': {},
+            'multiValueQueryStringParameters': {
                 'foo': [1, 2]
             },
-            u'path': u'/v1/runs',
-            u'params': {},
-            u'body': {},
-            u'headers': {
-                u'Content-Type': u'application/json'
+            'path': '/v1/runs',
+            'params': {},
+            'body': {},
+            'headers': {
+                'Content-Type': 'application/json'
             },
-            u'pathParameters': {
-                u'proxy': 'v1/runs'
+            'pathParameters': {
+                'proxy': 'v1/runs'
             },
-            u'requestContext': {
-                u"resourceId": u"123456",
-                u"apiId": u"1234567890",
-                u"resourcePath": u"/{proxy+}",
-                u"httpMethod": u"POST",
-                u"requestId": u"c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
-                u"accountId": u"123456789012",
-                u"identity": {
-                    u"userAgent": u"Custom User Agent String",
-                    u"cognitoIdentityPoolId": u"userpoolID",
-                    u"cognitoIdentityId": u"myCognitoID",
-                    u"sourceIp": u"127.0.0.1",
+            'requestContext': {
+                "resourceId": "123456",
+                "apiId": "1234567890",
+                "resourcePath": "/{proxy+}",
+                "httpMethod": "POST",
+                "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
+                "accountId": "123456789012",
+                "identity": {
+                    "userAgent": "Custom User Agent String",
+                    "cognitoIdentityPoolId": "userpoolID",
+                    "cognitoIdentityId": "myCognitoID",
+                    "sourceIp": "127.0.0.1",
                 },
                 "stage": "prod"
             },
-            u'query': {}
+            'query': {}
         }
         environ = create_wsgi_request(event, script_name='http://zappa.com/',
                                       trailing_slash=False)
-        self.assertEqual(environ['QUERY_STRING'], u'foo=1&foo=2')
+        self.assertEqual(environ['QUERY_STRING'], 'foo=1&foo=2')
diff --git a/tests/tests_placebo.py b/tests/tests_placebo.py
--- a/tests/tests_placebo.py
+++ b/tests/tests_placebo.py
@@ -199,102 +199,102 @@ def test_handler(self, session):
 
         # Test scheduled event
         event = {
-                    u'account': u'72333333333',
-                    u'region': u'us-east-1',
-                    u'detail': {},
-                    u'detail-type': u'Scheduled Event',
-                    u'source': u'aws.events',
-                    u'version': u'0',
-                    u'time': u'2016-05-10T21:05:39Z',
-                    u'id': u'0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
-                    u'resources': [u'arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
+                    'account': '72333333333',
+                    'region': 'us-east-1',
+                    'detail': {},
+                    'detail-type': 'Scheduled Event',
+                    'source': 'aws.events',
+                    'version': '0',
+                    'time': '2016-05-10T21:05:39Z',
+                    'id': '0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
+                    'resources': ['arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
                 }
         lh.handler(event, None)
 
         # Test command event
         event = {
-                    u'account': u'72333333333',
-                    u'region': u'us-east-1',
-                    u'detail': {},
-                    u'command': u'test_settings.command',
-                    u'source': u'aws.events',
-                    u'version': u'0',
-                    u'time': u'2016-05-10T21:05:39Z',
-                    u'id': u'0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
-                    u'resources': [u'arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
+                    'account': '72333333333',
+                    'region': 'us-east-1',
+                    'detail': {},
+                    'command': 'test_settings.command',
+                    'source': 'aws.events',
+                    'version': '0',
+                    'time': '2016-05-10T21:05:39Z',
+                    'id': '0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
+                    'resources': ['arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
                 }
         lh.handler(event, None)
 
         # Test command for async event
         event = {
-                    u'account': u'72333333333',
-                    u'region': u'us-east-1',
-                    u'detail': {},
-                    u'command': u'zappa.asynchronous.route_lambda_task',
-                    u'task_path': u'tests.test_app.async_me',
-                    u'args': [u'xxx'],
-                    u'kwargs': {},
-                    u'source': u'aws.events',
-                    u'version': u'0',
-                    u'time': u'2016-05-10T21:05:39Z',
-                    u'id': u'0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
+                    'account': '72333333333',
+                    'region': 'us-east-1',
+                    'detail': {},
+                    'command': 'zappa.asynchronous.route_lambda_task',
+                    'task_path': 'tests.test_app.async_me',
+                    'args': ['xxx'],
+                    'kwargs': {},
+                    'source': 'aws.events',
+                    'version': '0',
+                    'time': '2016-05-10T21:05:39Z',
+                    'id': '0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
                 }
         self.assertEqual('run async when on lambda xxx', lh.handler(event, None))
-        event[u'kwargs'] = {'foo': 'bar'}
+        event['kwargs'] = {'foo': 'bar'}
         self.assertEqual('run async when on lambda xxxbar', lh.handler(event, None))
 
         # Test raw_command event
         event = {
-                    u'account': u'72333333333',
-                    u'region': u'us-east-1',
-                    u'detail': {},
-                    u'raw_command': u'print("check one two")',
-                    u'source': u'aws.events',
-                    u'version': u'0',
-                    u'time': u'2016-05-10T21:05:39Z',
-                    u'id': u'0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
-                    u'resources': [u'arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
+                    'account': '72333333333',
+                    'region': 'us-east-1',
+                    'detail': {},
+                    'raw_command': 'print("check one two")',
+                    'source': 'aws.events',
+                    'version': '0',
+                    'time': '2016-05-10T21:05:39Z',
+                    'id': '0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
+                    'resources': ['arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
                 }
         lh.handler(event, None)
 
         # Test AWS S3 event
         event = {
-                    u'account': u'72333333333',
-                    u'region': u'us-east-1',
-                    u'detail': {},
-                    u'Records': [{'s3': {'configurationId': 'test_project:test_settings.aws_s3_event'}}],
-                    u'source': u'aws.events',
-                    u'version': u'0',
-                    u'time': u'2016-05-10T21:05:39Z',
-                    u'id': u'0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
-                    u'resources': [u'arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
+                    'account': '72333333333',
+                    'region': 'us-east-1',
+                    'detail': {},
+                    'Records': [{'s3': {'configurationId': 'test_project:test_settings.aws_s3_event'}}],
+                    'source': 'aws.events',
+                    'version': '0',
+                    'time': '2016-05-10T21:05:39Z',
+                    'id': '0d6a6db0-d5e7-4755-93a0-750a8bf49d55',
+                    'resources': ['arn:aws:events:us-east-1:72333333333:rule/tests.test_app.schedule_me']
                 }
         self.assertEqual("AWS S3 EVENT", lh.handler(event, None))
 
         # Test AWS SNS event
         event = {
-            u'account': u'72333333333',
-            u'region': u'us-east-1',
-            u'detail': {},
-            u'Records': [
+            'account': '72333333333',
+            'region': 'us-east-1',
+            'detail': {},
+            'Records': [
                 {
-                    u'EventVersion': u'1.0',
-                    u'EventSource': u'aws:sns',
-                    u'EventSubscriptionArn': u'arn:aws:sns:EXAMPLE',
-                    u'Sns': {
-                        u'SignatureVersion': u'1',
-                        u'Timestamp': u'1970-01-01T00:00:00.000Z',
-                        u'Signature': u'EXAMPLE',
-                        u'SigningCertUrl': u'EXAMPLE',
-                        u'MessageId': u'95df01b4-ee98-5cb9-9903-4c221d41eb5e',
-                        u'Message': u'Hello from SNS!',
-                        u'Subject': u'TestInvoke',
-                        u'Type': u'Notification',
-                        u'UnsubscribeUrl': u'EXAMPLE',
-                        u'TopicArn': u'arn:aws:sns:1',
-                        u'MessageAttributes': {
-                            u'Test': {u'Type': u'String', u'Value': u'TestString'},
-                            u'TestBinary': {u'Type': u'Binary', u'Value': u'TestBinary'}
+                    'EventVersion': '1.0',
+                    'EventSource': 'aws:sns',
+                    'EventSubscriptionArn': 'arn:aws:sns:EXAMPLE',
+                    'Sns': {
+                        'SignatureVersion': '1',
+                        'Timestamp': '1970-01-01T00:00:00.000Z',
+                        'Signature': 'EXAMPLE',
+                        'SigningCertUrl': 'EXAMPLE',
+                        'MessageId': '95df01b4-ee98-5cb9-9903-4c221d41eb5e',
+                        'Message': 'Hello from SNS!',
+                        'Subject': 'TestInvoke',
+                        'Type': 'Notification',
+                        'UnsubscribeUrl': 'EXAMPLE',
+                        'TopicArn': 'arn:aws:sns:1',
+                        'MessageAttributes': {
+                            'Test': {'Type': 'String', 'Value': 'TestString'},
+                            'TestBinary': {'Type': 'Binary', 'Value': 'TestBinary'}
                         }
                     }
                 }
@@ -304,28 +304,28 @@ def test_handler(self, session):
 
         # Test AWS SNS event
         event = {
-            u'account': u'72333333333',
-            u'region': u'us-east-1',
-            u'detail': {},
-            u'Records': [
+            'account': '72333333333',
+            'region': 'us-east-1',
+            'detail': {},
+            'Records': [
                 {
-                    u'EventVersion': u'1.0',
-                    u'EventSource': u'aws:sns',
-                    u'EventSubscriptionArn': u'arn:aws:sns:EXAMPLE',
-                    u'Sns': {
-                        u'SignatureVersion': u'1',
-                        u'Timestamp': u'1970-01-01T00:00:00.000Z',
-                        u'Signature': u'EXAMPLE',
-                        u'SigningCertUrl': u'EXAMPLE',
-                        u'MessageId': u'95df01b4-ee98-5cb9-9903-4c221d41eb5e',
-                        u'Message': u'{"args": ["arg1", "arg2"], "command": "zappa.asynchronous.route_sns_task", '
-                                    u'"task_path": "test_settings.aws_async_sns_event", "kwargs": {"arg3": "varg3"}}',
-                        u'Subject': u'TestInvoke',
-                        u'Type': u'Notification',
-                        u'UnsubscribeUrl': u'EXAMPLE',
-                        u'MessageAttributes': {
-                            u'Test': {u'Type': u'String', u'Value': u'TestString'},
-                            u'TestBinary': {u'Type': u'Binary', u'Value': u'TestBinary'}
+                    'EventVersion': '1.0',
+                    'EventSource': 'aws:sns',
+                    'EventSubscriptionArn': 'arn:aws:sns:EXAMPLE',
+                    'Sns': {
+                        'SignatureVersion': '1',
+                        'Timestamp': '1970-01-01T00:00:00.000Z',
+                        'Signature': 'EXAMPLE',
+                        'SigningCertUrl': 'EXAMPLE',
+                        'MessageId': '95df01b4-ee98-5cb9-9903-4c221d41eb5e',
+                        'Message': '{"args": ["arg1", "arg2"], "command": "zappa.asynchronous.route_sns_task", '
+                                    '"task_path": "test_settings.aws_async_sns_event", "kwargs": {"arg3": "varg3"}}',
+                        'Subject': 'TestInvoke',
+                        'Type': 'Notification',
+                        'UnsubscribeUrl': 'EXAMPLE',
+                        'MessageAttributes': {
+                            'Test': {'Type': 'String', 'Value': 'TestString'},
+                            'TestBinary': {'Type': 'Binary', 'Value': 'TestBinary'}
                         }
                     }
                 }
@@ -335,20 +335,20 @@ def test_handler(self, session):
 
         # Test AWS DynamoDB event
         event = {
-            u'Records': [
+            'Records': [
                 {
-                    u'eventID': u'1',
-                    u'eventVersion': u'1.0',
-                    u'dynamodb': {
-                        u'Keys': {u'Id': {u'N': u'101'}},
-                        u'NewImage': {u'Message': {u'S': u'New item!'}, u'Id': {u'N': u'101'}},
-                        u'StreamViewType': u'NEW_AND_OLD_IMAGES',
-                        u'SequenceNumber': u'111', u'SizeBytes': 26
+                    'eventID': '1',
+                    'eventVersion': '1.0',
+                    'dynamodb': {
+                        'Keys': {'Id': {'N': '101'}},
+                        'NewImage': {'Message': {'S': 'New item!'}, 'Id': {'N': '101'}},
+                        'StreamViewType': 'NEW_AND_OLD_IMAGES',
+                        'SequenceNumber': '111', 'SizeBytes': 26
                     },
-                    u'awsRegion': u'us-west-2',
-                    u'eventName': u'INSERT',
-                    u'eventSourceARN': u'arn:aws:dynamodb:1',
-                    u'eventSource': u'aws:dynamodb'
+                    'awsRegion': 'us-west-2',
+                    'eventName': 'INSERT',
+                    'eventSourceARN': 'arn:aws:dynamodb:1',
+                    'eventSource': 'aws:dynamodb'
                 }
             ]
         }
@@ -356,21 +356,21 @@ def test_handler(self, session):
 
         # Test AWS kinesis event
         event = {
-            u'Records': [
+            'Records': [
                 {
-                    u'eventID': u'shardId-000000000000:49545115243490985018280067714973144582180062593244200961',
-                    u'eventVersion': u'1.0',
-                    u'kinesis': {
-                        u'partitionKey': u'partitionKey-3',
-                        u'data': u'SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=',
-                        u'kinesisSchemaVersion': u'1.0',
-                        u'sequenceNumber': u'49545115243490985018280067714973144582180062593244200961'
+                    'eventID': 'shardId-000000000000:49545115243490985018280067714973144582180062593244200961',
+                    'eventVersion': '1.0',
+                    'kinesis': {
+                        'partitionKey': 'partitionKey-3',
+                        'data': 'SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=',
+                        'kinesisSchemaVersion': '1.0',
+                        'sequenceNumber': '49545115243490985018280067714973144582180062593244200961'
                     },
-                    u'invokeIdentityArn': u'arn:aws:iam::EXAMPLE',
-                    u'eventName': u'aws:kinesis:record',
-                    u'eventSourceARN': u'arn:aws:kinesis:1',
-                    u'eventSource': u'aws:kinesis',
-                    u'awsRegion': u'us-east-1'
+                    'invokeIdentityArn': 'arn:aws:iam::EXAMPLE',
+                    'eventName': 'aws:kinesis:record',
+                    'eventSourceARN': 'arn:aws:kinesis:1',
+                    'eventSource': 'aws:kinesis',
+                    'awsRegion': 'us-east-1'
                  }
             ]
         }
@@ -378,29 +378,29 @@ def test_handler(self, session):
 
         # Test AWS SQS event
         event = {
-            u"Records": [
+            "Records": [
                 {
-                    u"messageId": u"c80e8021-a70a-42c7-a470-796e1186f753",
-                    u"receiptHandle": u"AQEBJQ+/u6NsnT5t8Q/VbVxgdUl4TMKZ5FqhksRdIQvLBhwNvADoBxYSOVeCBXdnS9P+erlTtwEALHsnBXynkfPLH3BOUqmgzP25U8kl8eHzq6RAlzrSOfTO8ox9dcp6GLmW33YjO3zkq5VRYyQlJgLCiAZUpY2D4UQcE5D1Vm8RoKfbE+xtVaOctYeINjaQJ1u3mWx9T7tork3uAlOe1uyFjCWU5aPX/1OHhWCGi2EPPZj6vchNqDOJC/Y2k1gkivqCjz1CZl6FlZ7UVPOx3AMoszPuOYZ+Nuqpx2uCE2MHTtMHD8PVjlsWirt56oUr6JPp9aRGo6bitPIOmi4dX0FmuMKD6u/JnuZCp+AXtJVTmSHS8IXt/twsKU7A+fiMK01NtD5msNgVPoe9JbFtlGwvTQ==",
-                    u"body": u"{\"foo\":\"bar\"}",
-                    u"attributes": {
-                        u"ApproximateReceiveCount": u"3",
-                        u"SentTimestamp": u"1529104986221",
-                        u"SenderId": u"594035263019",
-                        u"ApproximateFirstReceiveTimestamp": u"1529104986230"
+                    "messageId": "c80e8021-a70a-42c7-a470-796e1186f753",
+                    "receiptHandle": "AQEBJQ+/u6NsnT5t8Q/VbVxgdUl4TMKZ5FqhksRdIQvLBhwNvADoBxYSOVeCBXdnS9P+erlTtwEALHsnBXynkfPLH3BOUqmgzP25U8kl8eHzq6RAlzrSOfTO8ox9dcp6GLmW33YjO3zkq5VRYyQlJgLCiAZUpY2D4UQcE5D1Vm8RoKfbE+xtVaOctYeINjaQJ1u3mWx9T7tork3uAlOe1uyFjCWU5aPX/1OHhWCGi2EPPZj6vchNqDOJC/Y2k1gkivqCjz1CZl6FlZ7UVPOx3AMoszPuOYZ+Nuqpx2uCE2MHTtMHD8PVjlsWirt56oUr6JPp9aRGo6bitPIOmi4dX0FmuMKD6u/JnuZCp+AXtJVTmSHS8IXt/twsKU7A+fiMK01NtD5msNgVPoe9JbFtlGwvTQ==",
+                    "body": "{\"foo\":\"bar\"}",
+                    "attributes": {
+                        "ApproximateReceiveCount": "3",
+                        "SentTimestamp": "1529104986221",
+                        "SenderId": "594035263019",
+                        "ApproximateFirstReceiveTimestamp": "1529104986230"
                         },
-                    u"messageAttributes": {},
-                    u"md5OfBody": u"9bb58f26192e4ba00f01e2e7b136bbd8",
-                    u"eventSource": u"aws:sqs",
-                    u"eventSourceARN": u"arn:aws:sqs:1",
-                    u"awsRegion": u"us-east-1"
+                    "messageAttributes": {},
+                    "md5OfBody": "9bb58f26192e4ba00f01e2e7b136bbd8",
+                    "eventSource": "aws:sqs",
+                    "eventSourceARN": "arn:aws:sqs:1",
+                    "awsRegion": "us-east-1"
                     }
                 ]
             }
         self.assertEqual("AWS SQS EVENT", lh.handler(event, None))
 
         # Test Authorizer event
-        event = {u'authorizationToken': u'hubtoken1', u'methodArn': u'arn:aws:execute-api:us-west-2:1234:xxxxx/dev/GET/v1/endpoint/param', u'type': u'TOKEN'}
+        event = {'authorizationToken': 'hubtoken1', 'methodArn': 'arn:aws:execute-api:us-west-2:1234:xxxxx/dev/GET/v1/endpoint/param', 'type': 'TOKEN'}
         self.assertEqual("AUTHORIZER_EVENT", lh.handler(event, None))
 
         # Ensure Zappa does return 401 if no function was defined.
@@ -410,17 +410,17 @@ def test_handler(self, session):
 
         # Unhandled event
         event = {
-            u'Records': [
+            'Records': [
                 {
-                    u'eventID': u'shardId-000000000000:49545115243490985018280067714973144582180062593244200961',
-                    u'eventVersion': u'1.0',
-                    u'kinesis': {
-                        u'partitionKey': u'partitionKey-3',
-                        u'data': u'SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=',
-                        u'kinesisSchemaVersion': u'1.0',
-                        u'sequenceNumber': u'49545115243490985018280067714973144582180062593244200961'
+                    'eventID': 'shardId-000000000000:49545115243490985018280067714973144582180062593244200961',
+                    'eventVersion': '1.0',
+                    'kinesis': {
+                        'partitionKey': 'partitionKey-3',
+                        'data': 'SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=',
+                        'kinesisSchemaVersion': '1.0',
+                        'sequenceNumber': '49545115243490985018280067714973144582180062593244200961'
                     },
-                    u'eventSourceARN': u'bad:arn:1',
+                    'eventSourceARN': 'bad:arn:1',
                 }
             ]
         }