Kuinran

Modified __init__.py for Trackvia Python SDK

Jun 5th, 2019
142
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #/usr/bin/python
  2. import urllib
  3. import httplib2
  4. import requests
  5. import json
  6. import sys
  7. import threading
  8. import signal
  9.  
  10. # Modified by Jarrett for using authentication keys to bypass login as well as use in Python3 since urllib is implemented differently
  11.  
  12. class trackvia:
  13.     """Class that wraps the TrackVia API. This client handles the initial Oauth authentication as well as refreshing the token before expiration."""
  14.  
  15.     def __init__(self, url, username, password, apikey, auth_key=None):
  16.         """This is a constructor for the TrackVia client."""
  17.  
  18.         #Register a method to handle signals and close our threads cleanly. Only if part of main thread
  19.         if __name__ == "__main__":
  20.             signal.signal(signal.SIGINT, self.__signal_handler)
  21.  
  22.         self.base_url=url
  23.         self.apikey=apikey
  24.  
  25.         #Login information
  26.         values = { 'grant_type' : 'password',
  27.                 'client_id' : 'TrackViaAPI',
  28.                 'username' : username,
  29.                 'password' : password}
  30.  
  31.         if values['username'] is not None and values['password'] is not None:
  32.             #Actually do the login and parse the token from the response.
  33.             resp,body=self.__json_request("{0}/oauth/token".format(self.base_url),post=values)
  34.  
  35.             if resp["status"] is 200:
  36.                 self.token=body['value']
  37.                 self.refreshToken=body['refreshToken']
  38.                 self.expiresIn=body['expires_in']
  39.  
  40.                 #Get the account ID that we are dealing with here
  41.                 get_values= {'access_token' : self.token}
  42.                 resp,body=self.__json_request("{0}/users".format(self.base_url), type="GET", get=get_values)
  43.                 self.account_id=body['accounts'][0]['id']
  44.  
  45.             else:
  46.                 # print("Key auth failed api_file_l34")
  47.                 if auth_key is not None:
  48.                     self.token=auth_key
  49.                     self.refreshToken=None
  50.                 else:
  51.                     raise Exception('Login to Trackvia failed and no Authentication Token was provided')
  52.  
  53.         if hasattr(self, "expiresIn") and self.refreshToken is not None:
  54.             #Schedule a oauth_token refresh 15s before it expires
  55.             self.thread=threading.Timer(self.expiresIn-15, self.__refresh_token)
  56.             self.thread.daemon = True
  57.             self.thread.start()
  58.  
  59.     # This is a helper class to make requests to the trackvia API
  60.     def __json_request(self,url,type="POST",post=None,get=None,content_type="urlencode"):
  61.         """This method is used internally for sending requests to the API."""
  62.         if post == None:
  63.             post_data=None
  64.         else:
  65.             try:
  66.                 post_data = urllib.parse.urlencode(post)
  67.             except:
  68.                 print("Failed to encode body (" + sys.exc_info()[0] + ")")
  69.  
  70.         #Convert get params to be used in the URL
  71.         if get == None:
  72.             get_data=""
  73.         else:
  74.             get_list=[]
  75.             for element in get.keys():
  76.                 get_list.append(urllib.parse.quote_plus(element)+"="+urllib.parse.quote_plus(str(get[element])))
  77.             get_data="?"+'&'.join(get_list)
  78.  
  79.         if content_type=="json":
  80.             headers={'Content-Type': 'application/json; charset=UTF-8'}
  81.         else:
  82.             headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
  83.  
  84.         h = httplib2.Http()
  85.  
  86.         response, content = h.request(url+get_data,type,headers=headers,body=json.dumps(post))
  87.        
  88.         try:
  89.             body=json.loads(content)
  90.         except ValueError as e:
  91.             body=content
  92.  
  93.         return response,body
  94.  
  95.     # It is much cleaner to upload multipart files using the Requests framework.
  96.     def __post_file(self, url, data, file):
  97.         r = requests.post(url,params=data,files=file)
  98.         return r.status_code, r.content
  99.  
  100.     def __refresh_token(self):
  101.         """This method is used internally to refresh the oauth token."""
  102.         #Login information
  103.         values = { 'grant_type' : 'refresh_token',
  104.                 'client_id' : 'TrackViaAPI',
  105.                 'refresh_token' : self.refreshToken['value']}
  106.  
  107.         #Actually do the login and parse the token from the response.
  108.         resp,body=self.__json_request("{0}/oauth/token".format(self.base_url),type="POST",post=values)
  109.         self.token=body['value']
  110.         self.refreshToken=body['refreshToken']
  111.         self.expiresIn=body['expires_in']
  112.  
  113.         self.thread=threading.Timer(self.expiresIn-15, self.__refresh_token)
  114.         self.thread.daemon = True
  115.         self.thread.start()
  116.  
  117.     def get_all_apps(self):
  118.         """Returns all apps for the logged in account."""
  119.         get_values={"access_token" : self.token,
  120.                 "user_key" : self.apikey}
  121.         resp,body=self.__json_request("{0}/openapi/apps".format(self.base_url),type='GET', get=get_values)
  122.         return resp,body
  123.  
  124.     def get_all_views(self):
  125.         """Returns all views for the logged in account."""
  126.         get_values={"access_token" : self.token,
  127.                 "user_key" : self.apikey}
  128.         resp,body=self.__json_request("{0}/openapi/views".format(self.base_url),type='GET', get=get_values)
  129.         return resp,body
  130.  
  131.     def get_view(self,viewId):
  132.         """Returns a specific view by the viewId."""
  133.         get_values={"access_token" : self.token,
  134.                 "user_key" : self.apikey,
  135.                 "viewId" : viewId }
  136.         resp,body=self.__json_request("{0}/openapi/views/{1}".format(self.base_url,viewId),type='GET', get=get_values)
  137.         return resp,body
  138.  
  139.     def find_records(self,viewId,query,start=0,max=50):
  140.         """Search for records in a view."""
  141.         get_values={"access_token" : self.token,
  142.                 "user_key" : self.apikey,
  143.                 "viewId" : viewId,
  144.                 "q" : query,
  145.                 "start": start,
  146.                 "max": max }
  147.         resp,body=self.__json_request("{0}/openapi/views/{1}/find".format(self.base_url, viewId),type='GET', get=get_values)
  148.         return resp,body
  149.  
  150.     def get_all_records(self,viewId,start=0,max=50):
  151.         """Returns all records within a view, from start to max."""
  152.         get_values={"access_token" : self.token,
  153.                 "user_key" : self.apikey,
  154.                 "viewId" : viewId,
  155.                 "q" : "",
  156.                 "start": start,
  157.                 "max":  max }
  158.         resp,body=self.__json_request("{0}/openapi/views/{1}/find".format(self.base_url, viewId),type='GET', get=get_values)
  159.         return resp,body
  160.  
  161.     def get_record(self,viewId,recordId):
  162.         """Returns a specific record from a view."""
  163.         get_values={"access_token" : self.token,
  164.                 "user_key" : self.apikey,
  165.                 "viewId" : viewId,
  166.                 "recordId" : recordId }
  167.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/{2}".format(self.base_url, viewId, recordId),type='GET', get=get_values)
  168.  
  169.         return resp,body
  170.  
  171.     def delete_record(self,viewId,recordId):
  172.         """Deletes a record in a view."""
  173.         get_values={"access_token" : self.token,
  174.                 "user_key" : self.apikey,
  175.                 "viewId" : viewId,
  176.                 "recordId" : recordId }
  177.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/{2}".format(self.base_url, viewId, recordId),type='DELETE', get=get_values)
  178.         return resp,body
  179.  
  180.     def delete_file(self, viewId, recordId, fieldName):
  181.         """Deletes a file from a field in a view."""
  182.         get_values={"access_token" : self.token,
  183.                 "user_key" : self.apikey,
  184.                 "viewId" : viewId,
  185.                 "recordId" : recordId }
  186.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/{2}/files/{3}".format(self.base_url, viewId, recordId, fieldName),type='DELETE', get=get_values)
  187.         return resp,body
  188.  
  189.     def get_file(self, viewId, recordId, fieldName):
  190.         """Returns a file from a field in a view."""
  191.         get_values={"access_token" : self.token,
  192.                 "user_key" : self.apikey,
  193.                 "viewId" : viewId,
  194.                 "recordId" : recordId }
  195.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/{2}/files/{3}".format(self.base_url, viewId, recordId, fieldName),type='GET', get=get_values)
  196.         return resp,body
  197.  
  198.     def attach_file(self, viewId, recordId, fieldName, file):
  199.         """Attaches a file to a record"""
  200.         get_values={"access_token" : self.token,
  201.                 "user_key" : self.apikey,
  202.                 "viewId" : viewId,
  203.                 "recordId" : recordId }
  204.         file={'file':open(file,'r')}
  205.         resp,body=self.__post_file("{0}/openapi/views/{1}/records/{2}/files/{3}".format(self.base_url, viewId, recordId, fieldName),get_values,file)
  206.         return resp,body
  207.  
  208.     def create_record(self, viewId, data):
  209.         """Creates a record in a view"""
  210.         post_data={"data":data}
  211.         get_values={"access_token" : self.token,
  212.                 "user_key" : self.apikey,
  213.                 "viewId" : viewId }
  214.         resp,body=self.__json_request("{0}/openapi/views/{1}/records".format(self.base_url, viewId),type='POST', post=post_data, get=get_values, content_type="json")
  215.  
  216.         return resp,body
  217.  
  218.     def update_record(self, viewId,  recordId, data):
  219.         """Updates a record in a view"""
  220.         post_data={"data":data}
  221.         get_values={"access_token" : self.token,
  222.                 "user_key" : self.apikey,
  223.                 "viewId" : viewId }
  224.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/{2}".format(self.base_url, viewId, recordId),type='PUT', post=post_data, get=get_values, content_type="json")
  225.  
  226.         return resp,body
  227.  
  228.     def delete_record(self, viewId, recordId):
  229.         """Deletes a record from a view"""
  230.         get_values={"access_token" : self.token,
  231.                 "user_key" : self.apikey,
  232.                 "viewId" : viewId,
  233.                 "recordId" : recordId }
  234.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/{2}".format(self.base_url, viewId, recordId),type="DELETE",get=get_values)
  235.         return resp,body
  236.  
  237.    
  238.     def delete_all_records(self, viewId):
  239.         """Deletes all records from a view"""
  240.         get_values={"access_token" : self.token,
  241.                 "user_key" : self.apikey,
  242.                 "viewId" : viewId}
  243.         resp,body=self.__json_request("{0}/openapi/views/{1}/records/all".format(self.base_url, viewId),type="DELETE",get=get_values)
  244.         return resp,body
  245.  
  246.  
  247.     def get_users(self,start=0,max=50):
  248.         """Gets users in the account"""
  249.         get_values={"access_token" : self.token,
  250.                 "user_key" : self.apikey,
  251.                 "start" : start,
  252.                 "max" : max }
  253.         resp,body=self.__json_request("{0}/openapi/users".format(self.base_url),type="GET",get=get_values)
  254.         return resp,body
  255.  
  256.     def create_user(self,email,firstName,lastName,timeZone):
  257.         """Creates a user"""
  258.         get_values={"access_token" : self.token,
  259.                 "user_key" : self.apikey,
  260.                 "email" : email,
  261.                 "firstName" : firstName,
  262.                 "lastName" : lastName,
  263.                 "timeZone" : timeZone }
  264.         resp,body=self.__json_request("{0}/openapi/users".format(self.base_url),type="POST",get=get_values)
  265.         return resp,body
  266.  
  267.     def __signal_handler(self, signal, frame):
  268.         """Internal method for handling signals."""
  269.         print("Caught Signal: {0}".format(signal) )
  270.         self.stop()
  271.         sys.exit(0)
  272.  
  273.     def stop(self):
  274.         """Cleanly stop the client and kill the oauth token refresh thread."""
  275.         print("Stopping client")
  276.         self.thread.cancel()
RAW Paste Data