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 safellyGetUrl(): url = None try: url = str(request.url) except Exception as exception: log.log(safellyGetUrl, 'Not possible to get url', exception=exception) return url
def getErrorMessage(clientResponse, exception=None): completeErrorMessage = f'{HttpClientConstant.ERROR_AT_CLIENT_CALL_MESSAGE}{c.DOT_SPACE}{HttpClientConstant.CLIENT_DID_NOT_SENT_ANY_MESSAGE}' errorMessage = HttpClientConstant.CLIENT_DID_NOT_SENT_ANY_MESSAGE possibleErrorMessage = None bodyAsJson = {} try : bodyAsJson = clientResponse.json() except Exception as innerException : bodyAsJsonException = FlaskUtil.safellyGetResponseJson(clientResponse) log.log(getErrorMessage, f'Invalid client response: {bodyAsJsonException}', exception=innerException) log.debug(getErrorMessage, f'Not possible to get error message from client response: {bodyAsJsonException}. Proceeding with value {bodyAsJson} by default', exception=innerException, muteStackTrace=True) try: if ObjectHelper.isNotNone(clientResponse): if ObjectHelper.isDictionary(bodyAsJson): possibleErrorMessage = bodyAsJson.get('message', bodyAsJson.get('error')).strip() if ObjectHelper.isList(bodyAsJson) and 0 < len(bodyAsJson): possibleErrorMessage = bodyAsJson[0].get('message', bodyAsJson[0].get('error')).strip() if ObjectHelper.isNotNone(possibleErrorMessage) and StringHelper.isNotBlank(possibleErrorMessage): errorMessage = f'{c.LOG_CAUSE}{possibleErrorMessage}' else: log.debug(getErrorMessage, f'Client response {FlaskUtil.safellyGetResponseJson(clientResponse)}') exceptionPortion = HttpClientConstant.ERROR_AT_CLIENT_CALL_MESSAGE if ObjectHelper.isNone(exception) or StringHelper.isBlank(exception) else str(exception) completeErrorMessage = f'{exceptionPortion}{c.DOT_SPACE}{errorMessage}' except Exception as exception: log.warning(getErrorMessage, f'Not possible to get error message. Returning {completeErrorMessage} by default', exception=exception) return completeErrorMessage
def validateGeneralSessionAndReturnItDecoded(self, rawJwt=None, options=None): decodedSessionToken = rawJwt try: decodedSessionToken = self.getDecodedToken( rawJwt=decodedSessionToken, options=options) assert ObjectHelper.isDictionary( decodedSessionToken ), f'Invalid session payload type. It should be a dictionary, bu it is {type(decodedSessionToken)}' assert ObjectHelper.isNotEmpty( decodedSessionToken), 'Session cannot be empty' jti = getJti(rawJwt=decodedSessionToken) assert ObjectHelper.isNotNone(jti), f'JWT jti cannot be None' assert jti not in BLACK_LIST, f'Session {jti} already revoked' nbf = getNfb(rawJwt=decodedSessionToken) assert ObjectHelper.isNotNone(nbf), f'JWT nbf cannot be None' assert UtcDateTimeUtil.now() >= UtcDateTimeUtil.ofTimestamp( nbf ), f'JWT session token not valid before {UtcDateTimeUtil.ofTimestamp(nbf)}' expiration = getExpiration(rawJwt=decodedSessionToken) assert UtcDateTimeUtil.now() <= UtcDateTimeUtil.ofTimestamp( expiration ), f'JWT session token expired at {UtcDateTimeUtil.ofTimestamp(expiration)}' except Exception as exception: addAccessTokenToBlackList(rawJwt=decodedSessionToken) log.log(self.validateGeneralSessionAndReturnItDecoded, f'Adding {rawJwt} (or current accces) to blackList', exception=exception, muteStackTrace=True) raise exception return decodedSessionToken
def validateCompleteResponse(responseClass, completeResponse): if isNotPythonFrameworkHttpsResponseBody(completeResponse): raiseBadResponseImplementation( f'It should be a tuple like this: ({"RESPONSE_CLASS" if ObjectHelper.isNone(responseClass) else responseClass if ObjectHelper.isNotList(responseClass) else responseClass[0]}, HEADERS, HTTPS_CODE). But it is: {completeResponse}' ) if ObjectHelper.isNotNone(responseClass): if Serializer.isSerializerList(responseClass): if 0 == len(responseClass): log.log(validateCompleteResponse, f'"responseClass" was not defined') elif 1 == len(responseClass): if ObjectHelper.isNotList(responseClass[0]): if not isinstance(completeResponse[0], responseClass[0]): raiseBadResponseImplementation( f'Response does not match expected class. Expected "{responseClass[0].__name__}", but got "{completeResponse[0].__class__.__name__}"' ) elif ObjectHelper.isNotList(responseClass[0][0]): if ObjectHelper.isNotList(completeResponse[0]): raiseBadResponseImplementation( f'Response is not a list. Expected "{responseClass[0].__class__.__name__}", but found "{completeResponse[0].__class__.__name__}"' ) elif Serializer.isSerializerList( completeResponse[0] ) and 0 < len(completeResponse[0]) and not isinstance( completeResponse[0][0], responseClass[0][0]): raiseBadResponseImplementation( f'Response element class does not match expected element class. Expected "{responseClass[0][0].__name__}", response "{completeResponse[0][0].__class__.__name__}"' ) else: if not isinstance(completeResponse[0], responseClass): raiseBadResponseImplementation( f'Response does not match expected class. Expected "{responseClass.__name__}", but got "{completeResponse[0].__class__.__name__}"' ) else: log.log(validateCompleteResponse, f'"responseClass" was not defined')
def safellyGetVerb(): verb = None try: verb = str(request.method) except Exception as exception: log.log(safellyGetVerb, 'Not possible to get verb', exception=exception) return verb
def innerResourceInstanceMethod(*args, **kwargs): f'''(*args, {FlaskUtil.KW_HEADERS}={{}}, {FlaskUtil.KW_PARAMETERS}={{}}, **kwargs)''' resourceInstance = args[0] clientResponse = None completeResponse = None try : FlaskManager.validateKwargs( kwargs, resourceInstance, resourceInstanceMethod, requestHeaderClass, requestParamClass ) FlaskManager.validateArgs(args, requestClass, resourceInstanceMethod) clientResponse = None httpClientEvent = getHttpClientEvent(resourceInstanceMethod, *args, **kwargs) if isinstance(httpClientEvent, ManualHttpClientEvent): completeResponse = httpClientEvent.completeResponse elif isinstance(httpClientEvent, HttpClientEvent): try : clientResponse = HTTP_CLIENT_RESOLVERS_MAP.get( httpClientEvent.verb, raiseHttpClientEventNotFoundException )( resourceInstance, *httpClientEvent.args, **httpClientEvent.kwargs ) except Exception as exception: raiseException(clientResponse, exception) raiseExceptionIfNeeded(clientResponse) completeResponse = getCompleteResponse(clientResponse, responseClass, produces) FlaskManager.validateCompleteResponse(responseClass, completeResponse) else: raise Exception('Unknown http client event') except Exception as exception: log.log(innerResourceInstanceMethod, 'Failure at client method execution', exception=exception, muteStackTrace=True) FlaskManager.raiseAndPersistGlobalException(exception, resourceInstance, resourceInstanceMethod, context=HttpDomain.CLIENT_CONTEXT) clientResponseStatus = completeResponse[-1] clientResponseHeaders = completeResponse[1] clientResponseBody = completeResponse[0] if ObjectHelper.isNotNone(completeResponse[0]) else {'message' : HttpStatus.map(clientResponseStatus).enumName} if resourceInstance.logResponse or logResponse : log.prettyJson( resourceInstanceMethod, '[CLIENT ] Response', { 'headers': clientResponseHeaders, 'body': Serializer.getObjectAsDictionary(clientResponseBody), 'status': clientResponseStatus }, condition = True, logLevel = log.INFO ) if returnOnlyBody: return completeResponse[0] else: return completeResponse
def safellyGetPath(): path = None try: path = str(request.path) except Exception as exception: path = c.FOWARD_SLASH log.log(safellyGetUrl, f'Not possible to get path. Returning {path} by default', exception=exception) return path
def safellyGetData(): dataBody = None try: dataBody = request.get_json(force=True) except Exception as exception: dataBody = {} log.log(safellyGetData, f'Not possible to get data. Returning {dataBody} by default', exception=exception) return dataBody
def safellyGetHost(): host = None try: path = str(request.host) except Exception as exception: host = c.FOWARD_SLASH log.log(safellyGetUrl, f'Not possible to get host. Returning {host} by default', exception=exception) return host
def killProcesses(givenProcess): try: process = psutil.Process(givenProcess.pid) for child in process.children(recursive=True): child.kill() process.kill() except Exception as exception: log.log(killProcesses, 'Error while killing process', exception=exception)
def safellyGetArgs(): args = None try: args = dict(request.args) except Exception as exception: args = {} log.log(safellyGetArgs, f'Not possible to get args. Returning {args} by default', exception=exception) return args if ObjectHelper.isNotNone(args) else dict()
def safellyGetRequestHeadersFromResponse(response): headers = None try: headers = dict(response.request.headers) except Exception as exception: headers = {} log.log( safellyGetRequestHeadersFromResponse, f'Not possible to get request headers from response. Returning {headers} by default', exception=exception) return headers if ObjectHelper.isNotNone(headers) else dict()
def safellyGetHeaders(): headers = None try: headers = dict(request.headers) except Exception as exception: headers = {} log.log( safellyGetHeaders, f'Not possible to get request headers. Returning {headers} by default', exception=exception) return headers if ObjectHelper.isNotNone(headers) else dict()
def safellyGetRequestJsonFromResponse(response): requestBody = None try: requestBody = response.request.body except Exception as exception: requestBody = {} log.log( safellyGetRequestJsonFromResponse, f'Not possible to get request body from response. Returning {requestBody} by default', exception=exception) return requestBody if ObjectHelper.isNotNone(requestBody) else dict()
def safellyGetResponseJson(response): jsonBody = None try: jsonBody = response.json() except Exception as exception: jsonBody = {} log.log( safellyGetResponseJson, f'Not possible to get response body. Returning {jsonBody} by default', exception=exception) return jsonBody
def safellyGetJson(): jsonBody = None try: jsonBody = request.get_json(force=True) except Exception as exception: jsonBody = {} log.log( safellyGetJson, f'Not possible to get request body. Returning {jsonBody} by default', exception=exception) return jsonBody
def safellyGetRequestVerbFromResponse(response): verb = None try: verb = response.request.method except Exception as exception: verb = UNKNOWN_VERB log.log( safellyGetRequestUrlFromResponse, f'Not possible to get request verb from response. Returning {verb} by default', exception=exception) return verb
def safellyGetRequestUrlFromResponse(response): url = None try: url = response.url except Exception as exception: url = c.BLANK log.log( safellyGetRequestUrlFromResponse, f'Not possible to get request url from response. Returning {url} by default', exception=exception) return url if ObjectHelper.isNotNone(url) else c.BLANK
def open(self, hidden=False) : log.log(self.open, 'Started') self.booting = True self.safelyClose() self.browser = self.client.browser.getNewBrowser(hidden=hidden) self.client.browser.maximize(self.browser) sessionId = self.browser.session_id commandExecutor = self.browser.command_executor._url self.service.session.create(sessionId, commandExecutor) self.booted = True self.booting = False log.log(self.open, 'Finished')
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 validateAccessApiKey(self, rawJwt=None, options=None): decodedApiKeyToken = rawJwt try: decodedApiKeyToken = self.validateGeneralApiKeyAndReturnItDecoded( rawJwt=decodedApiKeyToken, options=options) jwtType = getType(rawJwt=decodedApiKeyToken) assert jwtType == JwtConstant.ACCESS_VALUE_TYPE, f'Access apiKey should have type {JwtConstant.ACCESS_VALUE_TYPE}, but it is {jwtType}' except Exception as exception: addAccessTokenToBlackList(rawJwt=decodedApiKeyToken) log.log(self.validateAccessApiKey, f'Adding {rawJwt} (or current accces) to blackList', exception=exception, muteStackTrace=True) raise exception
def validateRefreshSession(self, rawJwt=None, options=None): decodedSessionToken = rawJwt try: decodedSessionToken = self.validateGeneralSessionAndReturnItDecoded( rawJwt=decodedSessionToken, options=options) jwtType = getType(rawJwt=decodedSessionToken) assert jwtType == JwtConstant.REFRESH_VALUE_TYPE, f'Refresh session should have type {JwtConstant.REFRESH_VALUE_TYPE}, but it is {jwtType}' except Exception as exception: addAccessTokenToBlackList(rawJwt=decodedSessionToken) log.log(self.validateRefreshSession, f'Adding {rawJwt} (or current accces) to blackList', exception=exception, muteStackTrace=True) raise exception
def addHeadersListToUrlVerb(verb, url, endPointUrl, requestHeaderClass, documentation): if ObjectHelper.isList(requestHeaderClass) and 0 == len( requestHeaderClass): log.warning( addHeadersListToUrlVerb, f'Invalid request header class. requestHeaderClass: {requestHeaderClass}' ) if ObjectHelper.isNotNone(requestHeaderClass): log.log( addHeadersListToUrlVerb, f'verb: {verb}, url: {url}, requestHeaderClass: {requestHeaderClass}' ) if ObjectHelper.isNotList(requestHeaderClass): for attributeName in ReflectionHelper.getAttributeOrMethodNameList( requestHeaderClass): documentation[k.PATHS][url][verb][k.PARAMETERS].append({ k.NAME: attributeName, k.IN: v.HEADER, k.TYPE: v.STRING, k.REQUIRED: True, k.DESCRIPTION: None }) elif 1 == len(requestHeaderClass): if ObjectHelper.isNotNone(requestHeaderClass[0]): if ObjectHelper.isNotList(requestHeaderClass[0]): addHeadersListToUrlVerb(verb, url, endPointUrl, requestHeaderClass[0], documentation) ###-, where=where elif ObjectHelper.isList(requestHeaderClass[0]) and 1 == len( requestHeaderClass[0]): if ObjectHelper.isNotNone(requestHeaderClass[0] [0]) and ObjectHelper.isNotList( requestHeaderClass[0][0]): # addHeadersListToUrlVerb(verb, url, endPointUrl, requestHeaderClass[0][0], documentation) ###-, where=where log.warning( addHeadersListToUrlVerb, f'Request header class as list not implemented yet. requestHeaderClass: {requestHeaderClass}' ) else: log.warning( addHeadersListToUrlVerb, f'Unexpected request header class. requestHeaderClass: {requestHeaderClass}' )
def importModule(resourceModuleName, muteLogs=False, reload=False, ignoreList=IGNORE_MODULES, required=False): if resourceModuleName not in ignoreList: importException = None try: if reload: IMPORT_CASHE[resourceModuleName] = importlib.reload( resourceModuleName) elif (resourceModuleName not in IMPORT_CASHE or required and ObjectHelper.isNone( IMPORT_CASHE.get(resourceModuleName))): IMPORT_CASHE[resourceModuleName] = importlib.import_module( resourceModuleName) except Exception as exception: importException = exception if not muteLogs: log.log( importModule, f'Not possible to import "{resourceModuleName}" module. Going for a second attempt', exception=exception) try: IMPORT_CASHE[resourceModuleName] = __import__( resourceModuleName) except Exception as innerException: importException = innerException IMPORT_CASHE[resourceModuleName] = None if not muteLogs: log.log( importModule, f'Not possible to import "{resourceModuleName}" module in the second attempt either. Original cause: {str(exception)}. Returning "{IMPORT_CASHE.get(resourceModuleName)}" by default', exception=innerException) if required and ObjectHelper.isNone( IMPORT_CASHE.get(resourceModuleName)): if not importException: try: IMPORT_CASHE[resourceModuleName] = __import__( resourceModuleName) return IMPORT_CASHE.get(resourceModuleName) except Exception as exception: importException = exception dotSpaceCause = f'{c.DOT_SPACE_CAUSE}{getExceptionTextWithoutDotAtTheEnd(importException)}' raise Exception( f'Not possible to import module "{resourceModuleName}"{dotSpaceCause}{c.BLANK if dotSpaceCause.endswith(DOT_SPACE_CHECK_LOG_LEVEL_LOGS_FOR_MORE_INFORMATION) else DOT_SPACE_CHECK_LOG_LEVEL_LOGS_FOR_MORE_INFORMATION}' ) return IMPORT_CASHE.get(resourceModuleName)
def getNullableChildDtoClass(attributeName, dtoClass, verb, url, documentation): log.log( getNullableChildDtoClass, f'attributeName: {attributeName}, dtoClass: {dtoClass}, verb: {verb}, url: {url}' ) childDtoClass = Serializer.getTargetClassFromFatherClassAndChildMethodName( dtoClass, attributeName) log.log(getNullableChildDtoClass, f'childDtoClass: {childDtoClass}') if childDtoClass: if ReflectionHelper.getName(type(type)) == ReflectionHelper.getName( type(childDtoClass)): addDtoToUrlVerb(verb, url, childDtoClass, documentation) else: addDtoToUrlVerb(verb, url, type(childDtoClass), documentation) return childDtoClass
def getDtoSchema(attributeName, attributeType, dtoClass): log.log( getDtoSchema, f'attributeName: {attributeName}, attributeType: {attributeType}, dtoClass: {dtoClass}' ) if dtoClass: dtoName = getDtoDocumentationName(dtoClass) if v.ARRAY == attributeType: return { k.TYPE: v.ARRAY, k.ITEMS: { k.TYPE: v.OBJECT, k.S_REF: getRefferenceValue(dtoName) } } if v.OBJECT == attributeType: return {k.S_REF: getRefferenceValue(dtoName)} return {}
def innerResourceInstanceMethod(*args, **kwargs): resourceInstance = args[0] completeResponse = None try: FlaskManager.validateArgs(args, requestClass, resourceInstanceMethod) completeResponse = resourceInstanceMethod(*args, **kwargs) ###- This simple client cannot handle headers or anything this much elegant if ObjectHelper.isTuple( completeResponse) and 0 < len(completeResponse): completeResponse = completeResponse[0] except Exception as exception: log.log(innerResourceInstanceMethod, 'Failure at client method execution', exception=exception, muteStackTrace=True) raise exception return completeResponse
def overrideDocumentation(apiInstance): try : documentationAsString = StringHelper.prettyJson(apiInstance.documentation) documentationFolderPath = getDocumentationFolderPath(apiInstance) documentationFilePath = getDocumentationFilePath(apiInstance) try: if not EnvironmentHelper.isDirectory(documentationFolderPath) : accessRights = 0o777 # define the access rights. write and read EnvironmentHelper.makeDirectory(documentationFolderPath, accessRights) except OSError as exception: exceptionMessage = f'Creation of the directory {documentationFilePath} failed' log.log(overrideDocumentation, exceptionMessage, exception=exception) raise Exception(exceptionMessage) with open(getDocumentationFilePath(apiInstance), c.OVERRIDE, encoding=c.ENCODING) as documentationFile : documentationFile.write(documentationAsString) except Exception as exception : log.log(overrideDocumentation,"Error while overriding OpenApi documentation file",exception) raise exception
def safellyGetResponseStatus(response): status = None try: status = response.status_code except Exception as exception: status = HttpStatus.INTERNAL_SERVER_ERROR log.log( safellyGetResponseStatus, f'Not possible to get response status. Returning {status} by default', exception=exception) try: status = HttpStatus.map(status if ObjectHelper.isNotNone(status) else HttpStatus.INTERNAL_SERVER_ERROR) except Exception as exception: status = HttpStatus.INTERNAL_SERVER_ERROR log.log( safellyGetResponseStatus, f'Not possible to parse response status. Returning {status} by default', exception=exception) return status