def publicControllerMethod(args, kwargs, contentType, resourceInstance, resourceInstanceMethod, requestHeaderClass, requestParamClass, requestClass, logRequest): if resourceInstanceMethod.__name__ in OpenApiManager.ABLE_TO_RECIEVE_BODY_LIST and requestClass: requestBodyAsJson = getRequestBodyAsJson(contentType, requestClass) if logRequest: log.prettyJson(resourceInstanceMethod, 'bodyRequest', requestBodyAsJson, condition=logRequest, logLevel=log.DEBUG) if Serializer.requestBodyIsPresent(requestBodyAsJson): serializerReturn = Serializer.convertFromJsonToObject( requestBodyAsJson, requestClass) args = getArgsWithSerializerReturnAppended(args, serializerReturn) addToKwargs(KW_HEADERS, requestHeaderClass, request.headers, kwargs) addToKwargs(KW_PARAMETERS, requestParamClass, request.args, kwargs) response = resourceInstanceMethod(resourceInstance, *args[1:], **kwargs) if response and Serializer.isSerializerCollection(response) and 2 == len( response): return response raise GlobalException.GlobalException( logMessage= f'''Bad implementation of {resourceInstance.__class__.__name__}.{resourceInstanceMethod.__class__.__name__}() controller method''' )
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 innerResourceInstanceMethod(*args,**kwargs) : resourceInstance = args[0] completeResponse = None if logRequest : log.prettyJson( resourceInstanceMethod, 'bodyRequest', json.loads(Serializer.jsonifyIt(args[1:])), condition = logRequest, logLevel = log.DEBUG ) try : FlaskManager.validateKwargs( kwargs, resourceInstance, innerResourceInstanceMethod, requestHeaderClass = requestHeaderClass, requestParamClass = requestParamClass ) FlaskManager.validateArgs(args, requestClass, innerResourceInstanceMethod) completeResponse = resourceInstanceMethod(*args,**kwargs) FlaskManager.validateResponseClass(responseClass, completeResponse) except Exception as exception : log.warning(innerResourceInstanceMethod, 'Not posssible to complete request', exception=exception) raise exception controllerResponse = completeResponse[0] if ObjectHelper.isNotNone(completeResponse[0]) else {'message' : completeResponse[1].enumName} if logResponse : log.prettyJson( resourceInstanceMethod, 'bodyResponse', json.loads(Serializer.jsonifyIt(controllerResponse)), condition = logResponse, logLevel = log.DEBUG ) return completeResponse[0]
def getJwtMannager(appInstance, jwtSecret, algorithm=None, headerName=None, headerType=None): if not jwtSecret: log.warning( getJwtMannager, f'Not possible to instanciate sessionManager{c.DOT_SPACE_CAUSE}Missing jwt secret at {ConfigurationKeyConstant.API_SESSION_SECRET}' ) else: jwtManager = JwtManager( jwtSecret, ConverterStatic.getValueOrDefault( algorithm, JwtConstant.DEFAULT_JWT_SESSION_ALGORITHM), ConverterStatic.getValueOrDefault( headerName, JwtConstant.DEFAULT_JWT_SESSION_HEADER_NAME), ConverterStatic.getValueOrDefault( headerType, JwtConstant.DEFAULT_JWT_SESSION_HEADER_TYPE)) if SettingHelper.activeEnvironmentIsLocal(): info = { 'secret': jwtManager.secret, 'algorithm': jwtManager.algorithm, 'headerName': jwtManager.headerName, 'headerType': jwtManager.headerType } log.prettyJson(getJwtMannager, f'JWT session', info, logLevel=log.SETTING) return jwtManager
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 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 innerResourceInstanceMethod(*args, **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 try: if ObjectHelper.isNotEmptyCollection(roleRequired): completeResponse = securedControllerMethod( args, kwargs, consumes, resourceInstance, resourceInstanceMethod, roleRequired, requestHeaderClass, requestParamClass, requestClass, logRequest) else: completeResponse = publicControllerMethod( args, kwargs, consumes, resourceInstance, resourceInstanceMethod, requestHeaderClass, requestParamClass, requestClass, logRequest) # print(f'completeResponse: {completeResponse}') validateResponseClass(responseClass, completeResponse) except Exception as exception: # print(exception) completeResponse = getCompleteResponseByException( exception, resourceInstance, resourceInstanceMethod) ###- 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 controllerResponse = completeResponse[0] if ObjectHelper.isNotNone( completeResponse[0]) else { 'message': completeResponse[1].enumName } status = completeResponse[1] if logResponse: log.prettyJson(resourceInstanceMethod, 'bodyResponse', json.loads( Serializer.jsonifyIt(controllerResponse)), condition=logResponse, logLevel=log.DEBUG) return jsonifyResponse(controllerResponse, produces, status)
def doLogRequest(verb, url, body, params, headers, logRequest): log.info(resourceInstanceMethod, f'[CLIENT ] {verb} - {url}') if logRequest: log.prettyJson( resourceInstanceMethod, '[CLIENT ] Request', { 'headers': ConverterStatic.getValueOrDefault(headers, dict()), 'query': ConverterStatic.getValueOrDefault(params, dict()), 'body': ConverterStatic.getValueOrDefault(body, dict()) }, condition = True, logLevel = log.INFO )
def getJwtMannager(appInstance, jwtSecret, algorithm=None, headerName=None, headerType=None): if ObjectHelper.isNone(jwtSecret): log.warning( getJwtMannager, f'Not possible to instanciate securityManager{c.DOT_SPACE_CAUSE}Missing jwt secret at {ConfigurationKeyConstant.API_SECURITY_SECRET}' ) else: jwtMannager = JWTManager(appInstance) appInstance.config[JwtConstant.KW_JWT_SECRET_KEY] = jwtSecret appInstance.config[JwtConstant.KW_JWT_BLACKLIST_ENABLED] = True appInstance.config[ JwtConstant.KW_JWT_ALGORITHM] = ConverterStatic.getValueOrDefault( algorithm, JwtConstant.DEFAULT_JWT_SECURITY_ALGORITHM) appInstance.config[ JwtConstant. KW_JWT_HEADER_NAME] = ConverterStatic.getValueOrDefault( headerName, JwtConstant.DEFAULT_JWT_SECURITY_HEADER_NAME) appInstance.config[ JwtConstant. KW_JWT_HEADER_TYPE] = ConverterStatic.getValueOrDefault( headerType, JwtConstant.DEFAULT_JWT_SECURITY_HEADER_TYPE) if SettingHelper.activeEnvironmentIsLocal(): info = { 'secret': jwtSecret, 'algorithm': appInstance.config[JwtConstant.KW_JWT_ALGORITHM], 'headerName': appInstance.config[JwtConstant.KW_JWT_HEADER_NAME], 'headerType': appInstance.config[JwtConstant.KW_JWT_HEADER_TYPE] } log.prettyJson(getJwtMannager, f'JWT security', info, logLevel=log.SETTING) return jwtMannager
def getUrl(self, dialect): log.log(self.getUrl, 'Loading repository configuration') url = EnvironmentHelper.get(self.ENV_DATABASE_URL) if isNeitherNoneNorBlank(url): dialect = None driver = None database = None username = None password = None host = None port = None schema = None log.log( self.getUrl, f'Prioritising repository url in {self.ENV_DATABASE_URL} environment variable' ) else: url = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_URL}' ) if isNeitherNoneNorBlank(url): dialect = None driver = None database = None username = None password = None host = None port = None schema = None log.log(self.getUrl, f'Prioritising repository url in yamel configuration') else: url = c.NOTHING driver = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_DRIVER}' ) database = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_DATABASE}' ) username = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_USERNAME}' ) password = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_PASSWORD}' ) host = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_HOST}' ) port = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_PORT}' ) schema = self.globals.getSetting( f'{self.KW_API}{c.DOT}{self.KW_DATABASE}{c.DOT}{self.KW_REPOSITORY_SCHEMA}' ) if isNeitherNoneNorBlank(username) and isNeitherNoneNorBlank( password): url += f'{username}{c.COLON}{password}' if isNeitherNoneNorBlank(host) and isNeitherNoneNorBlank(port): url += f'{c.ARROBA}{host}{c.COLON}{port}' url += c.SLASH database = f'{database}' if isNeitherNoneNorBlank( database ) else f'{self.DEFAULT_LOCAL_STORAGE_NAME if ObjectHelper.isNone(self.globals.apiName) else self.globals.apiName}{c.DOT}{self.EXTENSION}' if not isNeitherNoneNorBlank(dialect): dialect = self.DEFAULT_DIALECT plusDriverOrNothing = f'{c.PLUS}{driver}' if isNeitherNoneNorBlank( driver) else c.NOTHING dialectAndDriver = f'''{dialect}{plusDriverOrNothing}''' url = f'{dialectAndDriver}{c.COLON}{c.DOUBLE_SLASH}{url}{database}' log.log(self.getUrl, 'Prioritising repository yamel configuration') if SettingHelper.activeEnvironmentIsLocal(): log.prettyJson( self.getUrl, 'Repository configuations', { **self.globals.getSetting(f'{self.KW_API}{c.DOT}{self.KW_DATABASE}'), **{ 'dialect': dialect, 'driver': driver, 'database': database, 'username': username, 'password': password, 'host': host, 'port': port, 'schema': schema, 'url': url } }, logLevel=log.SETTING) # log.prettyPython(self.getUrl, 'url', url, logLevel=log.LOG) return url
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