def _api_create_package(
    am_url,
    am_user,
    am_api_key,
    name,
    package_type,
    accession,
    ts_location_uuid,
    ts_path,
):
    url = am_url + "/api/v2beta/package/"
    headers = {"Authorization": "ApiKey {}:{}".format(am_user, am_api_key)}
    data = {
        "name": name,
        "type": package_type,
        "accession": accession,
        "path": base64.b64encode(fsencode(ts_location_uuid) + b":" + ts_path),
    }
    LOGGER.debug("URL: %s; Headers: %s, Data: %s", url, headers, data)
    response = requests.post(url, headers=headers, json=data)
    response.raise_for_status()
    LOGGER.debug("Response: %s", response)
    resp_json = response.json()
    error = resp_json.get("error")
    if error:
        raise DashboardAPIError(error)
    return resp_json
Ejemplo n.º 2
0
def approve_transfer(dirname, url, am_api_key, am_user):
    """
    Approve transfer with dirname.

    :returns: UUID of the approved transfer or None.
    """
    LOGGER.info("Approving %s", dirname)
    time.sleep(6)
    am = AMClient(am_url=url, am_user_name=am_user, am_api_key=am_api_key)
    try:
        # Find the waiting transfers available to be approved via the am client
        # interface.
        waiting_transfers = am.unapproved_transfers()["results"]
    except (KeyError, TypeError):
        LOGGER.error(
            "Request to unapproved transfers did not return the "
            "expected response, see the request log"
        )
        return None
    if not waiting_transfers:
        LOGGER.warning("There are no waiting transfers.")
        return None
    res = list(
        filter(
            lambda waiting: fsencode(waiting["directory"]) == fsencode(dirname),
            waiting_transfers,
        )
    )
    if not res:
        LOGGER.warning(
            "Requested directory %s not found in the waiting " "transfers list", dirname
        )
        return None
    LOGGER.info("Found waiting transfer: %s", res[0]["directory"])
    # We can reuse the existing AM Client but we didn't know all the kwargs
    # at the outset so we need to set its attributes here.
    am.transfer_type = res[0]["type"]
    am.transfer_directory = dirname
    # Approve the transfer and return the UUID of the transfer approved.
    approved = am.approve_transfer()
    if isinstance(approved, int):
        if errors.error_lookup(approved) is not None:
            LOGGER.error("Error approving transfer: %s", errors.error_lookup(approved))
            return None
    # Get will return None, or the UUID.
    return approved.get("uuid")
Ejemplo n.º 3
0
def approve_transfer(dirname, url, am_api_key, am_user):
    """
    Approve transfer with dirname.

    :returns: UUID of the approved transfer or None.
    """
    LOGGER.info("Approving %s", dirname)
    time.sleep(6)
    am = AMClient(am_url=url, am_user_name=am_user, am_api_key=am_api_key)
    try:
        # Find the waiting transfers available to be approved via the am client
        # interface.
        waiting_transfers = am.unapproved_transfers()["results"]
    except (KeyError, TypeError):
        LOGGER.error(
            "Request to unapproved transfers did not return the "
            "expected response, see the request log"
        )
        return None
    if not waiting_transfers:
        LOGGER.warning("There are no waiting transfers.")
        return None
    res = list(
        filter(
            lambda waiting: fsencode(waiting["directory"]) == fsencode(dirname),
            waiting_transfers,
        )
    )
    if not res:
        LOGGER.warning(
            "Requested directory %s not found in the waiting " "transfers list", dirname
        )
        return None
    LOGGER.info("Found waiting transfer: %s", res[0]["directory"])
    # We can reuse the existing AM Client but we didn't know all the kwargs
    # at the outset so we need to set its attributes here.
    am.transfer_type = res[0]["type"]
    am.transfer_directory = dirname
    # Approve the transfer and return the UUID of the transfer approved.
    approved = am.approve_transfer()
    if isinstance(approved, int):
        if errors.error_lookup(approved) is not None:
            LOGGER.error("Error approving transfer: %s", errors.error_lookup(approved))
            return None
    # Get will return None, or the UUID.
    return approved.get("uuid")
Ejemplo n.º 4
0
def _api_create_package(am_url, am_user, am_api_key, name, package_type,
                        accession, ts_location_uuid, ts_path):
    url = am_url + '/api/v2beta/package/'
    headers = {'Authorization': 'ApiKey {}:{}'.format(am_user, am_api_key)}
    data = {
        'name': name,
        'type': package_type,
        'accession': accession,
        'path': base64.b64encode(fsencode(ts_location_uuid) + b':' + ts_path),
    }
    LOGGER.debug('URL: %s; Headers: %s, Data: %s', url, headers, data)
    response = requests.post(url, headers=headers, json=data)
    response.raise_for_status()
    LOGGER.debug('Response: %s', response)
    resp_json = response.json()
    error = resp_json.get('error')
    if error:
        raise DashboardAPIError(error)
    return resp_json
Ejemplo n.º 5
0
def call_start_transfer_endpoint(am_url, am_user, am_api_key, target,
                                 transfer_type, accession, ts_location_uuid):
    """Make the call to the start_transfer endpoint and return the unapproved
    directory name, and current (absolute path), of the transfer as a tuple.
    """
    url = "{}/api/transfer/start_transfer/".format(am_url)
    params = {"username": am_user, "api_key": am_api_key}
    target_name = os.path.basename(target)
    data = {
        "name": target_name,
        "type": transfer_type,
        "accession": accession,
        "paths[]":
        [base64.b64encode(fsencode(ts_location_uuid) + b":" + target)],
        "row_ids[]": [""],
    }
    LOGGER.debug("URL: %s; Params: %s; Data: %s", url, params, data)
    response = requests.post(url, params=params, data=data)
    LOGGER.debug("Response: %s", response)
    try:
        resp_json = response.json()
        # Retrieve transfer_name, and the absolute path to the transfer for the
        # calling function.
        transfer_abs_path = resp_json.get("path")
        return os.path.basename(transfer_abs_path.strip(
            os.sep)), transfer_abs_path
    except ValueError:
        LOGGER.error(
            "Could not parse JSON from response Response: %s: %s, %s",
            response.status_code,
            response.reason,
            response.headers,
        )
        # Debug log, rather than Warning as the response from the server is
        # likely to be HTML and likely to be too verbose to be useful.
        LOGGER.debug("Could not parse JSON from response: %s", response.text)
        return None, None
    if not response.ok or resp_json.get("error"):
        LOGGER.error("Unable to start transfer.")
        LOGGER.error("Response: %s", resp_json)
        return None, None
Ejemplo n.º 6
0
def call_start_transfer_endpoint(
    am_url, am_user, am_api_key, target, transfer_type, accession, ts_location_uuid
):
    """Make the call to the start_transfer endpoint and return the unapproved
    directory name, and current (absolute path), of the transfer as a tuple.
    """
    url = "{}/api/transfer/start_transfer/".format(am_url)
    params = {"username": am_user, "api_key": am_api_key}
    target_name = os.path.basename(target)
    data = {
        "name": target_name,
        "type": transfer_type,
        "accession": accession,
        "paths[]": [base64.b64encode(fsencode(ts_location_uuid) + b":" + target)],
        "row_ids[]": [""],
    }
    LOGGER.debug("URL: %s; Params: %s; Data: %s", url, params, data)
    response = requests.post(url, params=params, data=data)
    LOGGER.debug("Response: %s", response)
    try:
        resp_json = response.json()
        # Retrieve transfer_name, and the absolute path to the transfer for the
        # calling function.
        transfer_abs_path = resp_json.get("path")
        return os.path.basename(transfer_abs_path.strip(os.sep)), transfer_abs_path
    except ValueError:
        LOGGER.error(
            "Could not parse JSON from response Response: %s: %s, %s",
            response.status_code,
            response.reason,
            response.headers,
        )
        # Debug log, rather than Warning as the response from the server is
        # likely to be HTML and likely to be too verbose to be useful.
        LOGGER.debug("Could not parse JSON from response: %s", response.text)
        return None, None
    if not response.ok or resp_json.get("error"):
        LOGGER.error("Unable to start transfer.")
        LOGGER.error("Response: %s", resp_json)
        return None, None
Ejemplo n.º 7
0
    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)