def hide_unit(self, unit_uuid, unit_type): """GET <unit_type>/<unit_uuid>/delete/.""" return utils._call_url_json( "{}/api/{}/{}/delete/".format(self.am_url, unit_type, unit_uuid), params=self._am_auth(), method=utils.METHOD_DELETE, )
def get_pipelines(self): """GET Archivematica Pipelines (dashboard instances from the storage service. """ return utils._call_url_json( "{0}/api/v2/pipeline/".format(self.ss_url), headers=self._ss_auth_headers() )
def create_location(self): """Create a new location in the Storage Service.""" if not self.location_purpose.upper() in self.list_location_purposes(): return { "error": "location purpose not permitted", "valid_purposes": self.list_location_purposes(), } url = "{0}/api/v2/location/".format(self.ss_url) desc = self.location_description if self.location_description else "" pipelines = [ "/api/v2/pipeline/{}/".format(pipeline.strip()) for pipeline in self.pipeline_uuids.split(",") ] params = { "description": desc, "pipeline": pipelines, "space": "/api/v2/space/{}/".format(self.space_uuid), "default": self.default if self.default else False, "purpose": self.location_purpose, "relative_path": self.space_relative_path, } return utils._call_url_json( url, params=json.dumps(params), method=utils.METHOD_POST, headers=self._ss_auth_headers(), )
def get_ingest_status(self): """GET ingest status if there is an ingest in progress in the Archivematica pipeline. """ return utils._call_url_json( "{0}/api/ingest/status/{1}/".format(self.am_url, self.sip_uuid), headers=self._am_auth_headers(), )
def get_package_details(self): """SS GET /api/v2/file/<uuid>. Retrieve the details of a specific package given a package uuid. """ return utils._call_url_json( "{0}/api/v2/file/{1}".format(self.ss_url, self.package_uuid), headers=self._ss_auth_headers(), )
def unapproved_transfers(self): """Return all unapproved transfers. GET transfer/unapproved:: $ ./amclient.py unapproved-transfers \ --am-user-name=test \ --am-api-key=e8f8a0fb157f08a260045f805455e144d8ad0a5b """ return utils._call_url_json( "{}/api/transfer/unapproved".format(self.am_url), self._am_auth())
def completed_ingests(self): """Return all completed ingests. GET /ingest/completed:: $ ./amclient.py completed-ingests \ --am-user-name=test \ e8f8a0fb157f08a260045f805455e144d8ad0a5b """ return utils._call_url_json( "{}/api/ingest/completed".format(self.am_url), self._am_auth())
def approve_partial_reingest(self): """Approve a partial reingest using the SIP UUID.""" url = "{0}/api/ingest/reingest/approve/".format(self.am_url) params = {"uuid": self.sip_uuid} return utils._call_url_json( url, headers=self._am_auth_headers(), params=params, method=utils.METHOD_POST, )
def list_storage_locations(self): """List all Storage Service locations.""" params = {} url = "{0}/api/v2/location/".format(self.ss_url) return utils._call_url_json( url, headers=self._ss_auth_headers(), params=json.dumps(params), method=utils.METHOD_GET, )
def get_jobs(self): """Get a list of jobs ran for a unit (transfer or ingest).""" url = "{}/api/v2beta/jobs/{}".format(self.am_url, self.unit_uuid) params = {} for attribute in ["microservice", "link_uuid", "name"]: value = getattr(self, "job_{}".format(attribute), None) if value is not None: params[attribute] = value return utils._call_url_json( url, headers=self._am_auth_headers(), params=params, method=utils.METHOD_GET )
def get_processing_config(self, assume_json=False): """GET a processing configuration file from an Archivematica instance. if the request is successful an application/xml response is returned to the caller. If the request is unsuccessful then an error code is returned which needs to be handled via error_lookup. The default is to return the default processing config from the AM server. """ return utils._call_url_json( "{0}/api/processing-configuration/{1}".format( self.am_url, self.processing_config), headers=self._am_auth_headers(), assume_json=assume_json, )
def delete_package( self, package_uuid, pipeline_uuid, event_reason, ss_user_id, ss_user_email ): """Create a deletion request for a package.""" params = { "pipeline": pipeline_uuid, "event_reason": event_reason, "user_id": ss_user_id, "user_email": ss_user_email, } url = "{}/api/v2/file/{}/delete_aip/".format(self.ss_url, package_uuid) return utils._call_url_json( url, headers=self._ss_auth_headers(), params=json.dumps(params), method=utils.METHOD_POST, )
def get_transfer_status(self): """Given a Transfer UUID, GET the transfer status. If there isn't a transfer with this UUID in the pipeline then the response from the server will look as follows:: {"message": "Cannot fetch unitTransfer with UUID" " ebc8a35c-6742-4264-bc30-22e263966d69", "type": "transfer", "error": true} The response suggesting non-existence is an error, "error": true, is something the caller will have to handle appropriately for their application. """ return utils._call_url_json( "{0}/api/transfer/status/{1}/".format(self.am_url, self.transfer_uuid), headers=self._am_auth_headers(), )
def transferables(self, b64decode=True): """Return all transferable entities in the Storage Service. GET location/<TS_LOC_UUID>/browse/:: $ ./amclient.py transferables \ --ss-user-name=test \ --ss-api-key=7558e7485cf8f20aadbd95f6add8b429ba11cd2b \ --transfer-source=7ea1eb0e-5f4e-42e0-836d-c9b4ab5692e1 \ --transfer-path=vagrant/archivematica-sampledata """ url = "{}/api/v2/location/{}/browse/".format(self.ss_url, self.transfer_source) params = self._ss_auth() if self.transfer_path: params["path"] = base64.b64encode(utils.fsencode(self.transfer_path)) result = utils._call_url_json(url, params) if b64decode: return b64decode_ts_location_browse(result) return result
def validate_csv(self, validator, file_obj): """Validates a CSV file against a set of embedded rules. The file to be validated is expected to be passed as an open file object (in Python 3+ a io.TextIOBase instance).""" url = "{}/api/v2beta/validate/{}/".format(self.am_url, validator) if not (isinstance(file_obj, io.TextIOBase) or hasattr(file_obj, "read")): raise TypeError( "Expected an io.TextIOWrapper file object but got {} instead".format( type(file_obj) ) ) data = file_obj.read() headers = self._am_auth_headers() headers.update({"Content-Type": "text/csv; charset=utf-8"}) return utils._call_url_json( url, params=data, method=utils.METHOD_POST, headers=headers, enhanced_errors=getattr(self, "enhanced_errors", False), )
def create_package(self): """Create a transfer using the new API v2 package endpoint.""" url = "{}/api/v2beta/package/".format(self.am_url) transfer_source = getattr(self, "transfer_source", None) if not transfer_source: path = self.transfer_directory else: path = "{}:{}".format(self.transfer_source, self.transfer_directory) b64path = base64.b64encode(utils.fsencode(path)) params = { "name": self.transfer_name, "path": b64path.decode(), "type": self.transfer_type, "processing_config": self.processing_config, } return utils._call_url_json( url, headers=self._am_auth_headers(), params=json.dumps(params), method=utils.METHOD_POST, )
def copy_metadata_files(self, sip_uuid, source_paths): """Add metadata files to a SIP using its UUID. The `source_paths` parameter must be a list of tuples with (location UUID, absolute path). """ url = "{}/api/ingest/copy_metadata_files/".format(self.am_url) params = { "sip_uuid": sip_uuid, "source_paths[]": [ base64.b64encode("{}:{}".format(location_uuid, path).encode()) for (location_uuid, path) in source_paths ], } return utils._call_url_json( url, params=params, method=utils.METHOD_POST, headers=self._am_auth_headers(), enhanced_errors=getattr(self, "enhanced_errors", False), )
def reingest_aip(self): """Initiate the reingest of an AIP via the Storage Service given the API UUID and Archivematica Pipeline. Reingest default is set to ``full``. Alternatives are: * METADATA_ONLY (metadata only re-ingest) * OBJECTS (partial re-ingest) * FULL (full re-ingest) """ params = { "pipeline": self.pipeline_uuid, "reingest_type": self.reingest_type, "processing_config": self.processing_config, } url = "{0}/api/v2/file/{1}/reingest/".format(self.ss_url, self.aip_uuid) return utils._call_url_json( url, headers=self._ss_auth_headers(), params=json.dumps(params), method=utils.METHOD_POST, )
def approve_transfer(self): """Approve a transfer in the Archivematica Pipeline. The transfer_type informs Archivematica how to continue processing. Options are: * standard * unzipped bag * zipped bag * dspace Directory is the location where the transfer is to be picked up from. The directory can be found via the get_transfer_status API call. """ url = "{0}/api/transfer/approve/".format(self.am_url) params = { "type": self.transfer_type, "directory": utils.fsencode(self.transfer_directory), } return utils._call_url_json( url, headers=self._am_auth_headers(), params=params, method=utils.METHOD_POST, )
def get_package(self, params=None): """SS GET /api/v2/file/?<GET_PARAMS>.""" payload = self._ss_auth() payload.update(params) return utils._call_url_json("{}/api/v2/file/".format(self.ss_url), payload)
def get_next_package_page(self, next_path): """SS GET /api/v2/file/?<GET_PARAMS> using the next URL from previous responses, which includes the auth. parameters. """ return utils._call_url_json("{}{}".format(self.ss_url, next_path), {})