Help with Python API 2.0 & Transactional API

DaanishSoomar
Certified Master Anaplanner

Help with Python API 2.0 & Transactional API

Hello 

 

I am attempting to utilize the transactional API in Python. Specifically trying to retrieve all line items in a model w/ID

 

DaanishSoomar_0-1627056642907.png

 

I tried doing this in Anaplan Connect earlier, however, it did not work for me. I am now trying in Python. However, it's quite the challenge as 1 article does not have the steps, I am having to read 5+ articles to piece together the script, though because each author has slightly different naming variables, I am having a bit of difficulty piecing it all together. 

 

Anyone have a template which can call the transactional API? I will ideally need a template that takes me from authentication all the way through retrieving all line items and then putting that data into a csv.

 

Tagging Python pros: @Kevin_Cho @jesse_wilson @christophe_keom @JaredDolich 

 

1 ACCEPTED SOLUTION

Accepted Solutions
kevin.cho
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Cheers @DaanishSoomar  for picking that up, there is indeed a typo! 

 

And yeah, you can consolidate it all into one script if you'd like. You can create a function like how Karan had done it, if you will be calling it multiple times. 

E.g.

def auth_token_basic(email, password):
    user_pw = b64encode(bytes(email+':'+password, 'utf-8'))
    auth_headers = {} 
    auth_headers['Authorization'] = 'Basic ' + user_pw
    auth_url = 'https://auth.anaplan.com/token/authenticate'
    auth_json = requests.post(auth_url, headers=auth_headers).json()
    try:
        auth_token = auth_json['tokenInfo']['tokenValue']
        return auth_token
    except KeyError:
        print('No Token Info found - check your credentials?')

 

You can then just call this function 

my_email = '...'
my_password = '...'
token = auth_token_basic(my_email, my_password)

 

Can do the same for the CSV script I gave before too 

View solution in original post

11 REPLIES 11
JaredDolich
Moderator

Re: Help with Python API 2.0 & Transactional API

@DaanishSoomar 

Sorry Daanish! I haven't dug into the Transactional APIs yet primarily because they use V2 API. I have every scenario under the sun for bulk APIs using Python. The issue is the tokenization for me. I have to figure out how to get that working.


Jared Dolich
DaanishSoomar
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Yeah that’s also exactly where I’m struggling too. I’ve tried compiling research and applying it from other articles in community. I guess my execution is off.

karanAMP
Contributor

Re: Help with Python API 2.0 & Transactional API

@DaanishSoomar i was able to do it . What error are you getting ? may be share your python code i should be able to debug

 

My code ( function to get all line items for a given module)

 

def getAlllineitems(mID,t):
    url = 'https://api.anaplan.com/2/0/models/'+mID+'/lineItems'
    header = {'Authorization':'AnaplanAuthToken ' + t,'Accept':'application/json','Content-Type': 'application/json'}
    response = requests.get(url, headers= header)
    return response.json()

 

mID = model ID

t = Token value 

 

Karan Kochhar

kevin.cho
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Hey @DaanishSoomar and @JaredDolich 

 

Take a look at this (draft) article that I had written Python and Anaplan: Pt 2—Anaplan Model Registry Ca... - Anaplan Community It's the next part in my series, but just awaiting review before publication. 

 

It has some sample code to generate an authentication token using your username and password, and also has a link to a great article by @scott.smith for generating the auth strings using a CA Certificate. 

 

To specifically retrieve all line items in a model and then turn it into a CSV, you can follow the below: 

 

import csv
import json
import requests

auth_token = ''
mdl_id = '' # insert your model ID here
lineitem_url = 'https://api.anaplan.com/2/0/models/{}/lineItems/'.format(mdl_id) 
#.format() method replaces each set of curly braces with the variables listed 

#define headers as a dict
request_headers = {}
request_headers['Authorization'] = 'AnaplanAuthToken ' + auth_token

#pass request headers through
lineitem_json = requests.get(lineitem_url, headers=request_headers).json()
#line item endpoint returns specific json schema, we want the object "items" which is a list of dict objects representing each individual line item
lineitem_dict = lineitem_json['items']

#converting to csv 
keys = lineitem_dict[0].keys() #get column headers as the keys per object
file_name = 'lineitems.csv'
with open(file_name, 'w', newline='') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(lineitem_dict)

 

DaanishSoomar
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

You are amazing @kevin.cho!

 

Just to validate my understanding. Below is the script I should utilize for transactional api and retrieving all line items in a model. 

However, before I also need another script that creates an auth token? 

So the order of operations would be:

 

1. Run script that generates auth token in a separate script that is used only for generating a token. 
2. Copy/paste that token into my desired script into the token variable line. 
3. Run that desired script.

 

Can you please confirm if I have the steps correctly? 

DaanishSoomar
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Also quick follow up, I copied and pasted the basic authentication script from the article that is still in review, I received this error message. I also made sure to swap in my username and password above (hid it for privacy)

 

DaanishSoomar_0-1627314427588.png

 

DaanishSoomar
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Figured it out! There is a typo in the referenced article, line 31. Correction in red. @kevin.cho 
 
# %% - this defines our Jupyter code cell (more on this below)
import requests # tells our Python interpreter that we will be using functions from the requests module
from base64 import b64encode # tells our Python interpreter that we will be using the b64encode function from the base64 module

# the authentication API takes the Base64 encoded format of a string with the value "email:password". 
# The function b64encode takes a "bytes-like object", hence the b that prepends the 'email:password' string. 
# The function b64encode ouputs a "bytes" object, but since we need it as a string, we can call the function .decode() on the result. 

user_pw = b64encode(b'email:password').decode() 

# To make our first API call, we need to define our headers. We first define a variable called auth_headers, with an empty dict object ({})

auth_headers = {} 

# We can then add a key called 'Authorization' to this dict.
# We set the value of this key to 'Basic <encoded_user_pw>'
auth_headers['Authorization'] = 'Basic ' + user_pw

# We need to define our request URL - in this case as we are trying to authenticate with the Anaplan API, it will be the authenticate URL. 


# Finally, we can make our first API call - the authentication API expects a POST method, so we use the function in our requests module called post. It expects at least the API endpoint URL, which we pass through as auth_url, and then we define the headers value as auth_headers. As we want to be able to interpret the response, we append the .json() to retrieve the response as a JSON. This is stored as a dict object in auth_json. 

auth_json = requests.post(auth_urlheaders=auth_headers).json()

# The token value (that we need for later calls) is in a key called 'tokenValue', which in turn is in an object called 'tokenInfo'. 
# We can reference the auth_request 

try:
    auth_token = auth_json['tokenInfo']['tokenValue']
    print(auth_token)
# If this key is not found, it means that the response is not in the expected structure, and we would get a KeyError. To error handle this, we can then print a friendly debug message. 
except KeyError:
    print('No Token Info found - check your credentials?')
kevin.cho
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Cheers @DaanishSoomar  for picking that up, there is indeed a typo! 

 

And yeah, you can consolidate it all into one script if you'd like. You can create a function like how Karan had done it, if you will be calling it multiple times. 

E.g.

def auth_token_basic(email, password):
    user_pw = b64encode(bytes(email+':'+password, 'utf-8'))
    auth_headers = {} 
    auth_headers['Authorization'] = 'Basic ' + user_pw
    auth_url = 'https://auth.anaplan.com/token/authenticate'
    auth_json = requests.post(auth_url, headers=auth_headers).json()
    try:
        auth_token = auth_json['tokenInfo']['tokenValue']
        return auth_token
    except KeyError:
        print('No Token Info found - check your credentials?')

 

You can then just call this function 

my_email = '...'
my_password = '...'
token = auth_token_basic(my_email, my_password)

 

Can do the same for the CSV script I gave before too 

View solution in original post

DaanishSoomar
Certified Master Anaplanner

Re: Help with Python API 2.0 & Transactional API

Thanks Kevin!