Пример #1
0
def get_key_value(key: str) -> Any:
    """
    Get the value for a key

    Args:
        - key (str): the name of the key

    Returns:
        - value (Any): A json compatible value

    Raises:
        - ValueError: if the specified key does not exist
        - ClientError: if using Prefect Server instead of Cloud
    """
    if prefect.config.backend != "cloud":
        raise ClientError(NON_CLOUD_BACKEND_ERROR_MESSAGE)

    query = {
        "query": {
            with_args("key_value", {"where": {
                "key": {
                    "_eq": key
                }
            }}): {"value"}
        }
    }
    client = Client()
    result = client.graphql(query)  # type: Any
    if len(result.data.key_value) == 0:
        raise ValueError(f"No value found for key: {key}")
    return result.data.key_value[0].value
Пример #2
0
def set_key_value(key: str, value: Any) -> str:
    """
    Set key value pair, overwriting values for existing key

    Args:
        - key (str): the name of the key
        - value (Any): A json compatible value

    Returns:
        - id (str): the id of the key value pair

    Raises:
        - ClientError: if using Prefect Server instead of Cloud
        - ValueError: if `value` exceeds 10 KB limit
    """
    if prefect.config.backend != "cloud":
        raise ClientError(NON_CLOUD_BACKEND_ERROR_MESSAGE)

    # check value is under size limit
    # note this will be enforced by the API
    value_size = sys.getsizeof(json.dumps(value))
    if value_size > 10000:  # 10 KB max
        raise ValueError("Value payload exceedes 10 KB limit.")

    mutation = {
        "mutation($input: set_key_value_input!)": {
            "set_key_value(input: $input)": {"id"}
        }
    }

    client = Client()
    result = client.graphql(query=mutation,
                            variables=dict(input=dict(key=key, value=value)))

    return result.data.set_key_value.id
Пример #3
0
def list_keys() -> List[str]:
    """
    List all keys

    Returns:
        - keys (list): A list of keys

    Raises:
        - ClientError: if using Prefect Server instead of Cloud
    """
    if prefect.config.backend != "cloud":
        raise ClientError(NON_CLOUD_BACKEND_ERROR_MESSAGE)
    client = Client()
    result = client.graphql({"query": {"key_value": {"key"}}})  # type: ignore
    return sorted([res["key"] for res in result.data.key_value])
Пример #4
0
def delete_key(key: str) -> bool:
    """
    Delete a key value pair

    Args:
        - key (str): the name of the key

    Returns:
        - success (bool): Whether or not deleting the key succeeded

    Raises:
        - ValueError: if the specified key does not exist
        - ClientError: if using Prefect Server instead of Cloud
    """
    if prefect.config.backend != "cloud":
        raise ClientError(NON_CLOUD_BACKEND_ERROR_MESSAGE)

    query = {
        "query": {
            with_args("key_value", {"where": {
                "key": {
                    "_eq": key
                }
            }}): {"id"}
        }
    }
    mutation = {
        "mutation($input: delete_key_value_input!)": {
            "delete_key_value(input: $input)": {"success"}
        }
    }

    client = Client()
    key_value_id_query = client.graphql(query=query)
    if len(key_value_id_query.data.key_value) == 0:
        raise ValueError(f"No key {key} found to delete")
    result = client.graphql(
        query=mutation,
        variables=dict(input=dict(
            key_value_id=key_value_id_query.data.key_value[0].id)),
    )

    return result.data.delete_key_value.success
Пример #5
0
    def _send_graphql_request(
        self, query: str, variables: dict = None
    ) -> Dict[str, Any]:
        response = requests.post(
            url=self._api_url,
            json=dict(query=query, variables=variables),
            headers={
                "x-mcd-id": self.api_key_id,
                "x-mcd-token": self.api_token,
                "Content-Type": "application/json",
            },
        )
        # Check if request returned a successful status
        try:
            response.raise_for_status()
        except requests.HTTPError as exc:
            if response.status_code == 400:
                # Create a custom-formatted err message for graphql errors which always
                # return a 400 status code and have "query" in the parameter dict
                try:
                    graphql_msg = format_graphql_request_error(response)
                except Exception:
                    # Fallback to a general message
                    graphql_msg = (
                        "This is likely caused by a poorly formatted GraphQL query or "
                        "mutation but the response could not be parsed for more details"
                    )
                raise ClientError(f"{exc}\n{graphql_msg}") from exc

            # Server-side and non-graphql errors will be raised without modification
            raise
        response = response.json()
        self.logger.debug(
            "Response: %s for request %s with variables %s", response, query, variables
        )
        return response