Use python to export report

Vin100
Vin100 Expensify Customer Posts: 3 Expensify Newcomer
edited March 2020 in Integrations and API

Hi,

I am using the following curl command with success:

curl -v POST 'https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations' -d 'requestJobDescription={
    "type":"file",
    "credentials":{
      "partnerUserID":"userid",
      "partnerUserSecret":"secret"
    },
    "onReceive":{
      "immediateResponse":["returnRandomFileName"]
    },
    "inputSettings":{
      "type":"combinedReportData",
      "filters":{
        "startDate":"2019-11-01",
        "endDate":"2020-03-22"
      }
    },
    "outputSettings":{
      "fileExtension":"json",
  "fileBasename":"myExport"
    }
  }'   --data-urlencode "template@exp3.ftl"  

This command is sending the following POST data:

0000: requestJobDescription={.    "type":"file",.    "credenti

0040: als":{.      "partnerUserID":"userid

0080: seil_com",.      "partnerUserSecret":"secret

00c0: ".    },.    "onReceive":{.     

0100:  "immediateResponse":["returnRandomFileName"].    },.   

0140:  "inputSettings":{.      "type":"combinedReportData",.  

0180:      "filters":{.        "startDate":"2019-11-01",.

01c0:         "endDate":"2020-03-22".      }.    },.

0200:     "outputSettings":{.      "fileExtension":"json",. 

0240:  "fileBasename":"myExport".    }.  }&template=%3C%23if%20

0280: addHeader%20%3D%3D%20true%3E%0A%20%20%20%20Merchant%2COriginal%2

02c0: 0Amount%2CCategory%2CReport%20number%2CExpense%20number%3C%23lt%

0300: 3E%0A%3C%2F%23if%3E%0A%3C%23assign%20reportNumber%20%3D%201%3E%0

0340: A%3C%23assign%20expenseNumber%20%3D%201%3E%0A%3C%23list%20report

0380: s%20as%20report%3E%0A%20%20%20%20%3C%23list%20report.transaction

03c0: List%20as%20expense%3E%0A%20%20%20%20%20%20%20%20%24%7Bexpense.m

0400: erchant%7D%2C%3C%23t%3E%0A%20%20%20%20%20%20%20%20%3C%23--%20not

0440: e%3A%20expense.amount%20prints%20the%20original%20amount%20only%

0480: 20--%3E%0A%20%20%20%20%20%20%20%20%24%7Bexpense.amount%7D%2C%3C%

04c0: 23t%3E%0A%20%20%20%20%20%20%20%20%24%7Bexpense.category%7D%2C%3C

0500: %23t%3E%0A%20%20%20%20%20%20%20%20%24%7BreportNumber%7D%2C%3C%23

0540: t%3E%0A%20%20%20%20%20%20%20%20%24%7BexpenseNumber%7D%3C%23lt%3E

0580: %0A%20%20%20%20%20%20%20%20%3C%23assign%20expenseNumber%20%3D%20

05c0: expenseNumber%20%2B%201%3E%0A%20%20%20%20%3C%2F%23list%3E%0A%20%

0600: 20%20%20%3C%23assign%20reportNumber%20%3D%20reportNumber%20%2B%2

0640: 01%3E%0A%3C%2F%23list%3E%0A


I am not able to reproduce the same thing with Python.

The nearest I am able to get is:

equestJobDescription=%7B%22type%22%3A+%22file%22%2C+%22credentials%22%3A+%7B%22partnerUserID%22%3A+%22userid%22%2C+%22partnerUserSecret%22%3A+%secret%22%7D%2C+%22onReceive%22%3A+%7B%22immediateResponse%22%3A+%5B%22returnRandomFileName%22%5D%7D%2C+%22inputSettings%22%3A+%7B%22type%22%3A+%22combinedReportData%22%2C+%22filter%22%3A+%7B%22startDate%22%3A+%222019-11-01%22%2C+%22endDate%22%3A+%222020-03-22%22%7D%7D%2C+%22outputSettings%22%3A+%7B%22fileExtension%22%3A+%22json%22%7D%7D&template=%3C%23if+addHeader+%3D%3D+true%3EMerchant%2COriginal+Amount%2CCategory%2CReport+number%2CExpense+number%3C%23lt%3E%3C%2F%23if%3E%3C%23assign+reportNumber+%3D+1%3E%3C%23assign+expenseNumber+%3D+1%3E%3C%23list+reports+as+report%3E%3C%23list+report.transactionList+as+expense%3E%24%7Bexpense.merchant%7D%2C%3C%23t%3E%3C%23--+note%3A+expense.amount+prints+the+original+amount+only+--%3E%24%7Bexpense.amount%7D%2C%3C%23t%3E%24%7Bexpense.category%7D%2C%3C%23t%3E%24%7BreportNumber%7D%2C%3C%23t%3E%24%7BexpenseNumber%7D%3C%23lt%3E%3C%23assign+expenseNumber+%3D+expenseNumber+%2B+1%3E%3C%2F%23list%3E%3C%23assign+reportNumber+%3D+reportNumber+%2B+1%3E%3C%2F%23list%3E

I have the following error:

{'responseMessage': 'Error while parsing job description', 'responseCode': 500}

The only difference is that the first part is URL encoded.

Here is my Python code:

_export_template2 = "<#if addHeader == true>Merchant,Original Amount,Category,Report number,Expense number<#lt></#if><#assign reportNumber = 1><#assign expenseNumber = 1><#list reports as report><#list report.transactionList as expense>${expense.merchant},<#t><#-- note: expense.amount prints the original amount only -->${expense.amount},<#t>${expense.category},<#t>${reportNumber},<#t>${expenseNumber}<#lt><#assign expenseNumber = expenseNumber + 1></#list><#assign reportNumber = reportNumber + 1></#list>"

    JobDescription_exporter = {"requestJobDescription": json.dumps({
        "type": "file",
        "credentials": {
            "partnerUserID": _partnerUserID,
            "partnerUserSecret": _partnerUserSecret
        },
        "onReceive":{
            "immediateResponse":["returnRandomFileName"]
        },
        "inputSettings": {
            "type": "combinedReportData",
            "filter": {
                "startDate": "2019-11-01",
                "endDate": "2020-03-22"
            }
        },
        "outputSettings": {
            "fileExtension": "json"
        }
        })
    }
    # This is to combine the job description and template in one dict.
    post_data = {**JobDescription_exporter,**{"template":_export_template3}}
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    result = requests.post(self._base_url, data=post_data, headers=headers)

    print("header:      ",result.request.headers)
    print("data:        ",post_data)
    print("body:        ",result.request.body)
    print("status_code: ",result.status_code)
    print("result:      ",result.json())


It seems the first JSON part (requestJobDescription) must be sent without encoding, but the second part (template), must be sent with encoding.

Answers