\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /proc/self/root/opt/alt/python27/lib/python2.7/site-packages/raven/contrib/awslambda/

Viewing File: __init__.py

"""
raven.contrib.awslambda
~~~~~~~~~~~~~~~~~~~~

Raven wrapper for AWS Lambda handlers.

:copyright: (c) 2010-2012 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
# flake8: noqa

from __future__ import absolute_import

import os
import logging
import functools
from types import FunctionType

from raven.base import Client
from raven.transport.http import HTTPTransport

logger = logging.getLogger('sentry.errors.client')


def get_default_tags():
    return {
        'lambda': 'AWS_LAMBDA_FUNCTION_NAME',
        'version': 'AWS_LAMBDA_FUNCTION_VERSION',
        'memory_size': 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE',
        'log_group': 'AWS_LAMBDA_LOG_GROUP_NAME',
        'log_stream': 'AWS_LAMBDA_LOG_STREAM_NAME',
        'region': 'AWS_REGION'
    }


class LambdaClient(Client):
    """
    Raven decorator for AWS Lambda.

    By default, the lambda integration will capture unhandled exceptions and instrument logging.

    Usage:

    >>> from raven.contrib.awslambda import LambdaClient
    >>>
    >>>
    >>> client = LambdaClient()
    >>>
    >>> @client.capture_exceptions
    >>> def handler(event, context):
    >>>    ...
    >>>    raise Exception('I will be sent to sentry!')

    """

    def __init__(self, *args, **kwargs):
        transport = kwargs.get('transport', HTTPTransport)
        super(LambdaClient, self).__init__(*args, transport=transport, **kwargs)

    def capture(self, *args, **kwargs):
        if 'data' not in kwargs:
            kwargs['data'] = data = {}
        else:
            data = kwargs['data']
        event = kwargs.get('event', None)
        context = kwargs.get('context', None)
        user_info = self._get_user_interface(event)
        if user_info:
            data.update(user_info)
        if event:
            http_info = self._get_http_interface(event)
            if http_info:
                data.update(http_info)
            data['extra'] = self._get_extra_data(event, context)
        return super(LambdaClient, self).capture(*args, **kwargs)

    def build_msg(self, *args, **kwargs):

        data = super(LambdaClient, self).build_msg(*args, **kwargs)
        for option, default in get_default_tags().items():
            data['tags'].setdefault(option, os.environ.get(default))
        data.setdefault('release', os.environ.get('SENTRY_RELEASE'))
        data.setdefault('environment', os.environ.get('SENTRY_ENVIRONMENT'))
        return data

    def capture_exceptions(self, f=None, exceptions=None):  # TODO: Ash fix kwargs in base
        """
        Wrap a function or code block in try/except and automatically call
        ``.captureException`` if it raises an exception, then the exception
        is reraised.

        By default, it will capture ``Exception``

        >>> @client.capture_exceptions
        >>> def foo():
        >>>     raise Exception()

        >>> with client.capture_exceptions():
        >>>    raise Exception()

        You can also specify exceptions to be caught specifically

        >>> @client.capture_exceptions((IOError, LookupError))
        >>> def bar():
        >>>     ...

        ``kwargs`` are passed through to ``.captureException``.
        """
        if not isinstance(f, FunctionType):
            # when the decorator has args which is not a function we except
            # f to be the exceptions tuple
            return functools.partial(self.capture_exceptions, exceptions=f)

        exceptions = exceptions or (Exception,)

        @functools.wraps(f)
        def wrapped(event, context, *args, **kwargs):
            try:
                return f(event, context, *args, **kwargs)
            except exceptions:
                self.captureException(event=event, context=context, **kwargs)
                self.context.clear()
                raise
        return wrapped

    @staticmethod
    def _get_user_interface(event):
        if event.get('requestContext'):
            identity = event['requestContext']['identity']
            if identity:
                user = {
                    'id': identity.get('cognitoIdentityId', None) or identity.get('user', None),
                    'username': identity.get('user', None),
                    'ip_address': identity.get('sourceIp', None),
                    'cognito_identity_pool_id': identity.get('cognitoIdentityPoolId', None),
                    'cognito_authentication_type': identity.get('cognitoAuthenticationType', None),
                    'user_agent': identity.get('userAgent')
                }
                return {'user': user}

    @staticmethod
    def _get_http_interface(event):
        if event.get('path') and event.get('httpMethod'):
            request = {
                "url": event.get('path'),
                "method": event.get('httpMethod'),
                "query_string": event.get('queryStringParameters', None),
                "headers": event.get('headers', None) or [],
            }
            return {'request': request}

    @staticmethod
    def _get_extra_data(event, context):
        extra_context = {
            'event': event,
            'aws_request_id': context.aws_request_id,
            'context': vars(context),
        }

        if context.client_context:
            extra_context['client_context'] = {
                'client.installation_id': context.client_context.client.installation_id,
                'client.app_title': context.client_context.client.app_title,
                'client.app_version_name': context.client_context.client.app_version_name,
                'client.app_version_code': context.client_context.client.app_version_code,
                'client.app_package_name': context.client_context.client.app_package_name,
                'custom': context.client_context.custom,
                'env': context.client_context.env,
            }
        return extra_context