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