--- title: "Python" slug: "python" updated: 2025-12-05T10:46:11Z published: 2025-12-05T10:46:11Z canonical: "docs.mapp.com/python" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.mapp.com/llms.txt > Use this file to discover all available pages before exploring further. # Python > Before using our Analytics API, you need to be given access. Learn more about how to do this [here](/v1-api/apidocs/how-to-grant-access-to-the-intelligence-analytics-api). ## Install Tablib You will need to install Tablib for the example below, a very lightweight library for managing various data file types. You can install Tablib with xlsx support by running both of these commands: - pip install tablib - pip install tablib[xlsx] The code also uses standard libraries for JSON and requests, which will be present in the latest python versions. ## Check for statusUrl vs. resultUrl When making a call to create a calculation, the response may contain an element of either (**but not both**) of the following: - resultUrl - this means that the calculation is already done, and you can call the URL here to get the data. - statusUrl - this means that we are waiting for a result, and need to check back later by calling the statusUrl. - As soon as the result is ready, you will get the resultUrl element returned. The example below converts the response text to a Python dictionary, and hence looking up an element can throw an exception. Using try...except when retrieving an element from the dictionary will protect against problems. > Please be sure that you have the correct upper and lower limit set. When you copy the JSON from Mapp Intelligence, the upper limit will stay the same as it is onsite. If you would like to increase it, you can either change it before you copy the JSON or after in the JSON itself. Mapp can produce results with 5 million rows, but limits may apply depending on your consuming system (e.g. excel). In Python, this is the "upperLimit" value. Here is this example as a file: [AnalyticsAPItoExcel.py](https://cdn.document360.io/554b9b98-6720-4d8b-9919-c7b203d72648/Images/Documentation/AnalyticsAPItoExcel.py) ```python import json         # standard import requests     # standard import time         # standard import tablib       # see https://pypi.org/project/tablib/ # credentials (add your own here) user = 'XXX' secret = 'YYY' baseurl = 'https://intelligence.eu.mapp.com' # connect and authorize url = baseurl + "/analytics/api/oauth/token" querystring = {"grant_type":"client_credentials","scope":"mapp.intelligence-api"} try:    response = requests.request("POST", url, auth=(user,secret), params=querystring) except:    print("failed to connect and authorize")    exit() # something went wrong if response.status_code != 200:    print("Autorization returned - ", response)    exit() # get the token (make a dictionary using json, then extract the actual token) values = json.loads(response.text) token = values["access_token"] # we can now build a "Create Calculation" call adding the token to the headers url = baseurl + "/analytics/api/analysis-query" headers = {'Authorization': 'Bearer ' + token,           'Content-Type': "application/json"} # the json payload - the query we are trying to run # this can be retrieved from the 'copy JSON' menu in Intelligence payload="{\r\n    \"resultType\": \"DATA_ONLY\",\r\n    \"queryObject\": {\r\n        \"columns\": [\r\n            {\r\n                \"name\": \"session_id\",\r\n                \"scope\": \"OBJECT\",\r\n                \"context\": \"SESSION\",\r\n                \"variant\": \"NORMAL\",\r\n                \"lowerLimit\": 1,\r\n                \"upperLimit\": 500\r\n            },\r\n            {\r\n                \"name\": \"pages_pageImpressions\",\r\n                \"columnPeriod\": \"ANALYSIS\",\r\n                \"scope\": \"OBJECT\",\r\n                \"context\": \"PAGE\",\r\n                \"variant\": \"NORMAL\"\r\n            },\r\n            {\r\n                \"name\": \"order_value\",\r\n                \"columnPeriod\": \"ANALYSIS\",\r\n                \"scope\": \"OBJECT\",\r\n                \"context\": \"ACTION\",\r\n                \"variant\": \"NORMAL\"\r\n            }\r\n        ],\r\n        \"variant\": \"LIST\",\r\n        \"predefinedContainer\": {\r\n            \"filters\": [\r\n                {\r\n                    \"name\": \"time_dynamic\",\r\n                    \"filterPredicate\": \"LIKE\",\r\n                    \"connector\": \"AND\",\r\n                    \"caseSensitive\": false,\r\n                    \"context\": \"NONE\",\r\n                    \"intern\": false,\r\n                    \"value1\": \"last_90_days\",\r\n                    \"value2\": \"\"\r\n                }\r\n            ],\r\n            \"containers\": []\r\n        }\r\n    }\r\n}" # request the query # - if the response contains "resultUrl" then it's complete already # - if the response contains "statusUrl" then we need to call that to check back when it is finished try:    response = requests.request("POST", url, data=payload, headers=headers) except:    # something went wrong    print("Create calculation call failed")    exit() # something went wrong if response.status_code > 201:    print("Create Calculation returned - ", response)    exit() # unpack the response values = json.loads(response.text) try:    resultUrl = values["resultUrl"] except:    resultUrl = "" try:    statusUrl = values["statusUrl"] except:    statusUrl = "" # now we can call for the result... tries = 0 while True:    try:        if resultUrl != "":            # we have a result already, just retrieve it and exit the loop            response = requests.request("GET", resultUrl, headers=headers)            break        else:            # wait for a short time (optional)            sleep(1)            # is it done yet?            # call the status URL, and refresh the values of the URLs            response = requests.request("GET", statusUrl, headers=headers)            values = json.loads(response.text)                          try:                resultUrl = values["resultUrl"]            except:                resultUrl = ""                      tries +=1    except:        print("failed to fetch the result")    # give up after trying an arbitrary number of times    if tries == 10:        print("tried several times, didn't get result")        exit() # you will need to install tablib for this example # - pip install tablib (see https://pypi.org/project/tablib/) # ...create a tablib data set to build excel file ds = tablib.Dataset() # convert string into a python dictionary data = json.loads(response.text) # walk through headers headers = [] for item in data["headers"]:    headers.append(item["alias"]) # add the headers we just retrieved to the data set ds.headers = headers # walk through the rows for item in data["rows"]:    # build a tuple for each row    tuple = []    for row in item:        tuple.append(row)    # add the row to the data set    ds.append(tuple) # write it as an excel file with open('results.xlsx', 'wb') as f:    f.write(ds.xlsx)    f.close()                       ```