REST API : Recursive function with Python

yrignac
Occasional Contributor

REST API : Recursive function with Python

Hi,

 

I'm currently working on REST API. I would like to create a file with last username connected to each model.

 

Based on something created by Karan Kochhar, I currently have extracted all model information (with the user id of the last modification)

Problem is I can't extract all users information and merge both array. 

 

I assume I need to create a loop to get the name of the user for each model. 

 

I tried this code but it's not working. Can you help to fix this issue ? 

 

Thanks

 

Regards,

Yohan

 

 

models_response = anaplan.getModel(token)
 
for a in models_response['models']:
   if a['activeState'] != 'ARCHIVED':
user_info_response = anaplan.getUsersInformation(a['lastModifiedByUserGuid'],token)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_response[['id','email','lastname','firstname']],left_on='lastModifiedByUserGuid', right_on='id')

------

def getModel(vToken):
    model_header = {'Authorization':'AnaplanAuthToken ' + vToken}
    r = requests.get(model_url, headers=model_header)
    
    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()
    return r.json()
 
def getUsersInformation(UserID,vToken):
    getUsersInformation_url = 'https://api.anaplan.com/2/0/users/'+UserID
    header = {'Authorization':'AnaplanAuthToken ' + vToken,'Accept':'application/json'}
    r = requests.get(getUsersInformation_url, headers= header)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()
    return r.json()
1 ACCEPTED SOLUTION

Accepted Solutions
karanAMP
Contributor

Re: REST API : Recursive function with Python

@yrignac  

 

When it comes to API call , I cannot completely test this as I am not a tenant admin(I get 404 error as I don't have access to every user detail)  However i have tested this with my info only and it works . 

 

With regard to your python code , i think there are few issues 

 


  1. for a in models_response['models']:
       if a['activeState'] != 'ARCHIVED':
    user_info_response = anaplan.getUsersInformation(a['lastModifiedByUserGuid'],token)
    models_df =pd.DataFrame(models_response['models'])
    output_df = pd.merge(models_df,user_info_response[['id','email','lastname','firstname']],left_on='lastModifiedByUserGuid', right_on='id')
    you are recursively "over writing" user_info_response by calling the getUsers Information function in for loop . What you should do is append the responses in python object ( list ) 

eg 

user_info_response = []

for a in models_response['models'] :
   if a['activeState'] != 'ARCHIVED':
        user_info_response.append(getUsersInformation(a['lastModifiedByUserGuid'],token)['user'])

here I have defined an empty list user_info_response and then i am "appending" to the empty list . Also note ['user'] in the end this will give you only 'user' json tags. This should give you something like a list of dictionaries 

 

for a in models_response['models']:
   if a['activeState'] != 'ARCHIVED':
user_info_response = anaplan.getUsersInformation(a['lastModifiedByUserGuid'],token)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_response[['id','email','lastname','firstname']],left_on='lastModifiedByUserGuid', right_on='id')

 

in above highlighted code . model_df and output_df should never be in for loop . Instead do it outside for loop 

 

eg

user_info_df = pd.DataFrame(user_info_response)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_df,left_on='lastModifiedByUserGuid', right_on='id',how='left')

 

here  I have converted user_info_response list to user_info_df

model_df have model data

output.df is a merge of model_df and user_info_df . Please note how = left clause 

 

 

complete code 

import pandas as pd
import requests
import json
from base64 import b64encode

###############################################
username = "your username"
password = "your password"

###############################################

def getToken():
        
    header_string = { 'Authorization':'Basic ' + b64encode((username + ":" + password).encode('utf-8')).decode('utf-8') }
    anaplan_url='https://auth.anaplan.com/token/authenticate'

    print('getting Token')

    r=requests.post(anaplan_url, headers=header_string)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()

    resp_dict = json.loads(r.text)
    return resp_dict['tokenInfo']['tokenValue']

def getWorkspaces(t):

    workspace_url = 'https://api.anaplan.com/2/0/workspaces/?tenantDetails=true'
    header = {'Authorization':'AnaplanAuthToken ' + t}
    r = requests.get(workspace_url,headers=header)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()

    return r.json()

def getModel(t):
    
    model_url = 'https://api.anaplan.com/2/0/models/?modelDetails=True'
    model_header = {'Authorization':'AnaplanAuthToken ' + t}
    r = requests.get(model_url, headers=model_header)
    
    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()
    
    return r.json()

def getUsersInformation(UserID,vToken):
    getUsersInformation_url = 'https://api.anaplan.com/2/0/users/'+UserID
    header = {'Authorization':'AnaplanAuthToken ' + vToken,'Accept':'application/json'}
    r = requests.get(getUsersInformation_url, headers= header)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()
    return r.json()

################# main ##########################

token = getToken()
print(token)

workspaces_response = getWorkspaces(token)

#Saving workspace data in dataframe
workspace_df = pd.DataFrame(workspaces_response['workspaces'])
print(workspace_df)

models_response = getModel(token)

user_info_response = []
for a in models_response['models'] :
   if a['activeState'] != 'ARCHIVED':
        user_info_response.append(getUsersInformation(a['lastModifiedByUserGuid'],token)['user'])
        
user_info_df = pd.DataFrame(user_info_response)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_df,left_on='lastModifiedByUserGuid', right_on='id',how='left')

 

 

View solution in original post

3 REPLIES 3
yrignac
Occasional Contributor

Re: REST API : Recursive function with Python

Nobody has ever exeperience that ?

 

Thank you for your help

 

 

karanAMP
Contributor

Re: REST API : Recursive function with Python

@yrignac  

 

When it comes to API call , I cannot completely test this as I am not a tenant admin(I get 404 error as I don't have access to every user detail)  However i have tested this with my info only and it works . 

 

With regard to your python code , i think there are few issues 

 


  1. for a in models_response['models']:
       if a['activeState'] != 'ARCHIVED':
    user_info_response = anaplan.getUsersInformation(a['lastModifiedByUserGuid'],token)
    models_df =pd.DataFrame(models_response['models'])
    output_df = pd.merge(models_df,user_info_response[['id','email','lastname','firstname']],left_on='lastModifiedByUserGuid', right_on='id')
    you are recursively "over writing" user_info_response by calling the getUsers Information function in for loop . What you should do is append the responses in python object ( list ) 

eg 

user_info_response = []

for a in models_response['models'] :
   if a['activeState'] != 'ARCHIVED':
        user_info_response.append(getUsersInformation(a['lastModifiedByUserGuid'],token)['user'])

here I have defined an empty list user_info_response and then i am "appending" to the empty list . Also note ['user'] in the end this will give you only 'user' json tags. This should give you something like a list of dictionaries 

 

for a in models_response['models']:
   if a['activeState'] != 'ARCHIVED':
user_info_response = anaplan.getUsersInformation(a['lastModifiedByUserGuid'],token)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_response[['id','email','lastname','firstname']],left_on='lastModifiedByUserGuid', right_on='id')

 

in above highlighted code . model_df and output_df should never be in for loop . Instead do it outside for loop 

 

eg

user_info_df = pd.DataFrame(user_info_response)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_df,left_on='lastModifiedByUserGuid', right_on='id',how='left')

 

here  I have converted user_info_response list to user_info_df

model_df have model data

output.df is a merge of model_df and user_info_df . Please note how = left clause 

 

 

complete code 

import pandas as pd
import requests
import json
from base64 import b64encode

###############################################
username = "your username"
password = "your password"

###############################################

def getToken():
        
    header_string = { 'Authorization':'Basic ' + b64encode((username + ":" + password).encode('utf-8')).decode('utf-8') }
    anaplan_url='https://auth.anaplan.com/token/authenticate'

    print('getting Token')

    r=requests.post(anaplan_url, headers=header_string)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()

    resp_dict = json.loads(r.text)
    return resp_dict['tokenInfo']['tokenValue']

def getWorkspaces(t):

    workspace_url = 'https://api.anaplan.com/2/0/workspaces/?tenantDetails=true'
    header = {'Authorization':'AnaplanAuthToken ' + t}
    r = requests.get(workspace_url,headers=header)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()

    return r.json()

def getModel(t):
    
    model_url = 'https://api.anaplan.com/2/0/models/?modelDetails=True'
    model_header = {'Authorization':'AnaplanAuthToken ' + t}
    r = requests.get(model_url, headers=model_header)
    
    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()
    
    return r.json()

def getUsersInformation(UserID,vToken):
    getUsersInformation_url = 'https://api.anaplan.com/2/0/users/'+UserID
    header = {'Authorization':'AnaplanAuthToken ' + vToken,'Accept':'application/json'}
    r = requests.get(getUsersInformation_url, headers= header)

    try:
        r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("Error: " + str(e))
        exit()
    return r.json()

################# main ##########################

token = getToken()
print(token)

workspaces_response = getWorkspaces(token)

#Saving workspace data in dataframe
workspace_df = pd.DataFrame(workspaces_response['workspaces'])
print(workspace_df)

models_response = getModel(token)

user_info_response = []
for a in models_response['models'] :
   if a['activeState'] != 'ARCHIVED':
        user_info_response.append(getUsersInformation(a['lastModifiedByUserGuid'],token)['user'])
        
user_info_df = pd.DataFrame(user_info_response)
models_df =pd.DataFrame(models_response['models'])
output_df = pd.merge(models_df,user_info_df,left_on='lastModifiedByUserGuid', right_on='id',how='left')

 

 

View solution in original post

yrignac
Occasional Contributor

Re: REST API : Recursive function with Python

Well thank you very much Karan.

 

I had to split the for loop to avoid duplicate member as I have several models with the same last modified id user.

 

I still have one specific for one model who the user has been removed. 

Id exists within the model list but when you get user information with the id we got a error.

 

But I'll find a solution by myself.

 

Thank you very much

 

Regards,

Yohan