Alteryx IO Resources

Explore these resources to customize and extend the power of Alteryx with SDKs, APIs, and more.

Automate Creating a New Workspace and Inviting Users with the AAC API

briancoombs
Alteryx
Alteryx
Created

Overview

This guide explains how workspace admins or developers can use the AAC API to create a new workspace programmatically and then invite users to it.

It also gives an example of what you can quickly do with the API and show the potential for AAC users to build larger projects.

 

The create workspace endpoint used in this tutorial is still receiving updates and this documentation will be updated as that happens.

Guide

Video Demo

Getting your API Token and Using it

Follow our guide linked here.

You want an account-level refresh token. These tokens require account admin level privileges.

Create the Workspace

  1. You need an admin-level API token to create a workspace.

  2. You need to implement your own method for refreshing and setting the access tokens and refresh tokens at the top of the file.

  3. You’ll be hitting the /v4/workspaces?accountId={ACCOUNT_ID} endpoint to generate a workspace. Workspace-level API tokens cannot hit this endpoint.

  4. To find the ACCOUNT_ID variable, go to the account admin management console and copy the section in the URL between “/admin-portal/” and “/products”.

    screenshot of product account id.png
  5. When run with a valid account-level access token, this code returns a successful response and creates the workspace in your account.

import requests
import logging

# Setup logging
logging.basicConfig(level=logging.INFO)

## Variables to adjust based on the environment
base_url = "https://us1.alteryxcloud.com"

# Initial tokens (store these securely, possibly in environment variables or a secure key management system)
access_token = ""
refresh_token = ""

ACCOUNT_ID = "YOUR_ACCOUNT_ID_HERE"

def create_workspace(access_token, workspace_name, account_id):
    url = f"{base_url}/v4/workspaces?accountId={account_id}"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {access_token}",
        "x-alteryx-account-id" : f"{account_id}"
    }
    payload = {
        "name": workspace_name,
    }
    try:
        response = requests.post(url, json=payload, headers=headers)
        if response.status_code == 201:
            logging.info("Workspace created successfully!")
            return response.json()
        else:
            logging.error(f"Failed to create workspace, status code: {response.status_code}")
            logging.error(response.text)
            return None
    except requests.exceptions.RequestException as e:
        logging.exception("Request failed due to an exception.")
        return None

#### main exectution 

create_workspace(access_token, "inspire-api-demo-workspace", account_id)

 

Get Your New Workspace API Token

  1. Go to the new workspace and create an API token for it. This new API token creation cannot be automated at this time.

  2. Once you have your new access token and refresh token for the newly created workspace, you can invite users to it.

Figure Out the Roles You Want to Assign to Your New Users

  1. Use the /v4/people endpoint to get the roles associated with current users on your new workspace. If you assigned all the available roles to your new workspace admin, then you can see all the role options you have.

  2. Once you get the roles back from the script below, we recommend creating a JSON file (example included below).

Python Script

#### get roles and add users to workspace

import requests
import logging
import json

# Setup logging
logging.basicConfig(level=logging.INFO)

## Variables to adjust based on the environment
base_url = "https://us1.alteryxcloud.com"

# Initial tokens (store these securely, possibly in environment variables or a secure key management system)
access_token = ""
refresh_token = ""
WORKSPACE_ID = ""

def make_workspace_level_get_request(endpoint, access_token, workspace_id):
    url = base_url + endpoint
    try:
        headers = {
            "Accept": "application/json",
            "Authorization": f"Bearer {access_token}",
            "x-trifacta-workspace-id": f"{workspace_id}"  # Specific header for the workspace ID
        }   
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.json()
        else:
            logging.error(f"Failed to get data from {endpoint}, status code: {response.status_code}")
            logging.error(response.text)
            return None
    except requests.exceptions.RequestException as e:
        logging.exception("Request failed due to an exception.")
        return None
        
# main execution
        
people_response = make_workspace_level_get_request("/v4/people", access_token, WORKSPACE_ID)
print(people_response)

JSON File for Roles

This example includes an email list of the users to invite, along with the roles returned from the endpoint.

Please note, the variables like <YOURPOLICYID> that will be unique to your workspace in your people_response. The createdAt and updatedAt values will also be different.

As an example, you can save this JSON file as userInvite<workspaceId>.json.

{
    "emails": [
      "testuser1@alteryx.com", "testuser2@alteryx.com", "testuser3@alteryx.com", "testuser4@alteryx.com", "testuser5@alteryx.com", "testuser6@alteryx.com", "testuser7@alteryx.com", "testuser8@alteryx.com", "testuser9@alteryx.com", "testuser10@alteryx.com", "testuser11@alteryx.com", "testuser12@alteryx.com", "testuser13@alteryx.com", "testuser14@alteryx.com", "testuser15@alteryx.com", "testuser16@alteryx.com", "testuser17@alteryx.com", "testuser18@alteryx.com", "testuser19@alteryx.com", "testuser20@alteryx.com"
        ],
    "roles": [
      {
         "policyId":<YOURPOLICYID>,
         "name":"Auto Insights Creator",
         "workspaceId":<YOURWORKSPACEID>,
         "nameLocked":true,
         "privilegeLocked":true,
         "productPolicyId":<YOURPRODUCTPOLICYID>,
         "createdAt":"2024-04-24T05:05:57.000+00:00",
         "updatedAt":"2024-04-24T05:05:57.000+00:00",
         "resourceOperations":[
            {
               "operations":[
                  "share",
                  "update",
                  "read",
                  "create",
                  "delete"
               ],
               "resourceType":"connection",
               "policyTag":"connection_author"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"desktopworkflow",
               "policyTag":"desktopworkflow_none"
            },
            {
               "operations":[
                  "share",
                  "update",
                  "execute",
                  "read",
                  "create",
                  "delete"
               ],
               "resourceType":"aidatalayer",
               "policyTag":"aidatalayer_author"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"workflow",
               "policyTag":"workflow_none"
            },
            {
               "operations":[
                  "share",
                  "update",
                  "execute",
                  "read",
                  "create",
                  "delete"
               ],
               "resourceType":"plan",
               "policyTag":"plan_author"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"reference",
               "policyTag":"reference_none"
            },
            {
               "operations":[
                  "share",
                  "update",
                  "execute",
                  "read",
                  "create",
                  "delete"
               ],
               "resourceType":"aimission",
               "policyTag":"aimission_author"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"desktopapp",
               "policyTag":"desktopapp_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"abapplication",
               "policyTag":"abapplication_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"flow",
               "policyTag":"flow_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"vectorproject",
               "policyTag":"vectorproject_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"mlproject",
               "policyTag":"mlproject_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"aiproject",
               "policyTag":"aiproject_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"workload",
               "policyTag":"workload_none"
            },
            {
               "operations":[
                  "share",
                  "update",
                  "read",
                  "create",
                  "delete"
               ],
               "resourceType":"datasource",
               "policyTag":"datasource_author"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"userdefinedfunction",
               "policyTag":"userdefinedfunction_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"report",
               "policyTag":"report_none"
            },
            {
               "operations":[
                  
               ],
               "resourceType":"locationintelligenceproject",
               "policyTag":"locationintelligenceproject_none"
            }
         ]
      }
   ]
}

Invite Users to Your Workspace

  1. Now that you have the list of users, emails, and roles in the JSON file, you can invite the users.

  2. Add a POST request to /v4/workspaces/{workspace_id}/people/batch.

Additions to the Python Script

#### get roles and add users to workspace

import requests
import logging
import json

# Setup logging
logging.basicConfig(level=logging.INFO)

## Variables to adjust based on the environment
base_url = "https://us1.alteryxcloud.com"

# Initial tokens (store these securely, possibly in environment variables or a secure key management system)
access_token = ""
refresh_token = ""
WORKSPACE_ID = ""

def make_workspace_level_get_request(endpoint, access_token, workspace_id):
    url = base_url + endpoint
    try:
        headers = {
            "Accept": "application/json",
            "Authorization": f"Bearer {access_token}",
            "x-trifacta-workspace-id": f"{workspace_id}"  # Specific header for the workspace ID
        }   
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.json()
        else:
            logging.error(f"Failed to get data from {endpoint}, status code: {response.status_code}")
            logging.error(response.text)
            return None
    except requests.exceptions.RequestException as e:
        logging.exception("Request failed due to an exception.")
        return None

def invite_users(access_token, workspace_id, emails, roles):
    url = f"{base_url}/v4/workspaces/{workspace_id}/people/batch"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {access_token}",
        "x-trifacta-workspace-id": f"{workspace_id}"  # Specific header for the workspace ID
    }
    payload = {
        "emails": emails,
        "roles": roles
    }
    try:
        response = requests.post(url, json=payload, headers=headers)
        if response.status_code == 201:
            logging.info("Users invited successfully!")
            return response.json()
        else:
            logging.error(f"Failed to invite users, status code: {response.status_code}")
            logging.error(response.text)
            return None
    except requests.exceptions.RequestException as e:
        logging.exception("Request failed due to an exception.")
        return None

# main execution

with open("userInvite"+workspace_id+".json") as file:
    user_invitations = json.load(file)
    emails = user_invitations["emails"]
    roles = user_invitations["roles"]

invited_users = invite_users(access_token, WORKSPACE_ID, emails, roles)
print(invited_users)

Final Python Script

def invite_users(access_token, workspace_id, emails, roles):
    url = f"{base_url}/v4/workspaces/{workspace_id}/people/batch"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {access_token}",
        "x-trifacta-workspace-id": f"{workspace_id}"  # Specific header for the workspace ID
    }
    payload = {
        "emails": emails,
        "roles": roles
    }
    try:
        response = requests.post(url, json=payload, headers=headers)
        if response.status_code == 201:
            logging.info("Users invited successfully!")
            return response.json()
        else:
            logging.error(f"Failed to invite users, status code: {response.status_code}")
            logging.error(response.text)
            return None
    except requests.exceptions.RequestException as e:
        logging.exception("Request failed due to an exception.")
        return None

# main execution

people_response = make_workspace_level_get_request("/v4/people", access_token, WORKSPACE_ID)
print(people_response)

with open("userInvite"+workspace_id+".json") as file:
    user_invitations = json.load(file)
    emails = user_invitations["emails"]
    roles = user_invitations["roles"]

invited_users = invite_users(access_token, WORKSPACE_ID, emails, roles)
print(invited_users)

In Summary

You completed these steps to create new workspaces and invite users to them…

  1. Created an account level API Token and refreshed it as needed.

  2. Created a new workspace using our account level privileges.

  3. Got the workspace level API Token for that workspace and refreshed it as needed.

  4. Used that workspace token to determine the roles for our newly invited users.

  5. Invited those users with the specified roles.

You could expand upon this basic project by adding

  1. A smoother flow to pull roles and parse them into the invite endpoint without saving in JSON.

  2. User input option for emails.

  3. Automating this by attaching it to an AD group that adds users automatically to workspaces or creates workspaces based on rules for your AD groups.

Thank you for reading along and if you have issues or questions feel free to comment them below or post in the Developer Discussion Forum!