From 323eff469b330e6662ba968a29b43695a807d95f Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari <74908943+Hrishabh17@users.noreply.github.com> Date: Mon, 4 Mar 2024 19:58:30 +0530 Subject: [PATCH] Added generator for the get calls (#23) * Added generator for the get calls * fixed the loop terminate --- qbosdk/apis/accounts.py | 8 +++++ qbosdk/apis/api_base.py | 54 +++++++++++++++++++++++++++++++++- qbosdk/apis/attachments.py | 7 +++++ qbosdk/apis/bill_payments.py | 7 +++++ qbosdk/apis/bills.py | 7 +++++ qbosdk/apis/classes.py | 8 +++++ qbosdk/apis/customers.py | 8 +++++ qbosdk/apis/departments.py | 8 +++++ qbosdk/apis/employees.py | 8 +++++ qbosdk/apis/exchange_rates.py | 12 ++++++++ qbosdk/apis/items.py | 8 +++++ qbosdk/apis/journal_entries.py | 7 +++++ qbosdk/apis/purchases.py | 7 +++++ qbosdk/apis/tax_codes.py | 8 +++++ qbosdk/apis/tax_rates.py | 7 +++++ qbosdk/apis/vendors.py | 8 +++++ setup.py | 2 +- 17 files changed, 172 insertions(+), 2 deletions(-) diff --git a/qbosdk/apis/accounts.py b/qbosdk/apis/accounts.py index 7eec0b8..578a74f 100644 --- a/qbosdk/apis/accounts.py +++ b/qbosdk/apis/accounts.py @@ -16,3 +16,11 @@ def get(self): List with dicts in Accounts schema. """ return self._query_get_all('Account', Accounts.GET_ACCOUNTS) + + def get_all_generator(self): + """Get a generator of all the existing Accounts in the Organization. + + Returns: + Generator with dicts in Accounts schema. + """ + return self._query_get_all_generator('Account', Accounts.GET_ACCOUNTS) diff --git a/qbosdk/apis/api_base.py b/qbosdk/apis/api_base.py index 2aa792d..d4690a4 100644 --- a/qbosdk/apis/api_base.py +++ b/qbosdk/apis/api_base.py @@ -2,7 +2,7 @@ API Base class with util functions """ import json -from typing import List, Dict +from typing import List, Dict, Generator import requests @@ -86,6 +86,58 @@ def _query_get_all(self, object_type: str, url: str) -> List[Dict]: raise QuickbooksOnlineSDKError('Error: {0}'.format(response.status_code), response.text) + def _query_get_all_generator(self, object_type: str, url: str) -> Generator[Dict, None, None]: + """ + Gets all the objects of a particular type for query type GET calls + :param url: GET URL of object + :param object_type: type of object + :return: list of objects + """ + start_position = 1 + + request_url = '{0}{1}'.format(self.__server_url, url) + + api_headers = { + 'Authorization': 'Bearer {0}'.format(self.__access_token), + 'Accept': 'application/json' + } + + while True: + try: + response = requests.get(url=request_url.format(start_position), headers=api_headers) + response.raise_for_status() + + data = json.loads(response.text) + query_response = data['QueryResponse'] + + if not query_response[object_type]: + break + + for obj in query_response[object_type]: + yield obj + + start_position += 1000 + + except requests.exceptions.HTTPError as err: + if err.response.status_code == 400: + raise WrongParamsError('Some of the parameters are wrong', err.response.text) + + if err.response.status_code == 401: + raise InvalidTokenError('Invalid token, try to refresh it', err.response.text) + + if err.response.status_code == 403: + raise NoPrivilegeError('Forbidden, the user has insufficient privilege', err.response.text) + + if err.response.status_code == 404: + raise NotFoundItemError('Not found item with ID', err.response.text) + + if err.response.status_code == 498: + raise ExpiredTokenError('Expired token, try to refresh it', err.responseesponse.text) + + if err.response.status_code == 500: + raise InternalServerError('Internal server error', err.response.text) + + raise QuickbooksOnlineSDKError('Error: {0}'.format(err.response.status_code), err.response.text) def _query(self, url: str) -> List[Dict]: """ diff --git a/qbosdk/apis/attachments.py b/qbosdk/apis/attachments.py index cf55511..19cbc45 100644 --- a/qbosdk/apis/attachments.py +++ b/qbosdk/apis/attachments.py @@ -22,6 +22,13 @@ def get(self): """ return self._query_get_all('Attachable', Attachments.GET_ATTACHABLES) + def get_all_generator(self): + """ + Get all Attachables + :return: Generator with Dicts in Attachable Schema + """ + return self._query_get_all_generator('Attachable', Attachments.GET_ATTACHABLES) + def post(self, ref_id: str, ref_type: str, content, file_name): """ Post Attachable (check, etc) to Quickbooks Online diff --git a/qbosdk/apis/bill_payments.py b/qbosdk/apis/bill_payments.py index 6e817ba..3680fe6 100644 --- a/qbosdk/apis/bill_payments.py +++ b/qbosdk/apis/bill_payments.py @@ -19,6 +19,13 @@ def get(self): """ return self._query_get_all('BillPayment', BillPayments.GET_BILLS) + def get_all_generator(self): + """ + Get all Bill Payments + :return: Generator of Dicts in Bill Payment Schema + """ + return self._query_get_all_generator('BillPayment', BillPayments.GET_BILLS) + def post(self, data: Dict): """ Post Bill Payment to Quickbooks Online diff --git a/qbosdk/apis/bills.py b/qbosdk/apis/bills.py index d9e94e3..c54a81a 100644 --- a/qbosdk/apis/bills.py +++ b/qbosdk/apis/bills.py @@ -20,6 +20,13 @@ def get(self): """ return self._query_get_all('Bill', Bills.GET_BILLS) + def get_all_generator(self): + """ + Get all Bills + :return: Generator with Dicts in Bill Schema + """ + return self._query_get_all_generator('Bill', Bills.GET_BILLS) + def post(self, data: Dict): """ Post Bill to Quickbooks Online diff --git a/qbosdk/apis/classes.py b/qbosdk/apis/classes.py index 92bc4f0..5c62d2d 100644 --- a/qbosdk/apis/classes.py +++ b/qbosdk/apis/classes.py @@ -16,3 +16,11 @@ def get(self): List with dicts in Classes schema. """ return self._query_get_all('Class', Classes.GET_CLASSES) + + def get_all_generator(self): + """Get a list of the existing Classes in the Organization. + + Returns: + Generator with dicts in Classes schema. + """ + return self._query_get_all_generator('Class', Classes.GET_CLASSES) diff --git a/qbosdk/apis/customers.py b/qbosdk/apis/customers.py index 5c12641..5ffc0b2 100644 --- a/qbosdk/apis/customers.py +++ b/qbosdk/apis/customers.py @@ -18,6 +18,14 @@ def get(self): """ return self._query_get_all('Customer', Customers.GET_CUSTOMERS) + def get_all_generator(self): + """Get a list of the existing Customers in the Organization. + + Returns: + Generator with dicts in Customers schema. + """ + return self._query_get_all_generator('Customer', Customers.GET_CUSTOMERS) + def count(self): """Get count of Customers in the Organization. diff --git a/qbosdk/apis/departments.py b/qbosdk/apis/departments.py index f0024f9..2f09daf 100644 --- a/qbosdk/apis/departments.py +++ b/qbosdk/apis/departments.py @@ -16,3 +16,11 @@ def get(self): List with dicts in Departments schema. """ return self._query_get_all('Department', Departments.GET_DEPARTMENTS) + + def get_all_generator(self): + """Get a list of the existing Departments in the Organization. + + Returns: + Generator with dicts in Departments schema. + """ + return self._query_get_all_generator('Department', Departments.GET_DEPARTMENTS) diff --git a/qbosdk/apis/employees.py b/qbosdk/apis/employees.py index 8c17f2f..deb9a2d 100644 --- a/qbosdk/apis/employees.py +++ b/qbosdk/apis/employees.py @@ -20,6 +20,14 @@ def get(self): """ return self._query_get_all('Employee', Employees.GET_EMPLOYEES) + def get_all_generator(self): + """Get a list of the existing Employees in the Organization. + + Returns: + Generator with dicts in Employees schema. + """ + return self._query_get_all_generator('Employee', Employees.GET_EMPLOYEES) + def post(self, data: Dict): """ Post Employee to Quickbooks Online diff --git a/qbosdk/apis/exchange_rates.py b/qbosdk/apis/exchange_rates.py index 1f8330d..10970a0 100644 --- a/qbosdk/apis/exchange_rates.py +++ b/qbosdk/apis/exchange_rates.py @@ -24,6 +24,18 @@ def get(self, as_of_date: str = None): ExchangeRates.GET_EXCHANGE_RATES = ExchangeRates.GET_EXCHANGE_RATES.format(as_of_date, '{0}') return self._query_get_all('ExchangeRate', ExchangeRates.GET_EXCHANGE_RATES) + def get_all_generator(self, as_of_date: str = None): + """ + Get all the exchange rates + :param as_of_date: date to get rates for (1 day prior if left empty) + :return: List of Dicts for exchange rates + """ + if not as_of_date: + as_of_date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + + ExchangeRates.GET_EXCHANGE_RATES = ExchangeRates.GET_EXCHANGE_RATES.format(as_of_date, '{0}') + return self._query_get_all_generator('ExchangeRate', ExchangeRates.GET_EXCHANGE_RATES) + def get_by_source(self, source_currency_code: str): """ Get all the exchange rates diff --git a/qbosdk/apis/items.py b/qbosdk/apis/items.py index 747328e..8499c9c 100644 --- a/qbosdk/apis/items.py +++ b/qbosdk/apis/items.py @@ -17,3 +17,11 @@ def get(self): List with dicts in Items schema. """ return self._query_get_all('Item', Items.GET_ITEMS) + + def get_all_generator(self): + """Get a list of the existing items in the Organization. + + Returns: + Generator with dicts in Items schema. + """ + return self._query_get_all_generator('Item', Items.GET_ITEMS) diff --git a/qbosdk/apis/journal_entries.py b/qbosdk/apis/journal_entries.py index 32541ae..9b734c4 100644 --- a/qbosdk/apis/journal_entries.py +++ b/qbosdk/apis/journal_entries.py @@ -19,6 +19,13 @@ def get(self): """ return self._query_get_all('JournalEntry', JournalEntries.GET_JOURNAL_ENTRIES) + def get_all_generator(self): + """ + Get all JournalEntries + :return: Generator with Dicts in JournalEntry Schema + """ + return self._query_get_all_generator('JournalEntry', JournalEntries.GET_JOURNAL_ENTRIES) + def post(self, data: Dict): """ Post JournalEntry to Quickbooks Online diff --git a/qbosdk/apis/purchases.py b/qbosdk/apis/purchases.py index 1208b57..59d79e7 100644 --- a/qbosdk/apis/purchases.py +++ b/qbosdk/apis/purchases.py @@ -19,6 +19,13 @@ def get(self): """ return self._query_get_all('Purchase', Purchases.GET_PURCHASES) + def get_all_generator(self): + """ + Get all Purchases + :return: Generator with Dicts in Purchase Schema + """ + return self._query_get_all_generator('Purchase', Purchases.GET_PURCHASES) + def post(self, data: Dict): """ Post Purchase (check, etc) to Quickbooks Online diff --git a/qbosdk/apis/tax_codes.py b/qbosdk/apis/tax_codes.py index d236e11..c0b0d80 100644 --- a/qbosdk/apis/tax_codes.py +++ b/qbosdk/apis/tax_codes.py @@ -16,3 +16,11 @@ def get(self): Dict in TaxCode schema. """ return self._query_get_all('TaxCode', TaxCodes.GET_TAX_CODES) + + def get_all_generator(self): + """Get a list of the existing Tax Code in the Organization. + + Returns: + Generator with dicts in TaxCode schema. + """ + return self._query_get_all_generator('TaxCode', TaxCodes.GET_TAX_CODES) diff --git a/qbosdk/apis/tax_rates.py b/qbosdk/apis/tax_rates.py index 193fe23..ef3069c 100644 --- a/qbosdk/apis/tax_rates.py +++ b/qbosdk/apis/tax_rates.py @@ -17,6 +17,13 @@ def get(self): """ return self._query_get_all('TaxRate', TaxRates.GET_TAX_RATES) + def get_all_generator(self): + """ + Get all Taxrates + :return: Generator of Dicts in Taxrates Schema + """ + return self._query_get_all_generator('TaxRate', TaxRates.GET_TAX_RATES) + def get_by_id(self, taxrateId: str): """ Get Taxrates from Quickbooks Online diff --git a/qbosdk/apis/vendors.py b/qbosdk/apis/vendors.py index 7633427..cc064fd 100644 --- a/qbosdk/apis/vendors.py +++ b/qbosdk/apis/vendors.py @@ -21,6 +21,14 @@ def get(self): """ return self._query_get_all('Vendor', Vendors.GET_VENDORS) + def get_all_generator(self): + """Get a list of the existing Vendors in the Organization. + + Returns: + Generator with dicts in Vendors schema. + """ + return self._query_get_all_generator('Vendor', Vendors.GET_VENDORS) + def post(self, data: Dict): """ Post Vendor to Quickbooks Online diff --git a/setup.py b/setup.py index 06580cb..4ed5f2f 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name='qbosdk', - version='0.16.1', + version='0.17.0', author='Shwetabh Kumar', author_email='shwetabh.kumar@fyle.in', description='Python SDK for accessing Quickbooks Online APIs',