API with Python

Options
mikecaputozi
mikecaputozi Expensify Customer Posts: 3 Expensify Newcomer

I'm trying to build an integration to update employees' managers using the Expensify API with Python. I need to know how to attach the CSV file containing the employees to be updated. I see how to do it with curl, but I can't quite figure out how to translate that to Python. Should it be another key in the JSON data? If so, what's the key name?

Here is the Python code I have so far:

import requests as req

import json

import csv


class Expensify:

    apiurl = "https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations"

  user = "..."

  secret = "..."

  policyid = "..."


  def getbasemessage(self, action="update", objecttype="employees") -> dict:

    base = {

      "requestJobDescription": {

        "type": action,

        "credentials": {

          "partnerUserID": self.user,

          "partnerUserSecret": self.secret

        },

        "inputSettings": {

          "type": objecttype,

          "policyID": self.policyid,

          "fileType": "csv"

        }

      }

    }


    return base


  def sendmessage(self, msg):

    result = req.post(self.apiurl, data=json.dumps(msg), headers="Expect:")

    return result


  def usermanagerupdate(self, employeeemail, manageremail):

    msg = self.getbasemessage()

    d = {

      "EmployeeEmail": employeeemail,

      "ManagerEmail": manageremail,

      "Admin": False

    }

    with open("temp.csv", "w") as f:

      w = csv.DictWriter(f, d.keys())

      w.writeheader()

      w.writerow(d)


    # How do I get the file in here?

    self.sendmessage(msg)

Tagged:

Answers

  • mikecaputozi
    mikecaputozi Expensify Customer Posts: 3 Expensify Newcomer
    Options

    In case anyone is interested, I was able to figure this out with the help of a colleague. Here is the updated code. Note that the isAdmin function is new but not related to the solution to my original issue; it's there because the Admin field is required but I don't know of a way to query the API to find out if the user is actually an admin. So I had to create a file that lists all existing admins in order to avoid overwriting that property incorrectly.


    import requests as req

    import json

    import csv

    import os


    class Expensify:

        APIURL = "https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations"

        USER = "..."

        SECRET = "..."

        POLICYID = "..."

        TEMPFILE = "temp.csv"

        ADMINFILE = "admins.txt"

        

        def getbasemessage(self, action="update", objecttype="employees") -> dict:

            base = {

                "type": action,

                "credentials": {

                    "partnerUserID": self.USER,

                    "partnerUserSecret": self.SECRET

                },

                "inputSettings": {

                    "type": objecttype,

                    "policyID": self.POLICYID,

                    "fileType": "csv"

                }

            }

            return base

        

        def sendmessage(self, msg):

            output = []

            data = {

                "requestJobDescription": json.dumps(msg, indent=4),

            }

            files = {

                "data": (self.TEMPFILE, open(self.TEMPFILE, "r")),

            }

            result = req.post(self.APIURL, data=data, files=files, timeout=60)

            

            return result

     

        def employeemanagerupdate(self, employeeemail, manageremail):

            msg = self.getbasemessage()

            d = {

                "EmployeeEmail": employeeemail,

                "ManagerEmail": manageremail,

                "Admin": self.isAdmin(employeeemail)

            }

            with open(self.TEMPFILE, "w", newline="") as f:

                w = csv.DictWriter(f, d.keys())

                w.writeheader()

                w.writerow(d)

                  

            result = self.sendmessage(msg)

            os.remove(self.TEMPFILE)

            

            return result

        

        def isAdmin(self, email) -> bool:

            with open(self.ADMINFILE, "r") as a:

                admins = a.readlines()

                

            admin = False

            if email in admins:

                admin = True

                

            return admin