Skip to content

Commit f9353ec

Browse files
committed
feat: adding schedulers
1 parent 5d0a319 commit f9353ec

14 files changed

Lines changed: 110 additions & 64 deletions

File tree

‎python_framework/__init__.py‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from python_framework.api.src.helper import Serializer
44

5-
from python_framework.api.src.service import GlobalException
5+
from python_framework.api.src.service.GlobalException import GlobalException
66
from python_framework.api.src.service import Security
77
from python_framework.api.src.service import SqlAlchemyProxy
88
from python_framework.api.src.service import WebBrowser
@@ -15,20 +15,19 @@
1515

1616
from python_framework.api.src.enumeration.HttpStatus import HttpStatus
1717
from python_framework.api.src.enumeration.ActuatorHealthStatus import ActuatorHealthStatus
18+
from python_framework.api.src.enumeration.SchedulerType import SchedulerType
1819

1920
from python_framework.api.src.model import FrameworkModel
2021
from python_framework.api.src.model import ErrorLog
2122
from python_framework.api.src.model import ActuatorHealth
2223

2324
from python_framework.api.src.dto import ActuatorHealthDto
24-
2525
from python_framework.api.src.controller import ActuatorHealthController
26-
2726
from python_framework.api.src.converter import ActuatorHealthConverter
28-
2927
from python_framework.api.src.service import ActuatorHealthService
30-
3128
from python_framework.api.src.repository import ActuatorHealthRepository
3229

3330
from python_framework.api.src.annotation.EnumAnnotation import *
3431
from python_framework.api.src.service.flask.FlaskManager import *
32+
from python_framework.api.src.annotation.SchedulerAnnotation import *
33+
from python_framework.api.src.annotation.ServiceAnnotation import *

‎python_framework/api/src/annotation/SchedulerAnnotation.py‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
from python_helper import ReflectionHelper, ObjectHelper, log, Function
33
from python_framework.api.src.service.flask import FlaskManager
44

5-
65
@Function
76
def Scheduler() :
87
def Wrapper(OuterClass, *args, **kwargs):
98
log.debug(Scheduler,f'''wrapping {OuterClass.__name__}''')
10-
apiInstance = FlaskManager.getApi()
119
class InnerClass(OuterClass):
1210
def __init__(self,*args,**kwargs):
1311
log.debug(OuterClass,f'in {InnerClass.__name__}.__init__(*{args},**{kwargs})')
12+
apiInstance = FlaskManager.getApi()
1413
OuterClass.__init__(self,*args,**kwargs)
1514
self.globals = apiInstance.globals
1615
self.service = apiInstance.resource.service
@@ -22,16 +21,20 @@ def __init__(self,*args,**kwargs):
2221
def SchedulerMethod(*methodArgs, requestClass=None, **methodKwargs) :
2322
def innerMethodWrapper(resourceInstanceMethod, *innerMethodArgs, **innerMethodKwargs) :
2423
log.debug(SchedulerMethod,f'''wrapping {resourceInstanceMethod.__name__}''')
24+
apiInstance = resourceInstanceMethod.__self__.globals.api
2525
methodClassName = ReflectionHelper.getMethodClassName(resourceInstanceMethod)
26-
apiInstance = FlaskManager.getApi()
2726
methodName = ReflectionHelper.getName(resourceInstanceMethod)
28-
shedulerId = methodKwargs.get('id', None)
29-
if ObjectHelper.isNone(shedulerId) :
30-
shedulerId = f'{methodClassName}{c.DOT}{methodName}'
27+
shedulerId = methodKwargs.get('id', f'{methodClassName}{c.DOT}{methodName}')
28+
instancesUpTo = methodKwargs.get('instancesUpTo', 1)
29+
day_of_week = methodKwargs.get('daysOfWeek', None)
30+
methodKwargs['id'] = shedulerId
31+
methodKwargs['max_instances'] = instancesUpTo
32+
methodKwargs['day_of_week'] = day_of_week
3133
@apiInstance.scheduler.task(*methodArgs, **methodKwargs)
3234
def innerResourceInstanceMethod(*args, **kwargs) :
3335
args = FlaskManager.getArgumentInFrontOfArgs(args, ReflectionHelper.getAttributeOrMethod(apiInstance.resource.scheduler, methodClassName[:-len('Scheduler')].lower()))
3436
resourceInstance = args[0]
37+
methodReturn = None
3538
try :
3639
FlaskManager.validateArgs(args,requestClass,innerResourceInstanceMethod)
3740
methodReturn = resourceInstanceMethod(*args,**kwargs)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from python_helper import Constant as c
2+
from python_helper import ReflectionHelper, ObjectHelper, log, Function
3+
from python_framework.api.src.service.flask import FlaskManager
4+
5+
@Function
6+
def Service() :
7+
def Wrapper(OuterClass, *args, **kwargs):
8+
log.debug(Service,f'''wrapping {OuterClass.__name__}''')
9+
class InnerClass(OuterClass):
10+
def __init__(self,*args,**kwargs):
11+
log.debug(OuterClass,f'in {InnerClass.__name__}.__init__(*{args},**{kwargs})')
12+
OuterClass.__init__(self,*args,**kwargs)
13+
apiInstance = FlaskManager.getApi()
14+
self.globals = apiInstance.globals
15+
self.service = apiInstance.resource.service
16+
self.client = apiInstance.resource.client
17+
self.repository = apiInstance.resource.repository
18+
self.validator = apiInstance.resource.validator
19+
self.mapper = apiInstance.resource.mapper
20+
self.helper = apiInstance.resource.helper
21+
self.converter = apiInstance.resource.converter
22+
ReflectionHelper.overrideSignatures(InnerClass, OuterClass)
23+
return InnerClass
24+
return Wrapper
25+
26+
@Function
27+
def ServiceMethod(requestClass=None):
28+
def innerMethodWrapper(resourceInstanceMethod,*args,**kwargs) :
29+
log.debug(ServiceMethod,f'''wrapping {resourceInstanceMethod.__name__}''')
30+
def innerResourceInstanceMethod(*args,**kwargs) :
31+
resourceInstance = args[0]
32+
try :
33+
FlaskManager.validateArgs(args,requestClass,innerResourceInstanceMethod)
34+
methodReturn = resourceInstanceMethod(*args,**kwargs)
35+
except Exception as exception :
36+
FlaskManager.raiseGlobalException(exception, resourceInstance, resourceInstanceMethod)
37+
return methodReturn
38+
ReflectionHelper.overrideSignatures(innerResourceInstanceMethod, resourceInstanceMethod)
39+
return innerResourceInstanceMethod
40+
return innerMethodWrapper
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from python_framework.api.src.annotation.EnumAnnotation import Enum, EnumItem
2+
3+
@Enum(associateReturnsTo='key')
4+
class HttpStatusEnumeration() :
5+
CHRONOS = EnumItem(key='cron')
6+
INTERVAL = EnumItem(key='interval')
7+
8+
SchedulerType = HttpStatusEnumeration()

‎python_framework/api/src/service/ActuatorHealthService.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from python_helper import ObjectHelper, log
33
from python_framework.api.src.enumeration.ActuatorHealthStatus import ActuatorHealthStatus
44
from python_framework.api.src.model import ActuatorHealth
5-
from python_framework.api.src.service.flask.FlaskManager import Service, ServiceMethod
5+
from python_framework.api.src.annotation.ServiceAnnotation import Service, ServiceMethod
66

77
@Service()
88
class ActuatorHealthService:

‎python_framework/api/src/service/GlobalException.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def validateArgs(self, method, objectRequest, expecteObjectClass):
6969
if proceedValidation and (objectRequest and not type(expecteObjectClass) == type(objectRequest.__class__) and expecteObjectClass.__name__ == objectRequest.__class__.__name__) :
7070
raise GlobalException(logMessage = f'Invalid args. {self.__class__}.{method} call got an unnexpected object request: {objectRequest.__class__}. It should be {expecteObjectClass}')
7171
except Exception as exception :
72-
log.error(expecteObjectClass.__class__, f'Failed to validate args of {method.__name__} method', exception)
72+
log.failure(expecteObjectClass.__class__, f'Failed to validate args of {method.__name__} method', exception)
7373
raise GlobalException(logMessage = f'Failed to validate args of {method.__name__} method{DOT_SPACE_CAUSE}{str(exception)}')
7474

7575
@Function

‎python_framework/api/src/service/flask/FlaskManager.py‎

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
'LocalTestApi'
3232
]
3333
KW_CONTROLLER_RESOURCE = 'Controller'
34+
KW_SCHEDULER_RESOURCE = 'Scheduler'
3435
KW_SERVICE_RESOURCE = 'Service'
3536
KW_CLIENT_RESOURCE = 'Client'
3637
KW_REPOSITORY_RESOURCE = 'Repository'
@@ -42,6 +43,7 @@
4243
KW_CONTROLLER_RESOURCE : [
4344
'ActuatorHealthController'
4445
],
46+
KW_SCHEDULER_RESOURCE : [],
4547
KW_SERVICE_RESOURCE : [
4648
'ActuatorHealthService'
4749
],
@@ -209,8 +211,9 @@ def getResourceFinalName(resourceInstance, resourceName=None) :
209211
if not resourceName :
210212
resourceName = resourceInstance.__class__.__name__
211213
for resourceType in KW_RESOURCE_LIST :
212-
if resourceType in resourceName :
214+
if resourceName.endswith(resourceType) :
213215
resourceName = resourceName.replace(resourceType, c.NOTHING)
216+
print(f'{resourceName[0].lower()}{resourceName[1:]}')
214217
return f'{resourceName[0].lower()}{resourceName[1:]}'
215218

216219
@Function
@@ -229,7 +232,8 @@ def setResource(apiInstance, resourceInstance, resourceName=None) :
229232
@Function
230233
def bindResource(apiInstance,resourceInstance) :
231234
validateFlaskApi(apiInstance)
232-
setResource(getattr(apiInstance.resource, getResourceType(resourceInstance).lower()), resourceInstance)
235+
validateResourceInstance(resourceInstance)
236+
setResource(ReflectionHelper.getAttributeOrMethod(apiInstance.resource, getResourceType(resourceInstance).lower()), resourceInstance)
233237

234238
@Function
235239
def validateArgs(args, requestClass, method) :
@@ -344,43 +348,6 @@ def innerResourceInstanceMethod(*args,**kwargs) :
344348
return innerResourceInstanceMethod
345349
return innerMethodWrapper
346350

347-
@Function
348-
def Service() :
349-
def Wrapper(OuterClass, *args, **kwargs):
350-
log.debug(Service,f'''wrapping {OuterClass.__name__}''')
351-
class InnerClass(OuterClass):
352-
def __init__(self,*args,**kwargs):
353-
log.debug(OuterClass,f'in {InnerClass.__name__}.__init__(*{args},**{kwargs})')
354-
OuterClass.__init__(self,*args,**kwargs)
355-
apiInstance = getApi()
356-
self.globals = apiInstance.globals
357-
self.service = apiInstance.resource.service
358-
self.client = apiInstance.resource.client
359-
self.repository = apiInstance.resource.repository
360-
self.validator = apiInstance.resource.validator
361-
self.mapper = apiInstance.resource.mapper
362-
self.helper = apiInstance.resource.helper
363-
self.converter = apiInstance.resource.converter
364-
ReflectionHelper.overrideSignatures(InnerClass, OuterClass)
365-
return InnerClass
366-
return Wrapper
367-
368-
@Function
369-
def ServiceMethod(requestClass=None):
370-
def innerMethodWrapper(resourceInstanceMethod,*args,**kwargs) :
371-
log.debug(ServiceMethod,f'''wrapping {resourceInstanceMethod.__name__}''')
372-
def innerResourceInstanceMethod(*args,**kwargs) :
373-
resourceInstance = args[0]
374-
try :
375-
validateArgs(args,requestClass,innerResourceInstanceMethod)
376-
methodReturn = resourceInstanceMethod(*args,**kwargs)
377-
except Exception as exception :
378-
raiseGlobalException(exception, resourceInstance, resourceInstanceMethod)
379-
return methodReturn
380-
ReflectionHelper.overrideSignatures(innerResourceInstanceMethod, resourceInstanceMethod)
381-
return innerResourceInstanceMethod
382-
return innerMethodWrapper
383-
384351
@Function
385352
def Client() :
386353
def Wrapper(OuterClass, *args, **kwargs):
@@ -645,4 +612,8 @@ def validateFlaskApi(instance) :
645612
apiClassName = flask_restful.Api.__name__
646613
moduleName = flask_restful.__name__
647614
if not apiClassName == getClassName(instance) and apiClassName == getQualitativeName(instance) and moduleName == getModuleName(instance) :
648-
raise Exception(f'Globals can only be added to a "flask_restful.Api" instance. Not to {apiInstance}')
615+
raise Exception(f'Invalid "flask_restful.Api" instance. {apiInstance} is not an Api instance')
616+
617+
def validateResourceInstance(resourceInstance) :
618+
if ObjectHelper.isNone(resourceInstance) :
619+
raise Exception(f'Resource cannot be None')

‎python_framework/api/src/service/flask/ResourceManager.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ def addServiceListTo(apiInstance,serviceList) :
150150
for service in serviceList :
151151
apiInstance.bindResource(apiInstance,service())
152152

153+
@Function
154+
def addSchedulerListTo(apiInstance,schedulerList) :
155+
for scheduler in schedulerList :
156+
apiInstance.bindResource(apiInstance,scheduler())
157+
153158
@Function
154159
def addClientListTo(apiInstance,clientList) :
155160
for client in clientList :
@@ -199,6 +204,7 @@ def addFlaskApiResources(
199204
appInstance,
200205
jwtInstance,
201206
controllerList,
207+
schedulerList,
202208
serviceList,
203209
clientList,
204210
repositoryList,
@@ -217,6 +223,7 @@ def addFlaskApiResources(
217223
addRepositoryTo(apiInstance, repositoryList, model)
218224
addServiceListTo(apiInstance, serviceList)
219225
addClientListTo(apiInstance, clientList)
226+
addSchedulerListTo(apiInstance, schedulerList)
220227
addControllerListTo(apiInstance, controllerList)
221228
addValidatorListTo(apiInstance, validatorList)
222229
addMapperListTo(apiInstance, mapperList)

‎python_framework/api/test/TestApiTest.py‎

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,31 @@ def appRun_whenEnvironmentIsLocalFromLocalConfig_withSuccess_0() :
102102
time.sleep(ESTIMATED_BUILD_TIME_IN_SECONDS)
103103

104104
# act
105-
responseGetHealth = requests.get(BASE_URL + GET_ACTUATOR_HEALTH_CONTROLLER)
105+
import requests
106+
import logging
107+
import http.client
108+
http.client.HTTPConnection.debuglevel = 1
109+
logging.basicConfig()
110+
logging.getLogger().setLevel(logging.DEBUG)
111+
requests_log = logging.getLogger("requests.packages.urllib3")
112+
requests_log.setLevel(logging.DEBUG)
113+
requests_log.propagate = True
114+
headers = {"User-Agent": "Mozilla/5.0 (X11; CrOS x86_64 12871.102.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.141 Safari/537.36"}
106115

107-
responseGetNone = requests.get(BASE_URL + GET_NONE_ONE)
108-
responseGetNoneBatch = requests.post(BASE_URL + GET_NONE_ONE_BATCH, json=payload)
116+
session = requests.Session()
109117

110-
responsePostSendPayload = requests.post(BASE_URL + POST_PAYLOAD_ONE, json=payload)
111-
responsePostSendPayloadList = requests.post(BASE_URL + POST_PAYLOAD_ONE, json=payloadList)
112-
responsePostSendPayloadBatch = requests.post(BASE_URL + POST_PAYLOAD_ONE_BATCH, json=payload)
113-
responsePostSendPayloadListBatch = requests.post(BASE_URL + POST_PAYLOAD_ONE_BATCH, json=payloadList)
118+
responseGetHealth = session.get(BASE_URL + GET_ACTUATOR_HEALTH_CONTROLLER, headers=headers)
119+
120+
responseGetNone = session.get(BASE_URL + GET_NONE_ONE)
121+
responseGetNoneBatch = session.post(BASE_URL + GET_NONE_ONE_BATCH, json=payload, headers=headers)
122+
123+
responsePostSendPayload = session.post(BASE_URL + POST_PAYLOAD_ONE, json=payload, headers=headers)
124+
responsePostSendPayloadList = session.post(BASE_URL + POST_PAYLOAD_ONE, json=payloadList, headers=headers)
125+
responsePostSendPayloadBatch = session.post(BASE_URL + POST_PAYLOAD_ONE_BATCH, json=payload, headers=headers)
126+
responsePostSendPayloadListBatch = session.post(BASE_URL + POST_PAYLOAD_ONE_BATCH, json=payloadList, headers=headers)
127+
128+
print(requests.get('https://www.google.com/search?q=something&rlz=1C1GCEU_pt-BRBR884BR884&oq=something&aqs=chrome..69i57.5839j0j7&sourceid=chrome&ie=UTF-8'))
129+
print(requests.get('https://www.google.com/search?q=something+else&rlz=1C1GCEU_pt-BRBR884BR884&sxsrf=ALeKk03rn_R9yREVJSkMqIUeAJfmFMVSfA%3A1619326195697&ei=8_SEYNWPKsGn5OUPobip-AQ&oq=something+else&gs_lcp=Cgdnd3Mtd2l6EAMyBQgAEJECMgUIABDLATIFCC4QywEyBQgAEMsBMgUILhDLATIFCC4QywEyBQgAEMsBMgUILhDLATICCAAyBQgAEMsBOgcIABBHELADOgcIABCwAxBDOg0ILhCwAxDIAxBDEJMCOgoILhCwAxDIAxBDOgIILjoHCAAQChDLAUoFCDgSATFQr_wLWPyCDGDdigxoAXACeACAAZYBiAGiBpIBAzAuNpgBAKABAaoBB2d3cy13aXrIAQ_AAQE&sclient=gws-wiz&ved=0ahUKEwiV1a2VzJjwAhXBE7kGHSFcCk8Q4dUDCA4&uact=5'))
114130

115131
# print(f'responseGetNone: {responseGetNone.json()}')
116132
# print(f'responseGetNoneBatch: {responseGetNoneBatch.json()}')

‎python_framework/api/test/api/src/annotation/EnumAnnotationTest.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,5 @@ class MyThirdEnumTest :
604604
assert str(type(a[0])) == '''<class 'python_framework.api.src.annotation.EnumAnnotation.EnumItemStr'>'''
605605
assert f'''{b}''' == "['DEF']"
606606
assert str(type(b[0])) == '''<class 'python_framework.api.src.annotation.EnumAnnotation.EnumItemStr'>'''
607-
608-
print(MY_THIRD_ENUM_TEST)
609-
print(type(MY_THIRD_ENUM_TEST))
607+
# print(MY_THIRD_ENUM_TEST)
608+
# print(type(MY_THIRD_ENUM_TEST))

0 commit comments

Comments
 (0)