示例#1
0
def handler(event, context):
    """ Lambda event handler, invokes the WSGI wrapper and handles command invocation
    """
    if "_serverless-wsgi" in event:
        import shlex
        import subprocess
        from werkzeug._compat import StringIO, to_native

        native_stdout = sys.stdout
        native_stderr = sys.stderr
        output_buffer = StringIO()

        try:
            sys.stdout = output_buffer
            sys.stderr = output_buffer

            meta = event["_serverless-wsgi"]
            if meta.get("command") == "exec":
                # Evaluate Python code
                exec(meta.get("data", ""))
            elif meta.get("command") == "command":
                # Run shell commands
                result = subprocess.check_output(meta.get("data", ""),
                                                 shell=True,
                                                 stderr=subprocess.STDOUT)
                output_buffer.write(to_native(result))
            elif meta.get("command") == "manage":
                # Run Django management commands
                from django.core import management

                management.call_command(*shlex.split(meta.get("data", "")))
            elif meta.get("command") == "flask":
                # Run Flask CLI commands
                from flask.cli import ScriptInfo

                wsgi_app.cli.main(
                    shlex.split(meta.get("data", "")),
                    standalone_mode=False,
                    obj=ScriptInfo(create_app=_create_app),
                )
            else:
                raise Exception("Unknown command: {}".format(
                    meta.get("command")))
        except:  # noqa
            return traceback.format_exc()
        finally:
            sys.stdout = native_stdout
            sys.stderr = native_stderr

        return output_buffer.getvalue()
    else:
        return serverless_wsgi.handle_request(wsgi_app, event, context)
示例#2
0
def handler(event, context):
    if "Records" in event:
        process_sqs_messages(event)
        return
    """Lambda event handler, invokes the WSGI wrapper and handles command invocation"""
    if "_serverless-wsgi" in event:
        import shlex
        import subprocess

        from werkzeug._compat import StringIO, to_native

        native_stdout = sys.stdout
        native_stderr = sys.stderr
        output_buffer = StringIO()

        try:
            sys.stdout = output_buffer
            sys.stderr = output_buffer

            meta = event["_serverless-wsgi"]
            if meta.get("command") == "exec":
                # Evaluate Python code
                exec(meta.get("data", ""))
            elif meta.get("command2") == "command":
                # Run shell commands
                result = subprocess.check_output(meta.get("data", ""),
                                                 shell=True,
                                                 stderr=subprocess.STDOUT)
                output_buffer.write(to_native(result))
            elif meta.get("command") == "manage":
                # Run Django management commands
                from django.core import management

                management.call_command(*shlex.split(meta.get("data", "")))
            else:
                raise Exception("Unknown command: {}".format(
                    meta.get("command")))
        except subprocess.CalledProcessError as e:
            return [e.returncode, e.output.decode("utf-8")]
        except:  # noqa
            return [1, traceback.format_exc()]
        finally:
            sys.stdout = native_stdout
            sys.stderr = native_stderr

        return [0, output_buffer.getvalue()]
    else:
        return serverless_wsgi.handle_request(wsgi_app, event, context)
示例#3
0
    def __call__(self, environ, start_response):
        response_body = []
        _status = {}

        def catching_start_response(status, headers, exc_info=None):
            _status.update(code=status[0], msg=status[1])
            start_response(status, headers, exc_info)
            return response_body.append

        def runapp():
            appiter = self._app(environ, catching_start_response)
            response_body.extend(appiter)
            if hasattr(appiter, 'close'):
                appiter.close()

        p = Profile()
        self.logger.start()
        start = time.time()
        p.runcall(runapp)
        body = b''.join(response_body)

        elapsed = time.time() - start

        # Grab any information if we need it
        if isinstance(self.logger, QueuedMongoCommandLogger):
            mongo_events = list(self.logger.collector)  # copy (we empty after)

        # Stop (quiet) pymongo logger
        self.logger.stop(
        )  # Note: Also clears QueuedMongoCommandLogger.collector

        # Dump profile to variable
        s = StringIO()
        ps = Stats(p, stream=s).sort_stats('cumulative')
        ps.print_stats()
        profile_text = s.getvalue()
        profile_text = "\n".join(profile_text.split("\n")[0:256])

        if isinstance(self.logger, QueuedMongoCommandLogger):
            queries = profiling_utils.combine_events_to_queries(mongo_events)
            path = environ.get('PATH_INFO')

            referrer = werkzeug.urls.url_parse(environ.get('HTTP_REFERER', ''))

            if len(queries) > 0 and not any(
                    n in path for n in self._ignored_url_patterns
            ):  # Only record records with queries

                r = ProfilingRequest(
                    method=environ['REQUEST_METHOD'],
                    path=path,
                    referrer=referrer.path,
                    environ={
                        k.replace('.', WERKZEUG_ENVIRON_KEY_REPLACEMENT): v
                        for k, v in list(environ.items())[:18] if any(
                            isinstance(v, _type)
                            for _type in [list, tuple, str, dict, int])
                    },
                    status=_status,
                    pyprofile=profile_text,
                    query_count=len(queries),
                    query_duration=sum(q['duration'] for q in queries
                                       if 'duration' in q),
                    duration=elapsed * 1000,  # to milliseconds
                    time=datetime.utcnow(),
                )
                r.save()
                for q in queries:
                    ProfilingQuery(request=r, **q).save()

        return [body]