Example #1
0
    def execute_request(self, request, *args, **kwargs):
        """
        This is the entry point for all incoming requests
        (To be more precise, the URL mapper calls the
        L{resource.Resource.__call__} that does
        some pre-processing, which then calls L{execute_request} )

        It guides the request through all the necessary steps up to the point
        that its result is serialized into a dictionary.

        @type request: HTTPRequest object
        @param request: Incoming request

        @rype: dict
        @return: Dictionary of the result. The dictionary contains the
        following keys:
        
        * data: Contains the result of running the requested operation. The
        value to this key can be a dictionary, list, or string. Within this
        data structure, any dictionaries or lists are made of strings, with the
        exception of dates, which appear as I{datetime} functions, and will be
        serialized by the JSONEmitter.

        * total: Is only included if slicing was performed, and indicates the
        total result size.

        * Any other key can be included, if L{BaseHandler.enrich_response} has
        been overridden
        """
        # Validate request body data
        if hasattr(request, 'data') and request.data is not None:
            if request.method.upper() == 'PUT':
                # In the case of PUT requests, we first force the evaluation of
                # the affected dataset (theferore if there are any
                # HttpResourceGone exceptions, they will be raised now), and then in the
                # ``validate`` method, we perform any data validations. We
                # assign it to parameter ``request.dataset``.
                request.dataset = self.data(request, *args, **kwargs)              
            self.validate(request, *args, **kwargs)
        
        # Pick action to run
        action = getattr(self,  CALLMAP.get(request.method.upper()))
        # Run it
        data = action(request, *args, **kwargs)
        # Select output fields
        fields = self.get_output_fields(request) 
        # Slice
        sliced_data, total = self.response_slice_data(request, data)
        # inject fake dynamic fields to the response data
        sliced_data = self.inject_fake_dynamic_fields(request, sliced_data, fields)            
        
        # Use the emitter to serialize any python objects / data structures
        # within I{sliced_data}, to serializable forms(dict, list, string), 
        # so that the specific emitter we use for returning
        # the response, can easily serialize them in some other format,
        # The L{Emitter} is responsible for making sure that only fields contained in
        # I{fields} will be included in the result.
        emitter = Emitter(self, sliced_data, fields)      
        ser_data = emitter.construct()

        # Structure the response data
        ret = {'data': ser_data}
        if total is not None:
            ret['total'] = total
        # Add extra metadata
        self.enrich_response(ret, data)

        if request.method.upper() == 'DELETE':
            self.data_safe_for_delete(data)

        return ret