def handleControllerMethod(args, kwargs, contentType, resourceInstance, resourceInstanceMethod, requestHeaderClass, requestParamClass, requestClass, logRequest, muteStacktraceOnBusinessRuleException): requestBodyAsJson = {} if resourceInstanceMethod.__name__ in OpenApiManager.ABLE_TO_RECIEVE_BODY_LIST and requestClass: requestBodyAsJson = getRequestBodyAsJson(contentType, requestClass) if Serializer.requestBodyIsPresent(requestBodyAsJson): requestBodyAsJsonSerialized = Serializer.convertFromJsonToObject( requestBodyAsJson, requestClass) args = getArgsWithSerializerReturnAppended( args, requestBodyAsJsonSerialized) headers = FlaskUtil.addToKwargs(FlaskUtil.KW_HEADERS, requestHeaderClass, FlaskUtil.safellyGetHeaders(), kwargs) query = FlaskUtil.addToKwargs(FlaskUtil.KW_PARAMETERS, requestParamClass, FlaskUtil.safellyGetArgs(), kwargs) try: if resourceInstance.logRequest or logRequest: log.prettyJson( resourceInstanceMethod, '[CONTROLLER] Request', { 'headers': headers, # 'query': FlaskUtil.addToKwargs(FlaskUtil.KW_PARAMETERS, requestParamClass, FlaskUtil.safellyGetArgs(), kwargs), ###- safellyGetUrl() returns query param 'body': requestBodyAsJson }, condition=True, logLevel=log.INFO) except Exception as exception: log.failure(innerResourceInstanceMethod, 'Not possible to log request properly', exception) return validateAndReturnResponse( handleAdditionalResponseHeadersIfNeeded( resourceInstanceMethod(resourceInstance, *args[1:], **kwargs)))
def addEndPointDocumentation(endPointUrl, controllerMethod, controller, apiInstance): try: url = getUrl(endPointUrl, apiInstance.baseUrl) addUrlIfNeeded(url, apiInstance.documentation) verb = ReflectionHelper.getName(controllerMethod, muteLogs=True) if verb in [KW_GET, KW_POST, KW_PUT, KW_DELETE, KW_PATCH]: addVerb(verb, url, apiInstance.documentation) addTagToUrlVerb(verb, url, controller.tag, apiInstance.documentation) addConsumesAndProducesToUrlVerb(verb, url, controllerMethod.consumes, controllerMethod.produces, apiInstance.documentation) addSession(verb, url, controllerMethod.contextRequired, apiInstance.documentation, apiInstance.globals) addApiKey(verb, url, controllerMethod.apiKeyRequired, apiInstance.documentation, apiInstance.globals) addSecurity(verb, url, controllerMethod.roleRequired, apiInstance.documentation, apiInstance.globals) addHeadersListToUrlVerb(verb, url, endPointUrl, controllerMethod.requestHeaderClass, apiInstance.documentation) addUrlParamListToUrlVerb(verb, url, endPointUrl, apiInstance.documentation) addQueryParamListToUrlVerb(verb, url, endPointUrl, controllerMethod.requestParamClass, apiInstance.documentation) addRequestToUrlVerb(verb, url, controllerMethod.requestClass, apiInstance.documentation) addResponseToUrlVerb(verb, url, controllerMethod.responseClass, apiInstance.documentation) except Exception as exception: log.failure(addEndPointDocumentation, 'Not possible to add end point documentation', exception)
def mustLogPretyJsonWithColors(): # Arrange # log.log(mustLogPretyPythonWithColors, f'type({MyClass}): {type(MyClass)}') # log.log(mustLogPretyPythonWithColors, f'type({MyClass}).__name__: {type(MyClass).__name__}') # log.log(mustLogPretyPythonWithColors, f'type({MyClass().myMethod}): {type(MyClass().myMethod)}') # log.log(mustLogPretyPythonWithColors, f'type({MyClass().myMethod}).__name__: {type(MyClass().myMethod).__name__}') # log.log(mustLogPretyPythonWithColors, f'type({myFunction}): {type(myFunction)}') # log.log(mustLogPretyPythonWithColors, f'type({myFunction}).__name__: {type(myFunction).__name__}') # log.log(mustLogPretyPythonWithColors, f'type({log}): {type(log)}') # log.log(mustLogPretyPythonWithColors, f'type({log}).__name__: {type(log).__name__}') dictionaryInstance = { **{ 'class': MyClass, 'method': MyClass().myMethod, 'value': MyClass().myMethod(), 'function': myFunction, 'otherValue': myFunction(1.1), 'module': log }, **DICTIONARY_INSTANCE } exception = None # Act try: log.prettyJson(mustLogPretyJsonWithColors, 'prettyJson', dictionaryInstance) except Exception as e: log.failure(mustLogPretyJsonWithColors, 'Failed to log prety json in this method call', e) exception = e # Assert assert exception is None
def mustLogWithoutColors(): # Arrange noExceptionThrown = 'exception not thrown' someLogMessage = 'some log message' someExceptionMessage = 'some exception message' someInnerExceptionMessage = 'some inner exception message' exception = None someExceptionMessageWithStackTrace = f'{someExceptionMessage} with stacktrace' someExceptionMessageWithoutStackTrace = f'{someExceptionMessage} without stacktrace' def controlableException(logType, muteStackTrace=False): try: raise Exception( someExceptionMessageWithoutStackTrace if muteStackTrace else someExceptionMessageWithStackTrace) except Exception as exception: if logType in OPTIONAL_EXCEPTION_LOG_TYPES: logType(logType, someLogMessage, exception=exception, muteStackTrace=muteStackTrace) else: logType(logType, someLogMessage, exception, muteStackTrace=muteStackTrace) # Act log.success(log.success, someLogMessage) log.setting(log.setting, someLogMessage) log.debug(log.debug, someLogMessage) log.warning(log.warning, someLogMessage) controlableException(log.log) controlableException(log.debug) controlableException(log.warning) controlableException(log.wraper) controlableException(log.failure) controlableException(log.error) controlableException(log.test) controlableException(log.log, muteStackTrace=True) controlableException(log.debug, muteStackTrace=True) controlableException(log.warning, muteStackTrace=True) controlableException(log.wraper, muteStackTrace=True) controlableException(log.failure, muteStackTrace=True) controlableException(log.error, muteStackTrace=True) controlableException(log.test, muteStackTrace=True) log.log(log.log, someLogMessage, None) log.debug(log.debug, someLogMessage, None) log.warning(log.warning, someLogMessage, None) log.wraper(log.wraper, noExceptionThrown, None) log.failure(log.failure, noExceptionThrown, None) log.error(log.error, noExceptionThrown, None) log.test(log.test, someLogMessage, None) # Assert assert 'my environment' == EnvironmentHelper.get( SettingHelper.ACTIVE_ENVIRONMENT)
def handleSystemArgumentValue(self, commandList, externalFunction): globals = self.globals try: if self.apiClassSet: apiClass = self.apiClassSet.get(commandList[self._0_API_KEY]) if apiClass and apiClass in [self.__class__, GitCommitter]: log.success(self.__class__, f'running {commandList} command list') return self.handleCommandList(commandList) elif apiClass: globals.overrideApiTree(apiClass.__name__, package=apiClass.__name__) api = apiClass(*self.args, **self.kwargs) log.success( self.__class__, f'running {apiClass.__name__}({self.args}, {self.kwargs})' ) return api.handleCommandList(commandList) else: log.failure( self.__class__, f'''couldn't instance api class of {commandList[self._0_API_KEY]}''', c.NOTHING) else: log.debug( self.__class__, f'{commandList[self._0_API_KEY]} key called and running all alone' ) return externalFunction(commandList, globals, **self.kwargs) except Exception as exception: errorMessage = str(exception) if self.MISSING_REQUIRED_ARGUMENT in errorMessage: newArgs = *self.args, self.globals try: api = apiClass(*newArgs, **self.kwargs) log.success( self.__class__, f'running {apiClass.__name__}({self.args}, {self.kwargs})' ) return api.handleCommandList(commandList) except Exception as exception: secondErrorMessage = f', after first try: {str(exception)}' newArgs = *self.args, self.session, self.globals try: api = apiClass(*newArgs, **self.kwargs) log.success( self.__class__, f'running {apiClass.__name__}({self.args}, {self.kwargs})' ) return api.handleCommandList(commandList) except Exception as exception: thirdErrorMessage = f', after second try: {str(exception)}' else: secondErrorMessage = '' thirdErrorMessage = '' globals.error( self.__class__, f'error processing "{commandList[self._0_API_KEY]}" call{secondErrorMessage}{thirdErrorMessage}', errorMessage)
def shutdown(apiInstance, appInstance): try: apiInstance.repository.close() except Exception as exception: log.failure( shutdown, 'Not possible to close SqlAlchemyProxy database connection', exception) log.success(shutdown, 'SqlAlchemyProxy database connection successfully closed')
def closeSqlAlchemyProxySession(error): try: try: apiInstance.repository.session.commit() except Exception as innerException: log.log(closeSqlAlchemyProxySession, 'Not possible to close SqlAlchemyProxy session', exception=innerException) apiInstance.repository.session.close() except Exception as exception: log.failure(closeSqlAlchemyProxySession, 'Not possible to close SqlAlchemyProxy session', exception)
def mustLogPretyPythonWithoutColors(): # Arrange dictionaryInstance = {**{}, **DICTIONARY_INSTANCE} exception = None # Act try: log.prettyPython(mustLogPretyPythonWithoutColors, 'prettyPythonWithoutColors', dictionaryInstance) except Exception as e: log.failure(mustLogPretyPythonWithoutColors, 'Failed to log prety python in this method call', e) exception = e # Assert assert ObjectHelper.isNone(exception)
def addControllerDocumentation(controller, apiInstance): try: tag = getTagByTagName(controller.tag, apiInstance.documentation) if not tag: apiInstance.documentation[k.TAGS].append({ k.NAME: controller.tag, k.DESCRIPTION: controller.description, k.EXTERNAL_DOCS: None }) else: tag[k.DESCRIPTION] += f'. {controller.description}' except Exception as exception: log.failure(addControllerDocumentation, 'Not possible to add controller documentation', exception)
def getCompleteResponseByException(exception, resourceInstance, resourceInstanceMethod): exception = getGlobalException(exception, resourceInstance, resourceInstanceMethod) completeResponse = [{ 'message': exception.message, 'timestamp': str(exception.timeStamp) }, exception.status] try: logErrorMessage = f'Error processing {resourceInstance.__class__.__name__}.{resourceInstanceMethod.__name__} request' if HttpStatus.INTERNAL_SERVER_ERROR <= exception.status: log.error(resourceInstance.__class__, logErrorMessage, exception) else: log.failure(resourceInstance.__class__, logErrorMessage, exception=exception) except Exception as logErrorMessageException: log.log(getCompleteResponseByException, 'Error logging exception at controller', exception=logErrorMessageException) log.error(log.error, 'Error processing request', exception) return completeResponse
def validateArgs(self, method, objectRequest, expecteObjectClass): try: proceedValidation = True if ObjectHelper.isList(expecteObjectClass) and ObjectHelper.isList( objectRequest): if len(objectRequest) == 0: proceedValidation = False if proceedValidation and (objectRequest and not type(expecteObjectClass) == type( objectRequest.__class__) and expecteObjectClass.__name__ == objectRequest.__class__.__name__): raise GlobalException( logMessage= f'Invalid args. {self.__class__}.{method} call got an unnexpected object request: {objectRequest.__class__}. It should be {expecteObjectClass}' ) except Exception as exception: log.failure(expecteObjectClass.__class__, f'Failed to validate args of {method.__name__} method', exception) raise GlobalException( logMessage= f'Failed to validate args of {method.__name__} method{DOT_SPACE_CAUSE}{str(exception)}' )
def getCompleteResponseByException(exception, resourceInstance, resourceInstanceMethod, muteStacktraceOnBusinessRuleException): try: exception = getAndPersistGlobalException(exception, resourceInstance, resourceInstanceMethod) completeResponse = (ExceptionHandler.getDefaultBodyException( exception=exception), {}, exception.status) try: logErrorMessage = f'Error processing {resourceInstance.__class__.__name__}.{resourceInstanceMethod.__name__} request' if HttpStatus.INTERNAL_SERVER_ERROR <= HttpStatus.map( exception.status): log.error(resourceInstance.__class__, logErrorMessage, exception) else: log.failure( resourceInstance.__class__, logErrorMessage, exception=exception, muteStackTrace=muteStacktraceOnBusinessRuleException) except Exception as logErrorMessageException: log.debug(getCompleteResponseByException, 'Error logging exception at controller', exception=logErrorMessageException) log.error(getCompleteResponseByException, 'Error processing request', exception) return validateAndReturnResponse( handleAdditionalResponseHeadersIfNeeded(completeResponse)) except Exception as unexpectedException: log.error(getCompleteResponseByException, 'Error while building exception return', unexpectedException) log.error(getCompleteResponseByException, 'Error processing request', exception) return validateAndReturnResponse( (ExceptionHandler.getDefaultBodyException(), {}, ExceptionHandler.DEFAULT_STATUS))
def failure(self, message, exception, muteStackTrace=False): if c.TRUE == self.failureStatus: log.failure(self.__class__, message, exception, muteStackTrace=muteStackTrace)
def shutdown(apiInstance, appInstance): try: apiInstance.schedulerManager.shutdown(wait=False) except Exception as exception: log.failure(shutdown, 'Not possible to close APScheduler schedulers', exception) log.success(shutdown, 'APScheduler schedulers successfully closed')
def innerResourceInstanceMethod(*args, **kwargs): f'''(*args, {FlaskUtil.KW_HEADERS}={{}}, {FlaskUtil.KW_PARAMETERS}={{}}, **kwargs)''' # r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # r.headers["Pragma"] = "no-cache" # r.headers["Expires"] = "0" # r.headers['Cache-Control'] = 'public, max-age=0' resourceInstance = args[0] completeResponse = None log.info( resourceInstanceMethod, f'[CONTROLLER] {FlaskUtil.safellyGetVerb()} - {FlaskUtil.safellyGetUrl()}' ) try: completeResponse = handleAnyControllerMethodRequest( args, kwargs, consumes, resourceInstance, resourceInstanceMethod, contextRequired, apiKeyRequired, roleRequired, requestHeaderClass, requestParamClass, requestClass, logRequest, muteStacktraceOnBusinessRuleException) validateCompleteResponse(responseClass, completeResponse) except Exception as exception: log.log( innerResourceInstanceMethod, 'Failure at controller method execution. Getting complete response as exception', exception=exception, muteStackTrace=True) completeResponse = getCompleteResponseByException( exception, resourceInstance, resourceInstanceMethod, muteStacktraceOnBusinessRuleException) ###- request.method: GET ###- request.url: http://127.0.0.1:5000/alert/dingding/test?x=y ###- request.base_url: http://127.0.0.1:5000/alert/dingding/test ###- request.url_charset: utf-8 ###- request.url_root: http://127.0.0.1:5000/ ###- str(request.url_rule): /alert/dingding/test ###- request.host_url: http://127.0.0.1:5000/ ###- request.host: 127.0.0.1:5000 ###- request.script_root: ###- request.path: /alert/dingding/test ###- request.full_path: /alert/dingding/test?x=y ###- request.args: ImmutableMultiDict([('x', 'y')]) ###- request.args.get('x'): y try: status = HttpStatus.map(completeResponse[-1]) additionalResponseHeaders = completeResponse[1] if ObjectHelper.isNotNone(resourceInstance.responseHeaders): additionalResponseHeaders = { **resourceInstance.responseHeaders, **additionalResponseHeaders } if ObjectHelper.isNotNone(responseHeaders): additionalResponseHeaders = { **responseHeaders, **additionalResponseHeaders } responseBody = completeResponse[0] if ObjectHelper.isNotNone( completeResponse[0]) else { 'message': status.enumName } httpResponse = FlaskUtil.buildHttpResponse( additionalResponseHeaders, responseBody, status.enumValue, produces) except Exception as exception: log.failure( innerResourceInstanceMethod, f'Failure while parsing complete response: {completeResponse}. Returning simplified version of it', exception, muteStackTrace=True) completeResponse = getCompleteResponseByException( Exception('Not possible to handle complete response'), resourceInstance, resourceInstanceMethod, muteStacktraceOnBusinessRuleException) httpResponse = FlaskUtil.buildHttpResponse( completeResponse[1], completeResponse[0], completeResponse[-1].enumValue, produces) try: if resourceInstance.logResponse or logResponse: log.prettyJson( resourceInstanceMethod, '[CONTROLLER] Response', { 'headers': FlaskUtil.safellyGetResponseHeaders(httpResponse), 'body': FlaskUtil.safellyGetFlaskResponseJson( httpResponse ), ###- json.loads(Serializer.jsonifyIt(responseBody)) 'status': status }, condition=True, logLevel=log.INFO) except Exception as exception: log.failure(innerResourceInstanceMethod, 'Not possible to log response properly', exception) return httpResponse