An AWS Lambda function which parses specific API Gateway input into a
    WSGI request, feeds it to Flask, procceses the Flask response, and returns
    that back to the API Gateway.
769765
def lambda_handler(event, context, settings_name="zappa_settings"):
    
    # Loading settings from a python module
    settings = importlib.import_module(settings_name)

    # The flask-app module
    app_module = importlib.import_module(settings.APP_MODULE)

    # The flask-app
    app = getattr(app_module, settings.APP_OBJECT)
    app.config.from_object('zappa_settings')

    app.wsgi_app = ZappaWSGIMiddleware(app.wsgi_app)

    # This is a normal HTTP request
    if event.get('method', None):
        # If we just want to inspect this,
        # return this event instead of processing the request
        # https://your_api.aws-api.com/?event_echo=true
        event_echo = getattr(settings, "EVENT_ECHO", True)
        if event_echo:
            if 'event_echo' in list(event['params'].values()):
                return {'Content': str(event) + '\n' + str(context), 'Status': 200}

        # TODO: Enable Let's Encrypt
        # # If Let's Encrypt is defined in the settings,
        # # and the path is your.domain.com/.well-known/acme-challenge/{{lets_encrypt_challenge_content}},
        # # return a 200 of lets_encrypt_challenge_content.
        # lets_encrypt_challenge_path = getattr(settings, "LETS_ENCRYPT_CHALLENGE_PATH", None)
        # lets_encrypt_challenge_content = getattr(settings, "LETS_ENCRYPT_CHALLENGE_CONTENT", None)
        # if lets_encrypt_challenge_path:
        #     if len(event['params']) == 3:
        #         if event['params']['parameter_1'] == '.well-known' and \
        #             event['params']['parameter_2'] == 'acme-challenge' and \
        #             event['params']['parameter_3'] == lets_encrypt_challenge_path:
        #                 return {'Content': lets_encrypt_challenge_content, 'Status': 200}

        # Create the environment for WSGI and handle the request
        environ = create_wsgi_request(event, script_name=settings.SCRIPT_NAME,
                                      trailing_slash=False)

        # We are always on https on Lambda, so tell our wsgi app that.
        environ['wsgi.url_scheme'] = 'https'

        response = Response.from_app(app, environ)

        # This doesn't work. It should probably be set right after creation, not
        # at such a late stage.
        # response.autocorrect_location_header = False

        zappa_returndict = dict()

        if response.data:
            zappa_returndict['Content'] = response.data

        # Pack the WSGI response into our special dictionary.
        for (header_name, header_value) in response.headers:
            zappa_returndict[header_name] = header_value
        zappa_returndict['Status'] = response.status_code

        # TODO: No clue how to handle the flask-equivalent of this. Or is this
        # something entirely specified by the middleware?
        # # Parse the WSGI Cookie and pack it.
        # cookie = response.cookies.output()
        # if ': ' in cookie:
        #     zappa_returndict['Set-Cookie'] = response.cookies.output().split(': ')[1]

        # To ensure correct status codes, we need to
        # pack the response as a deterministic B64 string and raise it
        # as an error to match our APIGW regex.
        # The DOCTYPE ensures that the page still renders in the browser.
        if response.status_code in [400, 401, 403, 404, 500]:
            content = "<!DOCTYPE html>" + str(response.status_code) + response.data
            b64_content = base64.b64encode(content)
            raise Exception(b64_content)
        # Internal are changed to become relative redirects
        # so they still work for apps on raw APIGW and on a domain.
        elif response.status_code in [301, 302]:
            # Location is by default relative on Flask. Location is by default
            # absolute on Werkzeug. We can set autocorrect_location_header on
            # the response to False, but it doesn't work. We have to manually
            # remove the host part.
            location = response.location
            hostname = 'https://' + environ['HTTP_HOST']
            if location.startswith(hostname):
                location = location[len(hostname):]
            raise Exception(location)
        else:
            return zappa_returndict
653974
def _construct_target(self, function):
        
        target = {
                'Arn': function.get_runtime_attr("arn"),
                'Id': self.logical_id + 'LambdaTarget'
        }
        if self.Input is not None:
            target['Input'] = self.Input

        if self.InputPath is not None:
            target['InputPath'] = self.InputPath
        return target
1118618
def request_middleware(api=None):
    """"""
    def decorator(middleware_method):
        apply_to_api = hug.API(api) if api else hug.api.from_object(middleware_method)

        class MiddlewareRouter(object):
            __slots__ = ()

            def process_request(self, request, response):
                return middleware_method(request, response)

        apply_to_api.http.add_middleware(MiddlewareRouter())
        return middleware_method
    return decorator
964770
def _run_lambda_function(event, context, app, config):  # pragma: no cover
    """"""
    args = event.get('args', [])
    kwargs = event.get('kwargs', {})

    # first attempt to invoke the function passing the lambda event and context
    try:
        ret = app(*args, event=event, context=context, **kwargs)
    except TypeError:
        # try again without passing the event and context
        ret = app(*args, **kwargs)
    return ret
337497
def wsgi_app(self, environ, start_response):
        """"""
        @_LOCAL_MANAGER.middleware
        def _wrapped_app(environ, start_response):
            request = Request(environ)
            setattr(_local, _CURRENT_REQUEST_KEY, request)
            response = self._dispatch_request(request)
            return response(environ, start_response)
        return _wrapped_app(environ, start_response)
24775
def definition
      {
        method_logical_id => {
          type: "AWS::ApiGateway::Method",
          properties: {
            resource_id: "!Ref #{resource_id}",
            rest_api_id: "!Ref #{RestApi.logical_id}",
            http_method: @route.method,
            request_parameters: {},
            authorization_type: authorization_type,
            integration: {
              integration_http_method: "POST",
              type: "AWS_PROXY",
              uri: "!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${{namespace}LambdaFunction.Arn}/invocations"
            },
            method_responses: []
          }
        }
      }
    end
77262
def api(func=None, timeout=API_TIMEOUT):  # incoming
    
    if func is None:
        return partial(api, timeout=timeout)
    else:
        wrapper = _get_api_decorator(func=func, timeout=timeout)
        return wrapper
535578
def lambda_not_found_response(*args):
        
        response_data = jsonify(ServiceErrorResponses._NO_LAMBDA_INTEGRATION)
        return make_response(response_data, ServiceErrorResponses.HTTP_STATUS_CODE_502)
1354978
def _lambda_uri(self, lambda_name, lambda_region):
        '''
        
        '''
        profile = self._common_aws_args.get('profile')
        region = self._common_aws_args.get('region')

        lambda_region = __utils__['boto3.get_region']('lambda', lambda_region, profile)
        apigw_region = __utils__['boto3.get_region']('apigateway', region, profile)

        lambda_desc = __salt__['boto_lambda.describe_function'](lambda_name, **self._common_aws_args)

        if lambda_region != apigw_region:
            if not lambda_desc.get('function'):
                # try look up in the same region as the apigateway as well if previous lookup failed
                lambda_desc = __salt__['boto_lambda.describe_function'](lambda_name, **self._common_aws_args)

        if not lambda_desc.get('function'):
            raise ValueError('Could not find lambda function {0} in '
                             'regions [{1}, {2}].'.format(lambda_name, lambda_region, apigw_region))

        lambda_arn = lambda_desc.get('function').get('FunctionArn')
        lambda_uri = ('arn:aws:apigateway:{0}:lambda:path/2015-03-31'
                      '/functions/{1}/invocations'.format(apigw_region, lambda_arn))
        return lambda_uri
497326
def ping(awsclient, function_name, alias_name=ALIAS_NAME, version=None):
    
    log.debug('sending ping to lambda function: %s', function_name)
    payload = '{"ramuda_action": "ping"}'  # default to ping event
    # reuse invoke
    return invoke(awsclient, function_name, payload, invocation_type=None,
                  alias_name=alias_name, version=version)
989172
def create_api_gateway_routes(  self,
                                    lambda_arn,
                                    api_name=None,
                                    api_key_required=False,
                                    authorization_type='NONE',
                                    authorizer=None,
                                    cors_options=None,
                                    description=None,
                                    endpoint_configuration=None
                                ):
        

        restapi = troposphere.apigateway.RestApi('Api')
        restapi.Name = api_name or lambda_arn.split(':')[-1]
        if not description:
            description = 'Created automatically by Zappa.'
        restapi.Description = description
        endpoint_configuration = [] if endpoint_configuration is None else endpoint_configuration
        if self.boto_session.region_name == "us-gov-west-1":
            endpoint_configuration.append("REGIONAL")
        if endpoint_configuration:
            endpoint = troposphere.apigateway.EndpointConfiguration()
            endpoint.Types = list(set(endpoint_configuration))
            restapi.EndpointConfiguration = endpoint
        if self.apigateway_policy:
            restapi.Policy = json.loads(self.apigateway_policy)
        self.cf_template.add_resource(restapi)

        root_id = troposphere.GetAtt(restapi, 'RootResourceId')
        invocation_prefix = "aws" if self.boto_session.region_name != "us-gov-west-1" else "aws-us-gov"
        invocations_uri = 'arn:' + invocation_prefix + ':apigateway:' + self.boto_session.region_name + ':lambda:path/2015-03-31/functions/' + lambda_arn + '/invocations'

        ##
        # The Resources
        ##
        authorizer_resource = None
        if authorizer:
            authorizer_lambda_arn = authorizer.get('arn', lambda_arn)
            lambda_uri = 'arn:{invocation_prefix}:apigateway:{region_name}:lambda:path/2015-03-31/functions/{lambda_arn}/invocations'.format(
                invocation_prefix=invocation_prefix,
                region_name=self.boto_session.region_name,
                lambda_arn=authorizer_lambda_arn
            )
            authorizer_resource = self.create_authorizer(
                restapi, lambda_uri, authorizer
            )

        self.create_and_setup_methods(  restapi,
                                        root_id,
                                        api_key_required,
                                        invocations_uri,
                                        authorization_type,
                                        authorizer_resource,
                                        0
                                        )

        if cors_options:
            self.create_and_setup_cors( restapi,
                                        root_id,
                                        invocations_uri,
                                        0,
                                        cors_options
                                    )

        resource = troposphere.apigateway.Resource('ResourceAnyPathSlashed')
        self.cf_api_resources.append(resource.title)
        resource.RestApiId = troposphere.Ref(restapi)
        resource.ParentId = root_id
        resource.PathPart = "{proxy+}"
        self.cf_template.add_resource(resource)

        self.create_and_setup_methods(  restapi,
                                        resource,
                                        api_key_required,
                                        invocations_uri,
                                        authorization_type,
                                        authorizer_resource,
                                        1
                                    )  # pragma: no cover

        if cors_options:
            self.create_and_setup_cors( restapi,
                                        resource,
                                        invocations_uri,
                                        1,
                                        cors_options
                                    )  # pragma: no cover
        return restapi
403006
def wsgi_app(self, environ, start_response):
        

        path = environ['PATH_INFO']

        if re.match(self.path_pattern, path):
            ws = environ['wsgi.websocket']
            address = (environ.get('REMOTE_ADDR'), environ.get('REMOTE_PORT'))
            self._handle_stream(ws, address)
        else:
            if self.merge_wsgi_app:
                return self.merge_wsgi_app(environ, start_response)
            else:
                start_response("400 Bad Request", [])
                return ['400 Bad Request']
828883
def handle(self, *args, **options):
        

        # Load the settings
        self.require_settings(args, options)

        # Load your AWS credentials from ~/.aws/credentials
        self.load_credentials()

        # Invoke it!
        command = {"command": ' '.join(options['environment'][1:])}

        response = self.zappa.invoke_lambda_function(
            self.lambda_name, json.dumps(command), invocation_type='RequestResponse')

        if 'LogResult' in response:
            print(base64.b64decode(response['LogResult']))
        else:
            print(response)
            import pdb
            pdb.set_trace()

        return
1050035
def generate_lambda_functions():
    """"""
    logger.debug("[#] Setting up the Lambda functions")
    aws_lambda = boto3.client('lambda', region_name=PRIMARY_REGION)
    functions = aws_lambda.list_functions().get('Functions')
    existing_funcs = [x['FunctionName'] for x in functions]

    iam = boto3.resource('iam')
    account_id = iam.CurrentUser().arn.split(':')[4]

    responses = list()
    for label in LAMBDA_FUNCTIONS:
        if label in existing_funcs:
            logger.debug("[*] Lambda function %s already exists" % (label))
            continue
        dir_path = os.path.dirname(os.path.realpath(__file__))
        dir_path = dir_path.replace('/cli', '/aws')

        kwargs = {
            'Runtime': 'python2.7',
            'Role': 'arn:aws:iam::{0}:role/{1}'.format(account_id, BLOCKADE_ROLE),
            'Timeout': 3,
            'MemorySize': 128,
            'Publish': True,
            'Code': {
                'ZipFile': open("{0}/lambda-zips/{1}.zip".format(dir_path, label), 'rb').read()
            }
        }
        kwargs.update(LAMBDA_SCHEMA[label])
        logger.debug("[#] Setting up the %s Lambda function" % (label))
        response = aws_lambda.create_function(**kwargs)
        responses.append(response)
        logger.debug("[#] Successfully setup Lambda function %s" % (label))
    logger.info("[#] Successfully setup Lambda functions")

    return responses
1260335
def handle(self, *args, **options):  # NoQA
        

        # Load the settings
        self.require_settings(args, options)

        # Load your AWS credentials from ~/.aws/credentials
        self.load_credentials()

        #Get the Django settings file
        self.get_django_settings_file()

        # Create the Lambda Zip,
        # or used the supplied zip file.
        if not options['zip']:
            self.create_package()
        else:
            self.zip_path = options['zip']

        # Upload it to S3
        self.zappa.upload_to_s3(self.zip_path, self.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 = self.zappa.update_lambda_function(
            self.s3_bucket_name, self.zip_path, self.lambda_name)

        # Remove the uploaded zip from S3, because it is now registered..
        self.zappa.remove_from_s3(self.zip_path, self.s3_bucket_name)

        # Finally, delete the local copy our zip package
        if self.zappa_settings[self.api_stage].get('delete_zip', True) and not options['zip']:
            os.remove(self.zip_path)

        #Remove the local settings
        self.remove_s3_local_settings()

        print("Your updated Zappa deployment is live!")

        events = self.zappa_settings[self.api_stage].get('events')

        iam = self.zappa.boto_session.resource('iam')
        self.zappa.credentials_arn = iam.Role(self.zappa.role_name).arn

        if options['unschedule'] and events:
            self.zappa.unschedule_events(lambda_arn, self.lambda_name, events)
        elif options['unschedule'] and not events:
            print("No Events to Unschedule")

        if options['schedule'] and events:
            self.zappa.schedule_events(lambda_arn, self.lambda_name, events)
        elif options['schedule'] and not events:
            print("No Events to Schedule")
1167162
def lambdafan(func):
    
    if 'AWS_LAMBDA_FUNCTION_NAME' not in os.environ:
        return func

    @functools.wraps(func)
    def scaleout(*args, **kw):
        client = boto3.client('lambda')
        client.invoke(
            FunctionName=os.environ['AWS_LAMBDA_FUNCTION_NAME'],
            InvocationType='Event',
            Payload=dumps({
                'event': 'fanout',
                'function': func.__name__,
                'args': args,
                'kwargs': kw}),
            Qualifier=os.environ['AWS_LAMBDA_FUNCTION_VERSION'])
    return scaleout
748697
def get_lambda_function(self, function_name):
        
        response = self.lambda_client.get_function(
                FunctionName=function_name)
        return response['Configuration']['FunctionArn']