def defaults_for(self, command_type, data_type): """Provide default configuration for the given command and data type. This will use any wild card options first, overlaying more specific defaults as they are found. :param command_type: Type of modification (e.g. Types.UPSERT) :param data_type: Data type being modified :return: A dict of config """ defaults = self._command_defaults config = {} wild = defaults.get(self.WILD_CARD, {}) specific = defaults.get(CommandType(command_type), {}) data_type = DataType(data_type) for container in (wild, specific): if self.WILD_CARD in container: config.update(container[self.WILD_CARD]) if data_type in container: config.update(container[data_type]) return config
def add_concrete_id(self, data_type, id_ref, concrete_id): """Add a concrete id for a reference. :data_type: Data type of the object being referenced :id_ref: The reference string :concrete_id: The real id """ data_type = DataType(data_type) self._ref_to_concrete[data_type][id_ref] = concrete_id
def _command_defaults(self): config = defaultdict(dict) for command_type, data_type, defaults in self.raw["defaults"]: if command_type != self.WILD_CARD: command_type = CommandType(command_type) if data_type != self.WILD_CARD: data_type = DataType(data_type) config[command_type][data_type] = defaults return config
def _find_references(cls, body): """Search for references in the relationships of an object. :param body: Raw JSON API compatible data to search :return: A list of tuples with data type, reference, key and parent :rtype: Iterator[tuple] """ for relationship in body["data"].get("relationships", {}).values(): relationship = relationship["data"] if not isinstance(relationship["id"], dict): continue id_ref = relationship["id"].get(cls.REF_KEY) yield (DataType(relationship["type"]), id_ref, "id", relationship)
def body(self): """Get the appropriate body object for this command. :return: A different class depending on `DataType` and `data_classes` :raise UnsupportedOperationError: If no type can be found for the given `DataType` """ body = super().body data_type = DataType(body["data"]["type"]) try: # pylint: disable=unsubscriptable-object # It's subscriptable if child classes have set it to a dict class_ = self.data_classes[data_type] except KeyError: raise UnsupportedOperationError("Invalid action on data type") # Don't validate this all the time, we did it on the way in. If we have # mutated it it might not match the schema we except from clients, but # it's still valid return class_(body, validate=False)
def _get_concrete_id(self, data_type, id_ref): data_type = DataType(data_type) try: return self._ref_to_concrete[data_type][id_ref] except KeyError: raise UnpopulatedReferenceError(data_type, id_ref)