def _process_page_load_request(request_details):
            """
            :param request_details (delivery_api_client.Model.request_details.RequestDetails) request details
            :return: (delivery_api_client.Model.mbox_response.MboxResponse) decision consequences for page load
            """

            preserved = {
                "trace": None
            }

            def _preserve_trace(rule, mbox_response, request_type, request_detail, tracer):
                preserved["trace"] = mbox_response.trace
                return mbox_response

            if request_details:
                mbox_attributes = {attr: getattr(request_details, attr) for attr, val in
                                   request_details.attribute_map.items()}
                mbox_request = MboxRequest(**mbox_attributes)
            else:
                mbox_request = MboxRequest()

            mbox_request.name = self.global_mbox_name
            consequences = _process_mbox_request(mbox_request, [_preserve_trace, remove_page_load_attributes])
            options = flatten_list([consequence.options for consequence in consequences])
            mbox_response = MboxResponse(options=options, trace=preserved.get("trace"))

            def _metrics_accumulator(indexed, consequence):
                for metric in consequence.metrics or []:
                    indexed[metric.event_token] = metric
                return indexed

            indexed_metrics = reduce(_metrics_accumulator, consequences, {})

            if indexed_metrics:
                mbox_response.metrics = sorted(indexed_metrics.values(), key=order_by_event_token)

            return mbox_response
示例#2
0
def get_response_tokens(response):
    """Get all response tokens from all parts of response payload"""
    execute = response.execute or ExecuteResponse()
    prefetch = response.prefetch or PrefetchResponse()

    if not execute and not prefetch:
        return None

    execute_page_load_trace = get_response_tokens_from_object(execute.page_load)
    execute_mbox_trace = get_response_tokens_from_list(execute.mboxes)
    prefetch_page_load_trace = get_response_tokens_from_object(prefetch.page_load)
    prefetch_views_trace = get_response_tokens_from_list(prefetch.views)
    prefetch_mbox_trace = get_response_tokens_from_list(prefetch.mboxes)

    analytics = [
        execute_page_load_trace,
        execute_mbox_trace,
        prefetch_page_load_trace,
        prefetch_views_trace,
        prefetch_mbox_trace
    ]

    result = flatten_list([item for item in analytics if item])
    return result or None
示例#3
0
def get_analytics_details(response):
    """Get all analytics payloads from all parts of the response"""
    execute = response.execute or ExecuteResponse()
    prefetch = response.prefetch or PrefetchResponse()

    if not execute and not prefetch:
        return None

    execute_page_load_analytics = get_analytics_from_object(execute.page_load)
    execute_mbox_analytics = get_analytics_from_list(execute.mboxes)
    prefetch_page_load_analytics = get_analytics_from_object(prefetch.page_load)
    prefetch_views_analytics = get_analytics_from_list(prefetch.views)
    prefetch_mbox_analytics = get_analytics_from_list(prefetch.mboxes)

    analytics = [
        execute_page_load_analytics,
        execute_mbox_analytics,
        prefetch_page_load_analytics,
        prefetch_views_analytics,
        prefetch_mbox_analytics
    ]

    result = flatten_list([item for item in analytics if item])
    return result or None
    def _get_decisions(self, mode, post_processors):
        """
        :param mode: ("execute"|"prefetch") request mode
        :param post_processors: (list<callable>) post-processors used to process an mbox if needed, optional
        :return: (dict) decision response
        """
        if not getattr(self.request, mode):
            return None

        request_tracer = RequestTracer(self.trace_provider, self.artifact)

        def _view_request_accumulator(_result, key):
            _result.extend(self.rules.get("views", {}).get(key, []))
            return _result

        def _handle_view_consequence(consequences, consequence):
            if not consequences.get(consequence.name):
                consequences[consequence.name] = consequence
            else:
                existing_consequence = consequences.get(consequence.name)

                if not existing_consequence.options:
                    existing_consequence.options = []
                existing_consequence.options.extend(consequence.options or [])

                if not existing_consequence.metrics:
                    existing_consequence.metrics = []
                existing_consequence.metrics.extend(consequence.metrics or [])

        def _process_view_request(request_details, additional_post_processors=None):
            """
            :param request_details (delivery_api_client.Model.request_details.RequestDetails) request details
            :param additional_post_processors: (list<callable>) additional post-processors
            :return: (list<delivery_api_client.Model.mbox_response.MboxResponse>) decision consequences for views
            """
            if not additional_post_processors:
                additional_post_processors = []

            request_tracer.trace_request(mode, RequestType.VIEW.value, request_details, self.context)

            consequences = {}

            if request_details and request_details.name:
                view_rules = self.rules.get("views", {}).get(request_details.name, [])
            else:
                view_rules = reduce(_view_request_accumulator, self.rules.get("views", {}).keys(), [])

            view_rules = filter(by_property_token(self.property_token), view_rules)

            matched_rule_keys = set()
            _post_processors = list(post_processors)
            _post_processors.extend(additional_post_processors)

            for rule in view_rules:
                rule_key = get_rule_key(rule)
                consequence = None

                if rule_key not in matched_rule_keys:
                    consequence = self.process_rule(rule, self.context, RequestType.VIEW.value, request_details,
                                                    _post_processors, request_tracer)

                if consequence:
                    matched_rule_keys.add(rule_key)
                    _handle_view_consequence(consequences, consequence)

            return sorted(consequences.values(), key=order_by_name)

        def _process_mbox_request(mbox_request, additional_post_processors=None):
            """
            :param mbox_request (delivery_api_client.Model.mbox_request.MboxRequest) mbox request
            :param additional_post_processors: (list<callable>) additional post-processors
            :return: (list<delivery_api_client.Model.mbox_response.MboxResponse>) decision consequences for mboxes
            """
            if not additional_post_processors:
                additional_post_processors = []
            is_global_mbox = mbox_request.name == self.global_mbox_name

            request_tracer.trace_request(mode, RequestType.MBOX.value, mbox_request, self.context)

            consequences = []
            mbox_rules = filter(by_property_token(self.property_token),
                                self.rules.get("mboxes", {}).get(mbox_request.name, []))

            matched_rule_keys = set()
            _post_processors = list(post_processors)
            _post_processors.extend(additional_post_processors)

            for rule in mbox_rules:
                rule_key = get_rule_key(rule)
                consequence = None

                if not is_global_mbox or (is_global_mbox and rule_key not in matched_rule_keys):
                    consequence = self.process_rule(rule, self.context, RequestType.MBOX.value, mbox_request,
                                                    _post_processors, request_tracer)

                if consequence:
                    consequences.append(consequence)
                    matched_rule_keys.add(rule_key)
                    if not is_global_mbox:
                        break

            # add a blank if no consequences
            if not is_global_mbox and len(consequences) == 0:
                fallback_consequence = MboxResponse(name=mbox_request.name,
                                                    index=mbox_request.index,
                                                    trace=request_tracer.get_trace_result())
                consequences.append(fallback_consequence)

            return consequences

        def _process_page_load_request(request_details):
            """
            :param request_details (delivery_api_client.Model.request_details.RequestDetails) request details
            :return: (delivery_api_client.Model.mbox_response.MboxResponse) decision consequences for page load
            """

            preserved = {
                "trace": None
            }

            def _preserve_trace(rule, mbox_response, request_type, request_detail, tracer):
                preserved["trace"] = mbox_response.trace
                return mbox_response

            if request_details:
                mbox_attributes = {attr: getattr(request_details, attr) for attr, val in
                                   request_details.attribute_map.items()}
                mbox_request = MboxRequest(**mbox_attributes)
            else:
                mbox_request = MboxRequest()

            mbox_request.name = self.global_mbox_name
            consequences = _process_mbox_request(mbox_request, [_preserve_trace, remove_page_load_attributes])
            options = flatten_list([consequence.options for consequence in consequences])
            mbox_response = MboxResponse(options=options, trace=preserved.get("trace"))

            def _metrics_accumulator(indexed, consequence):
                for metric in consequence.metrics or []:
                    indexed[metric.event_token] = metric
                return indexed

            indexed_metrics = reduce(_metrics_accumulator, consequences, {})

            if indexed_metrics:
                mbox_response.metrics = sorted(indexed_metrics.values(), key=order_by_event_token)

            return mbox_response

        response = PrefetchResponse() if mode == "prefetch" else ExecuteResponse()

        if getattr(self.request, mode).mboxes:
            mboxes = getattr(self.request, mode).mboxes
            response.mboxes = flatten_list([_process_mbox_request(mbox_request) for mbox_request
                                            in mboxes if mbox_request])

        if getattr(getattr(self.request, mode), "views", None):
            views = getattr(getattr(self.request, mode), "views")
            response.views = flatten_list([_process_view_request(request_details) for request_details in views])

        page_load = getattr(self.request, mode).page_load
        response.page_load = _process_page_load_request(page_load)

        return response
示例#5
0
def get_response_tokens_from_list(_list):
    """Get response tokens from list within response payload"""
    if not _list:
        return None
    return flatten_list([get_response_tokens_from_object(item) for item in _list if item])
示例#6
0
def get_trace_from_list(_list):
    """Get trace from within list in response payload"""
    if not _list:
        return None
    return flatten_list([get_trace_from_object(item) for item in _list if item and item.trace])
示例#7
0
def get_analytics_from_list(_list):
    """Get analytics response payload from list within response"""
    if not _list:
        return None
    return flatten_list([get_analytics_from_object(item) for item in _list if item and item.analytics])