def save(self): """Either create or persist changes on this object back to the One Codex server.""" check_bind(self) creating = self.id is None if creating and not self.__class__._has_schema_method("create"): raise MethodNotSupported("{} do not support creating.".format( self.__class__.__name__)) if not creating and not self.__class__._has_schema_method("update"): raise MethodNotSupported("{} do not support updating.".format( self.__class__.__name__)) try: self._resource.save() except HTTPError as e: if e.response.status_code == 400: err_json = e.response.json().get("errors", []) msg = pretty_print_error(err_json) raise ServerError(msg) elif e.response.status_code == 404: action = "creating" if creating else "updating" raise MethodNotSupported("{} do not support {}.".format( self.__class__.__name__, action)) elif e.response.status_code == 409: raise ServerError("This {} object already exists".format( self.__class__.__name__)) else: raise e
def __setattr__(self, key, value): if key.startswith( "_"): # Allow directly setting _attributes, incl. _resource # these are any fields that have to be settable normally super(OneCodexBase, self).__setattr__(key, value) return elif key == "id": raise AttributeError("can't set attribute") elif isinstance(value, OneCodexBase) or isinstance( value, ResourceList): self._resource[key] = value._resource return elif isinstance(value, (list, tuple)): # convert any fancy items into their underlying resources new_value = [] for v in value: new_value.append( v._resource if isinstance(v, OneCodexBase) else v) # coerce back to the value passed in self._resource[key] = type(value)(new_value) return elif hasattr(self, "_resource") and hasattr(self.__class__, "_resource"): schema = self.__class__._resource._schema["properties"].get(key) if schema is not None: # do some type checking against the schema if not self.__class__._has_schema_method("update"): raise MethodNotSupported( "{} do not support editing.".format( self.__class__.__name__)) if schema.get("readOnly", False): raise MethodNotSupported( "{} is a read-only field".format(key)) if schema.get("format") == "date-time": if isinstance(value, datetime): if value.tzinfo is None: value = value.isoformat() + "Z" else: value = value.isoformat() # changes on this model also change the potion resource self._resource[key] = value return raise AttributeError("'{}' object has no attribute '{}'".format( self.__class__.__name__, key))
def __delattr__(self, key): if not self.__class__._has_schema_method('update'): raise MethodNotSupported('{} do not support editing.'.format(self.__class__.__name__)) if hasattr(self, '_resource') and key in self._resource.keys(): # changes on this model also change the potion resource del self._resource[key]
def delete(self): """Delete this object from the One Codex server.""" check_bind(self) if self.id is None: raise ServerError("{} object does not exist yet".format( self.__class__.name)) elif not self.__class__._has_schema_method("destroy"): raise MethodNotSupported("{} do not support deletion.".format( self.__class__.__name__)) try: self._resource.delete() except HTTPError as e: if e.response.status_code == 403: raise PermissionDenied("") # FIXME: is this right? else: raise e