From 1b06e7f875fd97d3ad48d8cd14b1c6176944ae72 Mon Sep 17 00:00:00 2001 From: Reena Aheer Date: Tue, 11 Apr 2023 11:06:05 +0200 Subject: [PATCH 1/5] feature/ remove API_VERSION from code base --- apimanager/apimanager/settings.py | 11 +++++--- apimanager/obp/api.py | 44 +++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/apimanager/apimanager/settings.py b/apimanager/apimanager/settings.py index f0df7a4..9b68ed5 100644 --- a/apimanager/apimanager/settings.py +++ b/apimanager/apimanager/settings.py @@ -259,8 +259,6 @@ API_HOST = 'http://127.0.0.1:8080' API_EXPLORER_HOST = 'http://127.0.0.1:8082' # Only override this if you have a separate portal instance API_PORTAL = API_HOST -API_BASE_PATH = '/obp/v' -API_VERSION = '5.1.0' # URL to API Tester API_TESTER_URL = 'https://www.example.com' @@ -317,11 +315,16 @@ except ImportError: pass # EVERYTHING BELOW HERE WILL *NOT* BE OVERWRITTEN BY LOCALSETTINGS! # DO NOT TRY TO DO SO YOU WILL BE IGNORED! +OBPv500 = API_HOST + '/obp/v5.0.0' +OBPv510 = API_HOST + '/obp/v5.1.0' # Settings here might use parts overwritten in local settings -API_ROOT = API_HOST + API_BASE_PATH + API_VERSION +API_ROOT = { + "v500": OBPv500, + "v510": OBPv510 +} # For some reason, swagger is not available at the latest API version -API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + API_VERSION + '/swagger' # noqa +API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + OBPv510 + '/swagger' # noqa if not OAUTH_CONSUMER_KEY: raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY') diff --git a/apimanager/obp/api.py b/apimanager/obp/api.py index 5f976fc..6c57cea 100644 --- a/apimanager/obp/api.py +++ b/apimanager/obp/api.py @@ -70,12 +70,14 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath + url = settings.API_ROOT["v500"] + urlpath response = self.handle_response(self.call('GET', url)) if response is not None and 'code' in response: - raise APIError(response['message']) - else: - return response + url = settings.API_ROOT["v510"] + urlpath + response = self.handle_response(self.call('GET', url)) + if response is not None and 'code' in response: + raise APIError(response['message']) + return response def delete(self, urlpath): """ @@ -83,9 +85,14 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath - response = self.call('DELETE', url) - return self.handle_response(response) + url = settings.API_ROOT["v500"] + urlpath + response = self.handle_response(self.call('DELETE', url)) + if response is not None and 'code' in response: + url = settings.API_ROOT["v510"] + urlpath + response = self.handle_response(self.call('DELETE', url)) + if response is not None and 'code' in response: + raise APIError(response['message']) + return response def post(self, urlpath, payload): """ @@ -93,19 +100,28 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath - response = self.call('POST', url, payload) - return self.handle_response(response) - + url = settings.API_ROOT["v500"] + urlpath + response = self.handle_response(self.call('POST', url, payload)) + if response is not None and 'code' in response: + url = settings.API_ROOT["v510"] + urlpath + response = self.handle_response(self.call('POST', url, payload)) + if response is not None and 'code' in response: + raise APIError(response['message']) + return response def put(self, urlpath, payload): """ Puts data on given urlpath with given payload Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath - response = self.call('PUT', url, payload) - return self.handle_response(response) + url = settings.API_ROOT["v500"] + urlpath + response = self.handle_response(self.call('PUT', url, payload)) + if response is not None and 'code' in response: + url = settings.API_ROOT["v510"] + urlpath + response = self.handle_response(self.call('PUT', url, payload)) + if response is not None and 'code' in response: + raise APIError(response['message']) + return response def handle_response_error(self, prefix, error): if 'Invalid or expired access token' in error: From 2a6dbb89f5d1438b39c6a80f74952b9c3ab3ad4a Mon Sep 17 00:00:00 2001 From: Reena Aheer Date: Tue, 11 Apr 2023 14:01:06 +0200 Subject: [PATCH 2/5] feature/ remove API_VERSION from code base --- apimanager/base/context_processors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apimanager/base/context_processors.py b/apimanager/base/context_processors.py index 1169fdc..a8f30c0 100644 --- a/apimanager/base/context_processors.py +++ b/apimanager/base/context_processors.py @@ -13,7 +13,7 @@ USER_CURRENT = "/users/current" def api_root(request): """Returns the configured API_ROOT""" - return {'API_ROOT': settings.API_ROOT} + return {'API_ROOT': settings.API_ROOT["v500"]} def portal_page(request): From 77f0cdfe65b5cffb1ba5eb4dd2aabb71e5d112b9 Mon Sep 17 00:00:00 2001 From: Reena Aheer Date: Tue, 18 Apr 2023 22:30:36 +0200 Subject: [PATCH 3/5] API_Version --- apimanager/apimanager/settings.py | 2 +- apimanager/atms/views.py | 4 ++- apimanager/base/context_processors.py | 4 +-- apimanager/obp/api.py | 50 +++++++++------------------ 4 files changed, 23 insertions(+), 37 deletions(-) diff --git a/apimanager/apimanager/settings.py b/apimanager/apimanager/settings.py index 9b68ed5..4b38fd2 100644 --- a/apimanager/apimanager/settings.py +++ b/apimanager/apimanager/settings.py @@ -324,7 +324,7 @@ API_ROOT = { "v510": OBPv510 } # For some reason, swagger is not available at the latest API version -API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + OBPv510 + '/swagger' # noqa +API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + OBPv500 + '/swagger' # noqa if not OAUTH_CONSUMER_KEY: raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY') diff --git a/apimanager/atms/views.py b/apimanager/atms/views.py index 277adde..7a5a0ed 100644 --- a/apimanager/atms/views.py +++ b/apimanager/atms/views.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ from django.views.decorators.csrf import csrf_exempt from django.urls import reverse, reverse_lazy from base.utils import exception_handle, error_once_only +from django.conf import settings CHOOSE = "Choose..." @@ -203,6 +204,7 @@ class UpdateAtmsView(LoginRequiredMixin, FormView): template_name = "atms/update.html" success_url = '/atms/list' form_class = CreateAtmForm + v510 = settings.API_ROOT['v510'] def dispatch(self, request, *args, **kwargs): self.api = API(request.session.get('obp')) @@ -374,7 +376,7 @@ class UpdateAtmsView(LoginRequiredMixin, FormView): def atm_attributes(self, **kwargs): atm_attributes_url_path = "/banks/{}/atms/{}/attributes".format(self.kwargs['bank_id'], self.kwargs['atm_id']) try: - atm_attributes_result = self.api.get(atm_attributes_url_path)["atm_attributes"] + atm_attributes_result = self.api.get(atm_attributes_url_path, version=self.v510)["atm_attributes"] return atm_attributes_result except Exception as err: messages.error(self.request, "Unknown Error {}".format(err)) diff --git a/apimanager/base/context_processors.py b/apimanager/base/context_processors.py index a8f30c0..1ad1068 100644 --- a/apimanager/base/context_processors.py +++ b/apimanager/base/context_processors.py @@ -13,7 +13,7 @@ USER_CURRENT = "/users/current" def api_root(request): """Returns the configured API_ROOT""" - return {'API_ROOT': settings.API_ROOT["v500"]} + return {'API_ROOT': settings.API_ROOT} def portal_page(request): @@ -38,7 +38,7 @@ def api_username(request): """Returns the API username/email of the logged-in user""" nametodisplay = 'not authenticated' get_current_user_api_url = USER_CURRENT - #Here we can not get the user from obp-api side, so we use the django auth user id here. + #Here we can not get the user from obp-api side, so we use the django auth user id here. cache_key_django_user_id = request.session._session.get('_auth_user_id') cache_key = '{},{},{}'.format('api_username',get_current_user_api_url, cache_key_django_user_id) apicaches=None diff --git a/apimanager/obp/api.py b/apimanager/obp/api.py index 6c57cea..d533ddc 100644 --- a/apimanager/obp/api.py +++ b/apimanager/obp/api.py @@ -43,7 +43,7 @@ class API(object): self.start_session(session_data) self.session_data = session_data - def call(self, method='GET', url='', payload=None): + def call(self, method='GET', url='', payload=None, version=settings.API_ROOT['v500']): """Workhorse which actually calls the API""" log(logging.INFO, '{} {}'.format(method, url)) if payload: @@ -64,20 +64,18 @@ class API(object): response.execution_time = elapsed return response - def get(self, urlpath=''): + def get(self, urlpath='', version=settings.API_ROOT['v500']): """ Gets data from the API Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath + url = version + urlpath response = self.handle_response(self.call('GET', url)) if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('GET', url)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + raise APIError(response['message']) + else: + return response def delete(self, urlpath): """ @@ -85,14 +83,9 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath - response = self.handle_response(self.call('DELETE', url)) - if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('DELETE', url)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + url = settings.API_ROOT + urlpath + response = self.call('DELETE', url) + return self.handle_response(response) def post(self, urlpath, payload): """ @@ -100,28 +93,19 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath - response = self.handle_response(self.call('POST', url, payload)) - if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('POST', url, payload)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + url = settings.API_ROOT + urlpath + response = self.call('POST', url, payload) + return self.handle_response(response) + def put(self, urlpath, payload): """ Puts data on given urlpath with given payload Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath - response = self.handle_response(self.call('PUT', url, payload)) - if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('PUT', url, payload)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + url = settings.API_ROOT + urlpath + response = self.call('PUT', url, payload) + return self.handle_response(response) def handle_response_error(self, prefix, error): if 'Invalid or expired access token' in error: @@ -198,4 +182,4 @@ class API(object): result = self.get('/users') for user in result['users']: choices.append((user['user_id'], user['username'])) - return choices + return choices \ No newline at end of file From 2c4f428816c519b43e80aabe7576c18b42031db6 Mon Sep 17 00:00:00 2001 From: Reena Aheer Date: Tue, 18 Apr 2023 22:30:36 +0200 Subject: [PATCH 4/5] API_Version --- apimanager/apimanager/settings.py | 2 +- apimanager/atms/views.py | 4 ++- apimanager/base/context_processors.py | 4 +-- apimanager/obp/api.py | 50 +++++++++------------------ 4 files changed, 23 insertions(+), 37 deletions(-) diff --git a/apimanager/apimanager/settings.py b/apimanager/apimanager/settings.py index 9b68ed5..4b38fd2 100644 --- a/apimanager/apimanager/settings.py +++ b/apimanager/apimanager/settings.py @@ -324,7 +324,7 @@ API_ROOT = { "v510": OBPv510 } # For some reason, swagger is not available at the latest API version -API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + OBPv510 + '/swagger' # noqa +API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + OBPv500 + '/swagger' # noqa if not OAUTH_CONSUMER_KEY: raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY') diff --git a/apimanager/atms/views.py b/apimanager/atms/views.py index 277adde..7a5a0ed 100644 --- a/apimanager/atms/views.py +++ b/apimanager/atms/views.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ from django.views.decorators.csrf import csrf_exempt from django.urls import reverse, reverse_lazy from base.utils import exception_handle, error_once_only +from django.conf import settings CHOOSE = "Choose..." @@ -203,6 +204,7 @@ class UpdateAtmsView(LoginRequiredMixin, FormView): template_name = "atms/update.html" success_url = '/atms/list' form_class = CreateAtmForm + v510 = settings.API_ROOT['v510'] def dispatch(self, request, *args, **kwargs): self.api = API(request.session.get('obp')) @@ -374,7 +376,7 @@ class UpdateAtmsView(LoginRequiredMixin, FormView): def atm_attributes(self, **kwargs): atm_attributes_url_path = "/banks/{}/atms/{}/attributes".format(self.kwargs['bank_id'], self.kwargs['atm_id']) try: - atm_attributes_result = self.api.get(atm_attributes_url_path)["atm_attributes"] + atm_attributes_result = self.api.get(atm_attributes_url_path, version=self.v510)["atm_attributes"] return atm_attributes_result except Exception as err: messages.error(self.request, "Unknown Error {}".format(err)) diff --git a/apimanager/base/context_processors.py b/apimanager/base/context_processors.py index a8f30c0..1ad1068 100644 --- a/apimanager/base/context_processors.py +++ b/apimanager/base/context_processors.py @@ -13,7 +13,7 @@ USER_CURRENT = "/users/current" def api_root(request): """Returns the configured API_ROOT""" - return {'API_ROOT': settings.API_ROOT["v500"]} + return {'API_ROOT': settings.API_ROOT} def portal_page(request): @@ -38,7 +38,7 @@ def api_username(request): """Returns the API username/email of the logged-in user""" nametodisplay = 'not authenticated' get_current_user_api_url = USER_CURRENT - #Here we can not get the user from obp-api side, so we use the django auth user id here. + #Here we can not get the user from obp-api side, so we use the django auth user id here. cache_key_django_user_id = request.session._session.get('_auth_user_id') cache_key = '{},{},{}'.format('api_username',get_current_user_api_url, cache_key_django_user_id) apicaches=None diff --git a/apimanager/obp/api.py b/apimanager/obp/api.py index 6c57cea..d533ddc 100644 --- a/apimanager/obp/api.py +++ b/apimanager/obp/api.py @@ -43,7 +43,7 @@ class API(object): self.start_session(session_data) self.session_data = session_data - def call(self, method='GET', url='', payload=None): + def call(self, method='GET', url='', payload=None, version=settings.API_ROOT['v500']): """Workhorse which actually calls the API""" log(logging.INFO, '{} {}'.format(method, url)) if payload: @@ -64,20 +64,18 @@ class API(object): response.execution_time = elapsed return response - def get(self, urlpath=''): + def get(self, urlpath='', version=settings.API_ROOT['v500']): """ Gets data from the API Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath + url = version + urlpath response = self.handle_response(self.call('GET', url)) if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('GET', url)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + raise APIError(response['message']) + else: + return response def delete(self, urlpath): """ @@ -85,14 +83,9 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath - response = self.handle_response(self.call('DELETE', url)) - if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('DELETE', url)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + url = settings.API_ROOT + urlpath + response = self.call('DELETE', url) + return self.handle_response(response) def post(self, urlpath, payload): """ @@ -100,28 +93,19 @@ class API(object): Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath - response = self.handle_response(self.call('POST', url, payload)) - if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('POST', url, payload)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + url = settings.API_ROOT + urlpath + response = self.call('POST', url, payload) + return self.handle_response(response) + def put(self, urlpath, payload): """ Puts data on given urlpath with given payload Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT["v500"] + urlpath - response = self.handle_response(self.call('PUT', url, payload)) - if response is not None and 'code' in response: - url = settings.API_ROOT["v510"] + urlpath - response = self.handle_response(self.call('PUT', url, payload)) - if response is not None and 'code' in response: - raise APIError(response['message']) - return response + url = settings.API_ROOT + urlpath + response = self.call('PUT', url, payload) + return self.handle_response(response) def handle_response_error(self, prefix, error): if 'Invalid or expired access token' in error: @@ -198,4 +182,4 @@ class API(object): result = self.get('/users') for user in result['users']: choices.append((user['user_id'], user['username'])) - return choices + return choices \ No newline at end of file From e0314aac6ada53d4825e973e6b4fc6e933e12531 Mon Sep 17 00:00:00 2001 From: Reena Aheer Date: Thu, 20 Apr 2023 11:28:10 +0200 Subject: [PATCH 5/5] Improve API_Version or hardcoded latest with endpoint --- apimanager/atms/views.py | 6 +++--- apimanager/obp/api.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apimanager/atms/views.py b/apimanager/atms/views.py index 7a5a0ed..2fa81b0 100644 --- a/apimanager/atms/views.py +++ b/apimanager/atms/views.py @@ -410,7 +410,7 @@ def atm_attribute_save(request): 'value': request.POST.get('value').strip(), 'is_active': True } - result = api.post(urlpath_save, payload = payload) + result = api.post(urlpath_save, payload = payload, version=settings.API_ROOT['v510']) return result @@ -428,7 +428,7 @@ def atm_attribute_update(request): 'value': request.POST.get('value').strip(), 'is_active': True } - result = api.put(urlpath_update, payload=payload) + result = api.put(urlpath_update, payload=payload, version=settings.API_ROOT['v510']) return result @@ -441,7 +441,7 @@ def atm_attribute_delete(request): api = API(request.session.get('obp')) urlpath_delete = '/banks/{}/atms/{}/attributes/{}'.format(bank_id, atm_id, atm_attribute_id) - result = api.delete(urlpath_delete) + result = api.delete(urlpath_delete, version=settings.API_ROOT['v510']) return result diff --git a/apimanager/obp/api.py b/apimanager/obp/api.py index d533ddc..4f5f75e 100644 --- a/apimanager/obp/api.py +++ b/apimanager/obp/api.py @@ -77,33 +77,33 @@ class API(object): else: return response - def delete(self, urlpath): + def delete(self, urlpath, version=settings.API_ROOT['v500']): """ Deletes data from the API Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath + url = version + urlpath response = self.call('DELETE', url) return self.handle_response(response) - def post(self, urlpath, payload): + def post(self, urlpath, payload, version=settings.API_ROOT['v500']): """ Posts data to given urlpath with given payload Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath + url = version + urlpath response = self.call('POST', url, payload) return self.handle_response(response) - def put(self, urlpath, payload): + def put(self, urlpath, payload, version=settings.API_ROOT['v500']): """ Puts data on given urlpath with given payload Convenience call which uses API_ROOT from settings """ - url = settings.API_ROOT + urlpath + url = version + urlpath response = self.call('PUT', url, payload) return self.handle_response(response)