Dataset Tags in Workflows Not accessible

NateBI
NateBI Contributor

Hi Team,

How do I access the 'tags' variable from the Get Metadata function output in Workflows. The option isn't included in the children:

image.png

however in code engine this is available:

image.png

Any thoughts please let me know.

Tagged:

Answers

  • brycec
    brycec Domo Employee

    That's not supported in that package in the current implementation. You can create an idea in the Ideas Exchange if that's something you would like added.

    If you want to instead create your own Code Engine function to achieve that, you can using the following:

    const codeengine = require('codeengine')
     
    async function getTags(datasetId) {
      const api = `/api/data/v3/datasources/${datasetId}`;
      const response = await codeengine.sendRequest("GET", api);
      console.log(response);
      let array = JSON.parse(response.tags);
      return array;
    }
    

    Was this comment helpful? Click Agree or Like below.
    Did this comment solve your problem? Accept it as the solution!

  • NateBI
    NateBI Contributor

    Thanks @brycec - ironically I started with code engine before discovering the functions. I'll write an idea.

  • NateBI
    NateBI Contributor

    Commenting back here @brycec . I'm getting a None response for the https://developer.domo.com/portal/35115c5c48927-datasets-api#createdatasettag function.

    It works, but if it doesn't return a Status there's no robust way of knowing when it doesn't work - for example when a dataset has been deleted, it will still go through despite the dataset no longer existing.

    The documentation says there is a response, so is this a bug?

    image.png
      try:
        test = update_response.get('HTTP/1.1','[]')
      except Exception as e:
        return f"That didn't work: {e}"
    
    » "That didn't work: 'NoneType' object has no attribute 'get'"
    
    
  • brycec
    brycec Domo Employee

    Are you doing this request in Code Engine? If so, you have to use the codeengine.sendRequest method.

    Also, in my original comment, I wrote a function for getting tags, which is a GET request. But the link you sent is for creating tags, which is a POST request. In your code, you are using GET but with a body of an empty array. This would fail as GET requests cannot ever have a body.

    Was this comment helpful? Click Agree or Like below.
    Did this comment solve your problem? Accept it as the solution!

  • NateBI
    NateBI Contributor
    edited June 12

    @brycec Not quite. So I'm using codeengine, and the get and post are for appropriate tasks (I thought you would have seen the Idea I commented) here's the full function I'm working with:

    def manipulate_dataset_tags(dataset_id, input_tags, action):
      """
      This function allows users to extend, remove, or replace dataset tags.
      Returns: Success status(str).
      Params:
      dataset_id(str) The dataset id - not using DATASET type to handle data types programmatically. 
      input_tags(list) The list of tags e.g. ['tag1','tag2','tag3'] for extending or removing
      action(str) The type of action: 'extend', 'remove', or 'replace
      """
      import json
      from datetime import datetime
    
      # Validate tags input
      if not isinstance(input_tags, list):
        raise ValueError("tags must be a list of strings or a single string")
    
      if not isinstance(action, str):
        raise ValueError("action must be a string: 'extend', 'remove', or 'replace")    
      
      if action not in('extend','remove','replace'):
        raise ValueError("Action must be either 'extend', 'remove', or 'replace'")
     
      get_url = f"/api/data/v3/datasources/{dataset_id}"
      post_url = f"/api/data/ui/v3/datasources/{dataset_id}/tags"
    
      current_dateTime = datetime.now()
      
      # Connect to Dataset  
      try:
        response = codeengine.send_request('GET', get_url)
      except Exception as e: 
        return f"unsuccessful,{current_dateTime},{str(input_tags).replace(',','+')}, error connecting to dataset: {e}"
    
      # Retrieve tags:
      try:
        raw_tags = response.get('tags', '[]')
        tags = json.loads(raw_tags) if isinstance(raw_tags, str) else raw_tags
        if not isinstance(tags, list):
            tags = []
      except Exception as e:
            tags = []
      
      if action == 'remove':
        # Find which tags are present
        present_tags = [tag for tag in input_tags if tag in tags]
    
        # if none of the tags are present, stop
        if not present_tags:
            return f"unsuccessful,{current_dateTime},{str(input_tags).replace(',','+')},none of the specified tags exist: {tags}"
        
        # Remove unwanted tags
        tags = [tag for tag in tags if tag not in input_tags]
      
      if action == 'extend':
        # Update Tags
        tags.extend(input_tags)
    
      if action == 'replace':
        # Replace tags
        tags = input_tags
        
      # Implement change
      update_response = codeengine.send_request('POST', post_url, tags)
      
      if not update_response or ('error' in update_response or 'status' in update_response and update_response['status'] != 200):
        return f"unsuccessful,{current_dateTime},{str(input_tags).replace(',','+')},POST request may have failed: {update_response}"
    
    
      # Validate by re-fetching the tags
      response = codeengine.send_request('GET', get_url)
    
      # Retrieve existing_tags tags:
      try:
        raw_tags = response.get('tags', '[]')
        existing_tags = json.loads(raw_tags) if isinstance(raw_tags, str) else raw_tags
        if not isinstance(tags, list):
            tags = []
      except Exception as e:
            tags = []
      
      # Validation status
      if set(existing_tags) == set(tags):
          return f"successful,{current_dateTime},{str(input_tags).replace(',','+')},validation was a success"
      else:
          return f"unsuccessful,{current_dateTime},{str(input_tags).replace(',','+')}, validation may have failed"
    

    The previous code I posted was a test using the dict.get() method once the call had been made to the var updated_repsonse - not related to a GET call. I'm using GET to extract tags and POST to add tags appropriate and it works, there's just no response.status for example. Documentation says it should be retrievable using the previous block I sent:

      try:
    test = update_response.get('HTTP/1.1','[]')
    except Exception as e:
    return f"That didn't work: {e}"

    » "That didn't work: 'NoneType' object has no attribute 'get'"

    But still getting that None response from the POST call.

  • brycec
    brycec Domo Employee

    Sorry, I didn't realize the function you were using was the same one in the idea.

    The function I suggested was written in JavaScript. You are using Python. I am less familiar with writing Code Engine functions in Python. But from what I can tell, the codeengine.request method is only for JavaScript. For Python, you want to instead import the requests library and provide full authentication details.

    token = "<your_api_access_token>"
    base_url = f"<instance>.domo.com"
    get_url = f"https://{base_url}/api/data/v3/datasources/{dataset_id}"
    headers = {
    "X-DOMO-Developer-Token": token
    } response = requests.get(get_url, headers=headers)





    print(response.text)

    data = response.json()

    Was this comment helpful? Click Agree or Like below.
    Did this comment solve your problem? Accept it as the solution!

  • NateBI
    NateBI Contributor
    edited 6:09AM

    @brycec so it is supported in Python as well, I was recommended it by Jace at Domo. I've created a ticket so all good, I'm pretty sure it's a bug.