From e8ef36b9b1606af4aba6e1de4f75a9fcb4c042cb Mon Sep 17 00:00:00 2001 From: Marek Isalski Date: Mon, 18 Jun 2018 11:29:38 +0200 Subject: [PATCH] initial import --- fulcrmpy/__init__.py | 0 fulcrmpy/apiv2.py | 93 ++++++++++++++++++++++++++++++++++++++++++++ setup.py | 0 3 files changed, 93 insertions(+) create mode 100644 fulcrmpy/__init__.py create mode 100644 fulcrmpy/apiv2.py create mode 100644 setup.py diff --git a/fulcrmpy/__init__.py b/fulcrmpy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fulcrmpy/apiv2.py b/fulcrmpy/apiv2.py new file mode 100644 index 0000000..3c7e285 --- /dev/null +++ b/fulcrmpy/apiv2.py @@ -0,0 +1,93 @@ +import requests +import requests.exceptions +import json +import time + +class ApiKeyAuth( requests.auth.AuthBase ): + def __init__( self, api_username, api_key ): + self.api_username = api_username + self.api_key = api_key + + def __call__( self, r ): + r.headers[ 'Authorization' ] = "ApiKey %s:%s" % ( self.api_username, self.api_key ) + r.headers[ 'Content-Type' ] = "application/json" + r.headers[ 'Accept-Encoding' ] = "application/json" + return r + +class APIv2( object ): + def __init__( self, api_username, api_key, base = "https://fulcrm.org", api_path = "/api/v2" ): + self.api_username = api_username + self.api_key = api_key + self.api_path = api_path + self.base = base + self.auth = ApiKeyAuth( self.api_username, self.api_key ) + + def normalize_url( self, url, no_d = False, count = None ): + if not url.startswith( self.base ): + if not url.startswith( self.api_path ): + if not url.startswith( "/" ): + url = "/" + url + url = self.api_path + url + url = self.base + url + + if not no_d: + if "?" in url: + url = url + "&expand=d&count=" + str( count ) + else: + url = url + "?expand=d&count=" + str( count ) + + if count is not None: + if "?" in url: + url = url + "&count=" + str( count ) + else: + url = url + "?count=" + str( count ) + + + return url + + def make_request( self, url, data, method, _countdown = 5 ): + url = self.normalize_url( url ) + + method = { 'POST': requests.post, + 'PATCH': requests.patch, + 'GET': requests.get, + 'DELETE': requests.delete + }.get( method, requests.get ) + + try: + if data: + request = method( url, data = json.dumps( data ), auth = self.auth ) + else: + request = method( url, auth = self.auth ) + except requests.exceptions.ConnectionError: + if _countdown > 0: + time.sleep( 2 ** ( 5 - _countdown ) ) + return self.make_request( url, data, method, _countdown - 1 ) + else: + raise + if request.ok: + try: + return request.json() + except: + return None + else: + raise ValueError( request.text ) + + def get_one( self, url, no_d = False ): + return self.make_request( url, None, 'GET' ) + + def get_many( self, url, count = 10, no_d = False ): + next = None + url = self.normalize_url( url, no_d = no_d, count = count ) + + while True: + result = self.make_request( url, None, 'GET' ) + if 'results' in result: + for object in result[ 'results' ]: + yield object + if 'next' in result: + next = result.get( 'next', None ) + if next: + url = next + else: + return diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..e69de29