def test_get_manylinux(self): z = Zappa() self.assertNotEqual(z.get_manylinux_wheel('pandas'), None) self.assertEqual(z.get_manylinux_wheel('derpderpderpderp'), None) # mock the pip.get_installed_distributions() to include a package in manylinux so that the code # for zipping pre-compiled packages gets called mock_named_tuple = collections.namedtuple('mock_named_tuple', ['project_name']) mock_return_val = [mock_named_tuple('pandas')] with mock.patch('pip.get_installed_distributions', return_value=mock_return_val): z = Zappa() path = z.create_lambda_zip(handler_file=os.path.realpath(__file__)) self.assertTrue(os.path.isfile(path)) os.remove(path)
def test_invoke_lambda_function(self, session): z = Zappa(session) z.credentials_arn = 'arn:aws:iam::724336686645:role/ZappaLambdaExecution' function_name = 'django-helloworld-unicode' payload = '{"event": "hello"}' response = z.invoke_lambda_function(function_name, payload)
def test_copy_editable_packages(self, mock_remove, mock_find_packages): temp_package_dir = '/var/folders/rn/9tj3_p0n1ln4q4jn1lgqy4br0000gn/T/1480455339' egg_links = [ '/user/test/.virtualenvs/test/lib/python2.7/site-packages/package-python.egg-link' ] egg_path = "/some/other/directory/package" mock_find_packages.return_value = ["package", "package.subpackage", "package.another"] temp_egg_link = os.path.join(temp_package_dir, 'package-python.egg-link') z = Zappa() with nested( patch_open(), mock.patch('glob.glob'), mock.patch('zappa.zappa.copytree') ) as ((mock_open, mock_file), mock_glob, mock_copytree): # We read in the contents of the egg-link file mock_file.read.return_value = "{}\n.".format(egg_path) # we use glob.glob to get the egg-links in the temp packages directory mock_glob.return_value = [temp_egg_link] z.copy_editable_packages(egg_links, temp_package_dir) # make sure we copied the right directories mock_copytree.assert_called_with( os.path.join(egg_path, 'package'), os.path.join(temp_package_dir, 'package'), symlinks=False ) self.assertEqual(mock_copytree.call_count, 1) # make sure it removes the egg-link from the temp packages directory mock_remove.assert_called_with(temp_egg_link) self.assertEqual(mock_remove.call_count, 1)
def test_load_credentials(self): z = Zappa() z.aws_region = 'us-east-1' z.load_credentials() self.assertEqual(z.boto_session.region_name, 'us-east-1') self.assertEqual(z.aws_region, 'us-east-1') z.aws_region = 'eu-west-1' z.profile_name = 'default' z.load_credentials() self.assertEqual(z.boto_session.region_name, 'eu-west-1') self.assertEqual(z.aws_region, 'eu-west-1') creds = { 'AWS_ACCESS_KEY_ID': 'AK123', 'AWS_SECRET_ACCESS_KEY': 'JKL456', 'AWS_DEFAULT_REGION': 'us-west-1' } with mock.patch.dict('os.environ', creds): z.aws_region = None z.load_credentials() loaded_creds = z.boto_session._session.get_credentials() self.assertEqual(loaded_creds.access_key, 'AK123') self.assertEqual(loaded_creds.secret_key, 'JKL456') self.assertEqual(z.boto_session.region_name, 'us-west-1')
def test_event_name(self): zappa = Zappa() truncated = zappa.get_event_name("basldfkjalsdkfjalsdkfjaslkdfjalsdkfjadlsfkjasdlfkjasdlfkjasdflkjasdf-asdfasdfasdfasdfasdf", "this.is.my.dang.function.wassup.yeah.its.long") self.assertTrue(len(truncated) <= 64) truncated = zappa.get_event_name("basldfkjalsdkfjalsdkfjaslkdfjalsdkfjadlsfkjasdlfkjasdlfkjasdflkjasdf-asdfasdfasdfasdfasdf", "thisidoasdfaljksdfalskdjfalsdkfjasldkfjalsdkfjalsdkfjalsdfkjalasdfasdfasdfasdklfjasldkfjalsdkjfaslkdfjasldkfjasdflkjdasfskdj") self.assertTrue(len(truncated) <= 64) truncated = zappa.get_event_name("a", "b") self.assertTrue(len(truncated) <= 64)
def test_rollback_lambda_function_version(self, session): z = Zappa(session) z.credentials_arn = 'arn:aws:iam::724336686645:role/ZappaLambdaExecution' function_name = 'django-helloworld-unicode' too_many_versions = z.rollback_lambda_function_version(function_name, 99999) self.assertFalse(too_many_versions) function_arn = z.rollback_lambda_function_version(function_name, 1)
def test_create_api_gateway_routes(self, session): z = Zappa(session) z.parameter_depth = 1 z.integration_response_codes = [200] z.method_response_codes = [200] z.http_methods = ['GET'] z.credentials_arn = 'arn:aws:iam::12345:role/ZappaLambdaExecution' lambda_arn = 'arn:aws:lambda:us-east-1:12345:function:helloworld' z.create_api_gateway_routes(lambda_arn)
def test_create_lambda_package(self): # mock the pip.get_installed_distributions() to include a package in lambda_packages so that the code # for zipping pre-compiled packages gets called mock_named_tuple = collections.namedtuple('mock_named_tuple', ['project_name']) mock_return_val = [mock_named_tuple(lambda_packages.keys()[0])] # choose name of 1st package in lambda_packages with mock.patch('pip.get_installed_distributions', return_value=mock_return_val): z = Zappa() path = z.create_lambda_zip(handler_file=os.path.realpath(__file__)) self.assertTrue(os.path.isfile(path)) os.remove(path)
def test_create_api_gateway_routes(self, session): z = Zappa(session) z.parameter_depth = 1 z.integration_response_codes = [200] z.method_response_codes = [200] z.http_methods = ['GET'] z.credentials_arn = 'arn:aws:iam::12345:role/ZappaLambdaExecution' lambda_arn = 'arn:aws:lambda:us-east-1:12345:function:helloworld' with mock.patch('time.time', return_value=123.456): api_id = z.create_api_gateway_routes(lambda_arn) self.assertEqual(api_id, 'j27idab94h')
def test_deploy_api_gateway(self, session): z = Zappa(session) z.credentials_arn = 'arn:aws:iam::12345:role/ZappaLambdaExecution' z.parameter_depth = 1 z.integration_response_codes = [200] z.method_response_codes = [200] z.http_methods = ['GET'] lambda_arn = 'arn:aws:lambda:us-east-1:12345:function:django-helloworld-unicode' api_id = z.create_api_gateway_routes(lambda_arn) endpoint_url = z.deploy_api_gateway(api_id, "test_stage")
def handle(self, *args, **options): """ Execute the command. """ if not options.has_key('environment') or len( options['environment']) < 2: print( "You must call deploy with an environment name and command. \n python manage.py invoke <environment> <command>" ) return from django.conf import settings if not 'ZAPPA_SETTINGS' in dir(settings): print( "Please define your ZAPPA_SETTINGS in your settings file before deploying." ) return zappa_settings = settings.ZAPPA_SETTINGS # Set your configuration project_name = settings.BASE_DIR.split(os.sep)[-1] api_stage = options['environment'][0] if api_stage not in zappa_settings.keys(): print( "Please make sure that the environment '" + api_stage + "' is defined in your ZAPPA_SETTINGS in your settings file before deploying." ) return lambda_name = project_name + '-' + api_stage # Make your Zappa object zappa = Zappa() # Invoke it! command = {"command": ' '.join(options['environment'][1:])} response = zappa.invoke_lambda_function( lambda_name, json.dumps(command), invocation_type='RequestResponse') if response.has_key('LogResult'): print(base64.b64decode(response['LogResult'])) else: print(response) import pdb pdb.set_trace() return
def _init(environment, zappa_settings): """ """ # Make your Zappa object zappa = Zappa() # Load settings and apply them to the Zappa object settings = apply_zappa_settings(zappa, zappa_settings, environment) # Create the Lambda zip package (includes project and virtualenvironment) # Also define the path the handler file so it can be copied to the zip root # for Lambda. module_dir = os.path.dirname(os.path.abspath(flask_zappa.__file__)) handler_file = os.path.join(module_dir, 'handler.py') lambda_name = settings['project_name'] + '-' + environment return zappa, settings, handler_file, lambda_name
def test_create_lambda_function(self, session): bucket_name = 'lmbda' zip_path = 'Spheres-dev-1454694878.zip' z = Zappa(session) z.aws_region = 'us-east-1' z.load_credentials(session) z.credentials_arn = 'arn:aws:iam::12345:role/ZappaLambdaExecution' arn = z.create_lambda_function(bucket=bucket_name, s3_key=zip_path, function_name='test_lmbda_function55', handler='runme.lambda_handler') arn = z.update_lambda_function( bucket=bucket_name, s3_key=zip_path, function_name='test_lmbda_function55', )
def test_load_credentials(self): z = Zappa() credentials = '[default]\naws_access_key_id = AK123\naws_secret_access_key = JKL456' config = '[default]\noutput = json\nregion = us-east-1' credentials_file = open('credentials', 'w') credentials_file.write(credentials) credentials_file.close() config_file = open('config', 'w') config_file.write(config) config_file.close() z.load_credentials('credentials', 'config') os.remove('credentials') os.remove('config') self.assertTrue((z.access_key == "AK123")) self.assertTrue((z.secret_key == "JKL456")) self.assertTrue((z.aws_region == 'us-east-1'))
def test_upload_remove_s3(self, session): bucket_name = 'test_zappa_upload_s3' z = Zappa(session) zip_path = z.create_lambda_zip(minify=False) res = z.upload_to_s3(zip_path, bucket_name) os.remove(zip_path) self.assertTrue(res) s3 = session.resource('s3') # will throw ClientError with 404 if bucket doesn't exist s3.meta.client.head_bucket(Bucket=bucket_name) # will throw ClientError with 404 if object doesn't exist s3.meta.client.head_object( Bucket=bucket_name, Key=zip_path, ) res = z.remove_from_s3(zip_path, bucket_name) self.assertTrue(res) fail = z.upload_to_s3('/tmp/this_isnt_real', bucket_name) self.assertFalse(fail)
def test_human_units(self): zappa = Zappa() zappa.human_size(1) zappa.human_size(9999999999999)
def handle(self, *args, **options): """ Execute the command. """ if not options.has_key('environment'): print("You must call deploy with an environment name. \n python manage.py deploy <environment>") return from django.conf import settings if not 'ZAPPA_SETTINGS' in dir(settings): print("Please define your ZAPPA_SETTINGS in your settings file before deploying.") return zappa_settings = settings.ZAPPA_SETTINGS # Set your configuration project_name = settings.BASE_DIR.split(os.sep)[-1] api_stage = options['environment'][0] if api_stage not in zappa_settings.keys(): print("Please make sure that the environment '" + api_stage + "' is defined in your ZAPPA_SETTINGS in your settings file before deploying.") return # Make your Zappa object zappa = Zappa() # Load environment-specific settings s3_bucket_name = zappa_settings[api_stage]['s3_bucket'] settings_file = zappa_settings[api_stage]['settings_file'] if '~' in settings_file: settings_file = settings_file.replace('~', os.path.expanduser('~')) if not os.path.isfile(settings_file): print("Please make sure your settings_file is properly defined.") return custom_settings = [ 'http_methods', 'parameter_depth', 'integration_response_codes', 'method_response_codes', 'role_name', 'aws_region' ] for setting in custom_settings: if zappa_settings[api_stage].has_key(setting): setattr(zappa, setting, zappa_settings[api_stage][setting]) # Load your AWS credentials from ~/.aws/credentials zappa.load_credentials() # Create the Lambda zip package (includes project and virtualenvironment) # Also define the path the handler file so it can be copied to the zip root for Lambda. current_file = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) handler_file = os.sep.join(current_file.split(os.sep)[0:-2]) + os.sep + 'handler.py' lambda_name = project_name + '-' + api_stage zip_path = zappa.create_lambda_zip(lambda_name, handler_file=handler_file) #Add this environment's Django settings to that zipfile with open(settings_file, 'r') as f: contents = f.read() all_contents = contents + '\n# Automatically added by Zappa:\nSCRIPT_NAME=\'/' + api_stage + '\'\n' f.close() with open('zappa_settings.py', 'w') as f: f.write(all_contents) with zipfile.ZipFile(zip_path, 'a') as lambda_zip: lambda_zip.write('zappa_settings.py', 'zappa_settings.py') lambda_zip.close() os.unlink('zappa_settings.py') # Upload it to S3 zip_arn = zappa.upload_to_s3(zip_path, s3_bucket_name) # Register the Lambda function with that zip as the source # You'll also need to define the path to your lambda_handler code. lambda_arn = zappa.update_lambda_function(s3_bucket_name, zip_path, lambda_name) # Get the URL! endpoint_url = zappa.get_api_url(lambda_name) # Finally, delete the local copy our zip package os.remove(zip_path) # Remove the uploaded zip from S3, because it is now registered.. zappa.remove_from_s3(zip_path, s3_bucket_name) print("Your updated Zappa deployment is live!") return
def test_zappa(self): self.assertTrue(True) Zappa()
def handle(self, *args, **options): """ Execute the command. """ if not options.has_key('environment'): print("You must call deploy with an environment name. \n python manage.py deploy <environment>") return from django.conf import settings if not 'ZAPPA_SETTINGS' in dir(settings): print("Please define your ZAPPA_SETTINGS in your settings file before deploying.") return zappa_settings = settings.ZAPPA_SETTINGS # Set your configuration project_name = settings.BASE_DIR.split(os.sep)[-1] api_stage = options['environment'][0] if api_stage not in zappa_settings.keys(): print("Please make sure that the environment '" + api_stage + "' is defined in your ZAPPA_SETTINGS in your settings file before deploying.") return # Make your Zappa object zappa = Zappa() # Load environment-specific settings s3_bucket_name = zappa_settings[api_stage]['s3_bucket'] settings_file = zappa_settings[api_stage]['settings_file'] if '~' in settings_file: settings_file = settings_file.replace('~', os.path.expanduser('~')) if not os.path.isfile(settings_file): print("Please make sure your settings_file is properly defined.") return custom_settings = [ 'http_methods', 'parameter_depth', 'integration_response_codes', 'method_response_codes', 'role_name', 'aws_region' ] for setting in custom_settings: if zappa_settings[api_stage].has_key(setting): setattr(zappa, setting, zappa_settings[api_stage][setting]) # Load your AWS credentials from ~/.aws/credentials zappa.load_credentials() # Make sure the necessary IAM execution roles are available zappa.create_iam_roles() # Create the Lambda zip package (includes project and virtualenvironment) # Also define the path the handler file so it can be copied to the zip root for Lambda. current_file = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) handler_file = os.sep.join(current_file.split(os.sep)[0:-2]) + os.sep + 'handler.py' lambda_name = project_name + '-' + api_stage zip_path = zappa.create_lambda_zip(lambda_name, handler_file=handler_file) # Add this environment's Django settings to that zipfile with open(settings_file, 'r') as f: contents = f.read() all_contents = contents if not zappa_settings[api_stage].has_key('domain'): script_name = api_stage else: script_name = '' if not "ZappaMiddleware" in all_contents: print("\n\nWARNING!\n") print("You do not have ZappaMiddleware in your remote settings's MIDDLEWARE_CLASSES.\n") print("This means that some aspects of your application may not work!\n\n") all_contents = all_contents + '\n# Automatically added by Zappa:\nSCRIPT_NAME=\'/' + script_name + '\'\n' f.close() with open('zappa_settings.py', 'w') as f: f.write(all_contents) with zipfile.ZipFile(zip_path, 'a') as lambda_zip: lambda_zip.write('zappa_settings.py', 'zappa_settings.py') lambda_zip.close() os.unlink('zappa_settings.py') # Upload it to S3 zip_arn = zappa.upload_to_s3(zip_path, s3_bucket_name) # Register the Lambda function with that zip as the source # You'll also need to define the path to your lambda_handler code. lambda_arn = zappa.create_lambda_function(s3_bucket_name, zip_path, lambda_name, 'handler.lambda_handler') # Create and configure the API Gateway delay = zappa_settings[api_stage].get('deploy_delay', 1) api_id = zappa.create_api_gateway_routes(lambda_arn, lambda_name, delay) # Deploy the API! endpoint_url = zappa.deploy_api_gateway(api_id, api_stage) # Finally, delete the local copy our zip package if zappa_settings[api_stage].get('delete_zip', True): os.remove(zip_path) # Remove the uploaded zip from S3, because it is now registered.. zappa.remove_from_s3(zip_path, s3_bucket_name) if zappa_settings[api_stage].get('touch', True): requests.get(endpoint_url) print("Your Zappa deployment is live!: " + endpoint_url) return
def test_schedule_events(self): z = Zappa() path = os.getcwd()
def test_logging(self): """ TODO """ Zappa()
def test_get_api_url(self, session): z = Zappa(session) z.credentials_arn = 'arn:aws:iam::724336686645:role/ZappaLambdaExecution' url = z.get_api_url('Spheres-demonstration', 'demonstration')
def test_fetch_logs(self, session): z = Zappa(session) z.credentials_arn = 'arn:aws:iam::12345:role/ZappaLambdaExecution' events = z.fetch_logs('Spheres-demonstration') self.assertTrue(events is not None)
def test_create_api_gateway_routes_with_different_auth_methods(self): z = Zappa() z.parameter_depth = 1 z.integration_response_codes = [200] z.method_response_codes = [200] z.http_methods = ['GET'] z.credentials_arn = 'arn:aws:iam::12345:role/ZappaLambdaExecution' lambda_arn = 'arn:aws:lambda:us-east-1:12345:function:helloworld' # No auth at all z.create_stack_template(lambda_arn, 'helloworld', False, {}, False, None) parsable_template = json.loads(z.cf_template.to_json()) self.assertEqual( "NONE", parsable_template["Resources"]["GET0"]["Properties"] ["AuthorizationType"]) self.assertEqual( "NONE", parsable_template["Resources"]["GET1"]["Properties"] ["AuthorizationType"]) self.assertEqual( False, parsable_template["Resources"]["GET0"]["Properties"] ["ApiKeyRequired"]) self.assertEqual( False, parsable_template["Resources"]["GET1"]["Properties"] ["ApiKeyRequired"]) # IAM auth z.create_stack_template(lambda_arn, 'helloworld', False, {}, True, None) parsable_template = json.loads(z.cf_template.to_json()) self.assertEqual( "AWS_IAM", parsable_template["Resources"]["GET0"]["Properties"] ["AuthorizationType"]) self.assertEqual( "AWS_IAM", parsable_template["Resources"]["GET1"]["Properties"] ["AuthorizationType"]) self.assertEqual( False, parsable_template["Resources"]["GET0"]["Properties"] ["ApiKeyRequired"]) self.assertEqual( False, parsable_template["Resources"]["GET1"]["Properties"] ["ApiKeyRequired"]) # API Key auth z.create_stack_template(lambda_arn, 'helloworld', True, {}, True, None) parsable_template = json.loads(z.cf_template.to_json()) self.assertEqual( "AWS_IAM", parsable_template["Resources"]["GET0"]["Properties"] ["AuthorizationType"]) self.assertEqual( "AWS_IAM", parsable_template["Resources"]["GET1"]["Properties"] ["AuthorizationType"]) self.assertEqual( True, parsable_template["Resources"]["GET0"]["Properties"] ["ApiKeyRequired"]) self.assertEqual( True, parsable_template["Resources"]["GET1"]["Properties"] ["ApiKeyRequired"]) # Authorizer and IAM authorizer = { "function": "runapi.authorization.gateway_authorizer.evaluate_token", "result_ttl": 300, "token_header": "Authorization", "validation_expression": "xxx" } z.create_stack_template(lambda_arn, 'helloworld', False, {}, True, authorizer) parsable_template = json.loads(z.cf_template.to_json()) self.assertEqual( "AWS_IAM", parsable_template["Resources"]["GET0"]["Properties"] ["AuthorizationType"]) self.assertEqual( "AWS_IAM", parsable_template["Resources"]["GET1"]["Properties"] ["AuthorizationType"]) with self.assertRaises(KeyError): parsable_template["Resources"]["Authorizer"] # Authorizer with validation expression invocations_uri = 'arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/' + lambda_arn + '/invocations' z.create_stack_template(lambda_arn, 'helloworld', False, {}, False, authorizer) parsable_template = json.loads(z.cf_template.to_json()) self.assertEqual( "CUSTOM", parsable_template["Resources"]["GET0"]["Properties"] ["AuthorizationType"]) self.assertEqual( "CUSTOM", parsable_template["Resources"]["GET1"]["Properties"] ["AuthorizationType"]) self.assertEqual( "TOKEN", parsable_template["Resources"]["Authorizer"]["Properties"]["Type"]) self.assertEqual( "ZappaAuthorizer", parsable_template["Resources"]["Authorizer"]["Properties"]["Name"]) self.assertEqual( 300, parsable_template["Resources"]["Authorizer"]["Properties"] ["AuthorizerResultTtlInSeconds"]) self.assertEqual( invocations_uri, parsable_template["Resources"]["Authorizer"] ["Properties"]["AuthorizerUri"]) self.assertEqual( z.credentials_arn, parsable_template["Resources"]["Authorizer"] ["Properties"]["AuthorizerCredentials"]) self.assertEqual( "xxx", parsable_template["Resources"]["Authorizer"]["Properties"] ["IdentityValidationExpression"]) # Authorizer without validation expression authorizer.pop('validation_expression', None) z.create_stack_template(lambda_arn, 'helloworld', False, {}, False, authorizer) parsable_template = json.loads(z.cf_template.to_json()) self.assertEqual( "CUSTOM", parsable_template["Resources"]["GET0"]["Properties"] ["AuthorizationType"]) self.assertEqual( "CUSTOM", parsable_template["Resources"]["GET1"]["Properties"] ["AuthorizationType"]) self.assertEqual( "TOKEN", parsable_template["Resources"]["Authorizer"]["Properties"]["Type"]) with self.assertRaises(KeyError): parsable_template["Resources"]["Authorizer"]["Properties"][ "IdentityValidationExpression"]
def test_create_lambda_package(self): self.assertTrue(True) z = Zappa() path = z.create_lambda_zip() self.assertTrue(os.path.isfile(path)) os.remove(path)
def test_create_iam_roles(self, session): z = Zappa(session) arn, updated = z.create_iam_roles() self.assertEqual(arn, "arn:aws:iam::123:role/{}".format(z.role_name))
def __init__(self, *args, **kwargs): super(ZappaCommand, self).__init__(*args, **kwargs) self.zappa = Zappa()
def test_create_lambda_package(self): self.assertTrue(True) z = Zappa() path = z.create_lambda_zip(handler_file=os.path.realpath(__file__)) self.assertTrue(os.path.isfile(path)) os.remove(path)