def get_all_consumers(self): urlpath = '/management/consumers' api = API(self.request.session.get('obp')) cache_key = get_cache_key_for_current_call(self.request, urlpath) apicaches = None try: apicaches = cache.get(cache_key) except Exception as err: apicaches = None if not apicaches is None: apps_list = apicaches else: try: apps = api.get(urlpath) apps_list = apps["consumers"] cache.set( cache_key, apps_list, 60 * 60 ) # for the consumers we cache for 1 hour, consumers may be increased LOGGER.warning( 'The cache is setting, url is: {}'.format(urlpath)) LOGGER.warning( 'The cache is setting key is: {}'.format(cache_key)) except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) return apps_list
def get_top_warehouse_calls(self, cleaned_data, from_date, to_date): try: top_apis = self.get_top_apis(cleaned_data, from_date, to_date) top_warehouse_calls = [] for api in top_apis: if "elasticSearchWarehouse" in api[ 'Implemented_by_partial_function']: top_warehouse_calls.append(api) except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) return top_warehouse_calls
def get_aggregate_metrics(self, from_date, to_date, is_included_obp_apps, only_show_api_explorer_metrics=False): """ Gets the metrics from the API, using given parameters, There are different use cases, so we accept different parameters. only_show_api_explorer_metrics has the default value False, because it is just used for app = API_Explorer. """ try: api_calls_total = 0 average_response_time = 0 urlpath = '/management/aggregate-metrics' if only_show_api_explorer_metrics: urlpath = urlpath + '?from_date={}&to_date={}&app_name={}'.format( from_date, to_date, API_EXPLORER_APP_NAME) elif ((not only_show_api_explorer_metrics) and (not is_included_obp_apps)): urlpath = urlpath + '?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format( from_date, to_date, ",".join(EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN)) else: urlpath = urlpath + '?from_date={}&to_date={}'.format( from_date, to_date) cache_key = get_cache_key_for_current_call(self.request, urlpath) apicaches = None try: apicaches = cache.get(cache_key) except Exception as err: apicaches = None if not apicaches is None: metrics = apicaches else: api = API(self.request.session.get('obp')) metrics = api.get(urlpath) apicaches = cache.set(cache_key, metrics) LOGGER.warning( 'The cache is setting, url is: {}'.format(urlpath)) LOGGER.warning( 'The cache is setting key is: {}'.format(cache_key)) api_calls_total, average_calls_per_day, average_response_time = self.get_internal_api_call_metrics( api_calls_total, average_response_time, cache_key, from_date, metrics, to_date, urlpath) return api_calls_total, average_response_time, int( average_calls_per_day) except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err))
def get_context_data(self, **kwargs): context = super(DetailView, self).get_context_data(**kwargs) api_collection_id = context['view'].kwargs['api_collection_id'] api = API(self.request.session.get('obp')) urlpath = '/my/api-collection-ids/{}/api-collection-endpoints'.format( api_collection_id) api_collection_endpoints = [] try: response = api.get(urlpath) if 'code' in response and response['code'] >= 400: error_once_only(self.request, response['message']) else: api_collection_endpoints = response['api_collection_endpoints'] except APIError as err: error_once_only( self.request, Exception( "OBP-API server is not running or do not response properly. " "Please check OBP-API server. " "Details: " + str(err))) except BaseException as err: error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err)))) else: context.update({ 'api_collection_endpoints': api_collection_endpoints, 'api_collection_id': api_collection_id }) return context
def get_context_data(self, **kwargs): context = super(IndexView, self).get_context_data(**kwargs) api = API(self.request.session.get('obp')) urlpath = '/my/api-collections' api_collections = [] try: response = api.get(urlpath) if 'code' in response and response['code'] >= 400: error_once_only(self.request, response['message']) else: api_collections = response['api_collections'] except APIError as err: error_once_only( self.request, Exception( "OBP-API server is not running or do not response properly. " "Please check OBP-API server. " "Details: " + str(err))) except BaseException as err: error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err)))) else: # set the default endpoint there, the first item will be the new endpoint. default_api_endpoint = { "api_collection_name": "Customer", "is_sharable": True, "description": "Describe the purpose of the collection" } api_collections.insert(0, json.dumps(default_api_endpoint)) context.update({'api_collections': api_collections}) return context
def calls_per_delta(self, is_included_obp_apps, from_date_string, to_date_string, **delta): """ return how many calls were made in total per given delta. Here we need to convert date_string to datetime object, and calculate the dates. """ # we need to convert string to datetime object, then we can calculate the date from_datetime_object = datetime.datetime.strptime( from_date_string, API_DATEFORMAT) to_datetime_object = datetime.datetime.strptime( to_date_string, API_DATEFORMAT) time_delta_in_loop = from_datetime_object + timedelta(**delta) result_list = [] result_list_pure = [] date_list = [] while time_delta_in_loop <= to_datetime_object: try: # here we need to first convert datetime object to String form_date = from_datetime_object.strftime(API_DATEFORMAT) to_date = time_delta_in_loop.strftime(API_DATEFORMAT) aggregate_metrics = self.get_aggregate_metrics( form_date, to_date, is_included_obp_apps) result = aggregate_metrics[0] result_list_pure.append(result) result_list.append('{} - {} # {}'.format( from_datetime_object, time_delta_in_loop, result)) date_list.append(from_datetime_object) except Exception as err: break error_once_only(self.request, 'Unknown Error. {}'.format(err)) from_datetime_object = time_delta_in_loop time_delta_in_loop = time_delta_in_loop + timedelta(**delta) return (result_list, result_list_pure, date_list)
def get_active_apps(self, is_included_obp_apps, from_date, to_date): """ Gets the metrics from the API, using given parameters, There are different use cases, so we accept different parameters. only_show_api_explorer_metrics has the default value False, because it is just used for app = API_Explorer. """ apps = [] form = self.get_form() active_apps_list = [] if is_included_obp_apps: urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}'.format( from_date, to_date) api = API(self.request.session.get('obp')) try: apps = api.get(urlpath) if apps is not None and 'code' in apps and apps['code'] == 403: error_once_only(self.request, apps['message']) else: active_apps_list = list(apps) except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) else: urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format( from_date, to_date, ",".join(EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN)) api = API(self.request.session.get('obp')) try: apps = api.get(urlpath) active_apps_list = list(apps['top_consumers']) except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) return active_apps_list
def get_context_data(self, **kwargs): context = super(IndexView, self).get_context_data(**kwargs) api = API(self.request.session.get('obp')) urlpath = '/management/method_routings?active=true' method_routings = [] try: response = api.get(urlpath) if 'code' in response and response['code'] >= 400: error_once_only(self.request, response['message']) else: method_routings = response['method_routings'] except APIError as err: error_once_only( self.request, Exception( "OBP-API server is not running or do not response properly. " "Please check OBP-API server. " "Details: " + str(err))) except BaseException as err: error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err)))) else: for i in range(len(method_routings)): #if the parameters are empty, we provide the example value. if (str(method_routings[i]['parameters']).find("key") == -1): method_routings[i]['parameters'] = json.dumps( [{ "key": "url", "value": "http://example.com/xxx" }], sort_keys=False) else: method_routings[i]['parameters'] = json.dumps( method_routings[i]['parameters'], sort_keys=False) if (str(settings.API_ROOT).find("127.0.0.1") == -1): methodSwaggerUrl = '{}/message-docs?connector=stored_procedure_vDec2019#'.format( settings.API_HOST.replace(".openbankproject.", "-explorer.openbankproject.")) else: methodSwaggerUrl = "http://127.0.0.1:8082/message-docs?connector=stored_procedure_vDec2019#" context.update({ 'method_routings': method_routings, "methodSwaggerUrl": methodSwaggerUrl }) return context
def get_users_cansearchwarehouse(self): users = [] users_with_cansearchwarehouse = [] email_with_cansearchwarehouse = [] api = API(self.request.session.get('obp')) try: urlpath = '/users' users = api.get(urlpath) if users is not None and 'code' in users and users['code'] == 403: error_once_only(self.request, users['message']) if 'users' not in users: users['users'] = [] except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) else: try: for user in users['users']: for entitlement in user['entitlements']['list']: if 'CanSearchWarehouse' in entitlement['role_name']: users_with_cansearchwarehouse.append( user["username"]) email_with_cansearchwarehouse.append(user["email"]) # fail gracefully in case API provides new structure except KeyError as err: messages.error(self.request, 'KeyError: {}'.format(err)) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) user_email_cansearchwarehouse = dict( zip(users_with_cansearchwarehouse, email_with_cansearchwarehouse)) number_of_users_with_cansearchwarehouse = len( user_email_cansearchwarehouse) return user_email_cansearchwarehouse, number_of_users_with_cansearchwarehouse
def get_metrics(self, cleaned_data): """ Gets the metrics from the API, using given cleaned form data. """ metrics = [] params = self.to_api(cleaned_data) urlpath = '{}?{}'.format(self.api_urlpath, params) api = API(self.request.session.get('obp')) try: metrics = api.get(urlpath) metrics = self.to_django(metrics['metrics']) except APIError as err: error_once_only(self.request, err) except KeyError as err: error_once_only(self.request, metrics['message']) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) return metrics
def get_top_apps_using_warehouse(self, from_date, to_date): form = self.get_form() top_apps_using_warehouse = [] urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&implemented_by_partial_function={}'.format( from_date, to_date, "elasticSearchWarehouse") api = API(self.request.session.get('obp')) try: top_apps_using_warehouse = api.get(urlpath) if top_apps_using_warehouse is not None and 'code' in top_apps_using_warehouse and top_apps_using_warehouse[ 'code'] == 403: error_once_only(self.request, top_apps_using_warehouse['message']) top_apps_using_warehouse = [] else: top_apps_using_warehouse = top_apps_using_warehouse[ "top_consumers"][:2] except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) return top_apps_using_warehouse
def prepare_general_context(self, web_page_type, **kwargs): try: form = self.get_form() per_day_chart = [] calls_per_month_list = [] per_month_chart = [] calls_per_hour_list = [] per_hour_chart = [] if form.is_valid(): is_included_obp_apps = form.cleaned_data.get( 'include_obp_apps') form_to_date_string = form.data['to_date'] to_date = convert_form_date_to_obpapi_datetime_format( form_to_date_string) if (web_page_type == SummaryType.DAYLY): # for one day, the from_date is 1 day ago. from_date = return_to_days_ago(to_date, 1) calls_per_hour_list, calls_per_hour, hour_list = self.calls_per_hour( is_included_obp_apps, from_date, to_date) per_hour_chart = self.plot_line_chart( calls_per_hour, hour_list, 'hour') if (web_page_type == SummaryType.WEEKLY): # for one month, the from_date is 7 days ago. from_date = return_to_days_ago(to_date, 7) calls_per_day_list, calls_per_day, date_list = self.calls_per_day( is_included_obp_apps, from_date, to_date) per_day_chart = self.plot_line_chart( calls_per_day, date_list, "day") if (web_page_type == SummaryType.MONTHLY): # for one month, the from_date is 30 days ago. from_date = return_to_days_ago(to_date, 30) calls_per_day_list, calls_per_day, date_list = self.calls_per_day( is_included_obp_apps, from_date, to_date) per_day_chart = self.plot_line_chart( calls_per_day, date_list, "day") if (web_page_type == SummaryType.QUARTERLY): # for one quarter, the from_date is 90 days ago. from_date = ( datetime.datetime.strptime(to_date, API_DATEFORMAT) - timedelta(90)).strftime(API_DATEFORMAT) calls_per_month_list, calls_per_month, month_list = self.calls_per_month( is_included_obp_apps, from_date, to_date) per_month_chart = self.plot_line_chart( calls_per_month, month_list, 'month') if (web_page_type == SummaryType.YEARLY): from_date = return_to_days_ago(to_date, 365) calls_per_month_list, calls_per_month, month_list = self.calls_per_month( is_included_obp_apps, from_date, to_date) per_month_chart = self.plot_line_chart( calls_per_month, month_list, "month") if (web_page_type == SummaryType.CUSTOM): # for one month, the from_date is x day ago. form_from_date_string = form.data['from_date_custom'] from_date = convert_form_date_to_obpapi_datetime_format( form_from_date_string) calls_per_day_list, calls_per_day, date_list = self.calls_per_day( is_included_obp_apps, from_date, to_date) per_day_chart = self.plot_line_chart( calls_per_day, date_list, "day") api_host_name = API_HOST top_apps_using_warehouse = self.get_top_apps_using_warehouse( from_date, to_date) user_email_cansearchwarehouse, number_of_users_with_cansearchwarehouse = self.get_users_cansearchwarehouse( ) median_time_to_first_api_call = self.median_time_to_first_api_call( from_date, to_date) top_apis = self.get_top_apis(form.cleaned_data, from_date, to_date) top_apis_bar_chart = self.plot_bar_chart(top_apis) top_consumers = self.get_top_consumers(form.cleaned_data, from_date, to_date) top_consumers_bar_chart = self.plot_topconsumer_bar_chart( top_consumers) top_warehouse_calls = self.get_top_warehouse_calls( form.cleaned_data, from_date, to_date) api_calls, average_response_time, average_calls_per_day = self.get_aggregate_metrics( from_date, to_date, is_included_obp_apps) calls_by_api_explorer, average_response_time_api_explorer, average_calls_per_day_api_explorer = self.get_aggregate_metrics_api_explorer( from_date, to_date) unique_app_names, number_of_apps_with_unique_app_name, number_of_apps_with_unique_developer_email = self.get_total_number_of_apps( form.cleaned_data, from_date, to_date) active_apps_list = self.get_active_apps( is_included_obp_apps, from_date, to_date) context = super(MonthlyMetricsSummaryView, self).get_context_data(**kwargs) context.update({ 'form': form, 'api_calls': api_calls, 'calls_by_api_explorer': calls_by_api_explorer, 'calls_per_month_list': calls_per_month_list, 'per_month_chart': per_month_chart, 'per_day_chart': per_day_chart, 'calls_per_hour_list': calls_per_hour_list, 'per_hour_chart': per_hour_chart, 'number_of_apps_with_unique_app_name': number_of_apps_with_unique_app_name, 'number_of_apps_with_unique_developer_email': number_of_apps_with_unique_developer_email, 'active_apps_list': active_apps_list, 'average_calls_per_day': average_calls_per_day, 'average_response_time': average_response_time, 'top_warehouse_calls': top_warehouse_calls, 'top_apps_using_warehouse': top_apps_using_warehouse, 'user_email_cansearchwarehouse': user_email_cansearchwarehouse, 'number_of_users_with_cansearchwarehouse': number_of_users_with_cansearchwarehouse, 'api_host_name': api_host_name, 'from_date': (datetime.datetime.strptime( from_date, API_DATEFORMAT)).strftime('%Y-%m-%d'), 'to_date': (datetime.datetime.strptime( to_date, API_DATEFORMAT)).strftime('%Y-%m-%d'), 'top_apis': top_apis, 'top_apis_bar_chart': top_apis_bar_chart, 'top_consumers_bar_chart': top_consumers_bar_chart, 'median_time_to_first_api_call': median_time_to_first_api_call, 'excluded_apps': EXCLUDE_APPS, 'excluded_functions': EXCLUDE_FUNCTIONS, 'excluded_url_pattern': EXCLUDE_URL_PATTERN, }) return context else: error_once_only(self.request, form.errors) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err))
def median_time_to_first_api_call(self, from_date, to_date): return 0 #TODO this cost too much time, do not use this at the moment. form = self.get_form() new_apps_list = [] apps = [] apps_list = self.get_all_consumers() for app in apps_list: created_date = datetime.datetime.strptime(app['created'], '%Y-%m-%dT%H:%M:%SZ') created_date = created_date.strftime(API_DATEFORMAT) created_date = datetime.datetime.strptime(created_date, API_DATEFORMAT) if created_date >= datetime.datetime.strptime( from_date, API_DATEFORMAT): new_apps_list.append(app) times_to_first_call = [] strfrom_date = datetime.datetime.strptime(from_date, API_DATEFORMAT) strto_date = datetime.datetime.strptime(to_date, API_DATEFORMAT) for app in new_apps_list: urlpath_metrics = '/management/metrics?from_date={}&to_date={}&consumer_id={}&sort_by={}&direction={}&limit={}'.format( from_date, to_date, app['consumer_id'], 'date', 'asc', '1') cache_key = get_cache_key_for_current_call(self.request, urlpath_metrics) api = API(self.request.session.get('obp')) try: apicaches = None try: apicaches = cache.get(cache_key) except Exception as err: apicaches = None metrics = [] if not apicaches is None: metrics = apicaches else: metrics = api.get(urlpath_metrics) if metrics is not None and 'code' in metrics and metrics[ 'code'] == 403: error_once_only(self.request, metrics['message']) if (metrics['message'].startswith('OBP-20006')): break metrics = [] else: metrics = list(metrics['metrics']) cache.set(cache_key, metrics) LOGGER.warning( 'The cache is setting, url is: {}'.format( urlpath_metrics)) LOGGER.warning( 'The cache is setting key is: {}'.format( cache_key)) if metrics: time_difference = datetime.datetime.strptime( metrics[0]['date'], '%Y-%m-%dT%H:%M:%S.%fZ') - datetime.datetime.strptime( app['created'], '%Y-%m-%dT%H:%M:%SZ') times_to_first_call.append(time_difference.total_seconds()) except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) if times_to_first_call: median = statistics.median(times_to_first_call) delta = datetime.timedelta(seconds=median) else: delta = 0 return delta
def get_top_consumers(self, cleaned_data, from_date, to_date): top_consumers = [] form = self.get_form() if cleaned_data.get('include_obp_apps'): urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}'.format( from_date, to_date) api = API(self.request.session.get('obp')) try: top_consumers = api.get(urlpath) if top_consumers is not None and 'code' in top_consumers and top_consumers[ 'code'] == 403: error_once_only(self.request, top_consumers['message']) top_consumers = [] else: top_consumers = top_consumers['top_consumers'] except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) else: urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format( from_date, to_date, ",".join(EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN)) api = API(self.request.session.get('obp')) try: top_consumers = api.get(urlpath) if top_consumers is not None and 'code' in top_consumers and top_consumers[ 'code'] == 403: error_once_only(self.request, top_consumers['message']) top_consumers = [] else: top_consumers = top_consumers['top_consumers'] except APIError as err: error_once_only(self.request, err) except Exception as err: error_once_only(self.request, 'Unknown Error. {}'.format(err)) for consumer in top_consumers: if consumer['app_name'] == "": top_consumers.remove(consumer) top_consumers = top_consumers[:10] top_consumers = reversed(top_consumers) return top_consumers
def get_context_data(self, **kwargs): context = super(IndexView, self).get_context_data(**kwargs) api = API(self.request.session.get('obp')) urlpath = '/management/dynamic-endpoints' dynamic_endpoints = [] try: response = api.get(urlpath) if 'code' in response and response['code'] >= 400: error_once_only(self.request, response['message']) else: dynamic_endpoints = response['dynamic_endpoints'] except APIError as err: error_once_only( self.request, Exception( "OBP-API server is not running or do not response properly. " "Please check OBP-API server. " "Details: " + str(err))) except BaseException as err: error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err)))) else: # set the default endpoint there, the first item will be the new endpoint. default_dynamic_endpoint = { "dynamic_endpoint_id": "Try the new endpoint: ", "swagger_string": { "swagger": "2.0", "info": { "version": "0.0.1", "title": "Example Title", "description": "Example Description", "contact": { "name": "Example Company", "email": "*****@*****.**", "url": "https://www.tesobe.com/" } }, "host": "localhost:8080", "basePath": "/user", "schemes": ["http"], "consumes": ["application/json"], "produces": ["application/json"], "paths": { "/save": { "post": { "parameters": [{ "name": "body", "in": "body", "required": True, "schema": { "$ref": "#/definitions/user" } }], "responses": { "201": { "description": "create user successful and return created user object", "schema": { "$ref": "#/definitions/user" } }, "500": { "description": "unexpected error", "schema": { "$ref": "#/responses/unexpectedError" } } } } }, "/getById/{userId}": { "get": { "description": "get reuested user by user ID", "parameters": [{ "$ref": "#/parameters/userId" }], "consumes": [], "responses": { "200": { "description": "the successful get requested user by user ID", "schema": { "$ref": "#/definitions/user" } }, "400": { "description": "bad request", "schema": { "$ref": "#/responses/invalidRequest" } }, "404": { "description": "user not found", "schema": { "$ref": "#/definitions/APIError" } }, "500": { "description": "unexpected error", "schema": { "$ref": "#/responses/unexpectedError" } } } } }, "/listUsers": { "get": { "description": "get list of users", "consumes": [], "responses": { "200": { "description": "get all users", "schema": { "$ref": "#/definitions/users" } }, "404": { "description": "user not found", "schema": { "$ref": "#/definitions/APIError" } } } } }, "/updateUser": { "put": { "parameters": [{ "name": "body", "in": "body", "required": True, "schema": { "$ref": "#/definitions/user" } }], "responses": { "200": { "description": "create user successful and return created user object", "schema": { "$ref": "#/definitions/user" } }, "500": { "description": "unexpected error", "schema": { "$ref": "#/responses/unexpectedError" } } } } }, "/delete/{userId}": { "delete": { "description": "delete user by user ID", "parameters": [{ "$ref": "#/parameters/userId" }], "consumes": [], "responses": { "204": { "description": "the successful delete user by user ID" }, "400": { "description": "bad request", "schema": { "$ref": "#/responses/invalidRequest" } }, "500": { "description": "unexpected error", "schema": { "$ref": "#/responses/unexpectedError" } } } } } }, "definitions": { "user": { "type": "object", "properties": { "id": { "type": "integer", "description": "user ID" }, "first_name": { "type": "string" }, "last_name": { "type": "string" }, "age": { "type": "integer" }, "career": { "type": "string" } }, "required": ["first_name", "last_name", "age"] }, "users": { "description": "array of users", "type": "array", "items": { "$ref": "#/definitions/user" } }, "APIError": { "description": "content any error from API", "type": "object", "properties": { "errorCode": { "description": "content error code relate to API", "type": "string" }, "errorMessage": { "description": "content user-friendly error message", "type": "string" } } } }, "responses": { "unexpectedError": { "description": "unexpected error", "schema": { "$ref": "#/definitions/APIError" } }, "invalidRequest": { "description": "invalid request", "schema": { "$ref": "#/definitions/APIError" } } }, "parameters": { "userId": { "name": "userId", "in": "path", "required": True, "type": "string", "description": "user ID" } } } } dynamic_endpoints.insert(0, default_dynamic_endpoint) # replace all the json list to json object. for i in range(len(dynamic_endpoints)): dynamic_endpoints[i]['swagger_string'] = json.dumps( dynamic_endpoints[i]['swagger_string']) context.update({'dynamic_endpoints': dynamic_endpoints}) return context