jit-utils-backend 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,177 @@
1
+ # -*-coding:utf-8-*-
2
+
3
+ """
4
+ Created on 2023/9/20
5
+
6
+ @author: 臧韬
7
+
8
+ @desc: 默认描述
9
+ """
10
+ from commons.utils.config.exception import TlConfigException
11
+
12
+
13
+ class NoneType(object):
14
+ def __bool__(self):
15
+ return False
16
+
17
+
18
+ class AnyType(object):
19
+ pass
20
+
21
+
22
+ class Inf(float):
23
+ __instance = None
24
+
25
+ def __new__(cls, *args, **kwargs):
26
+ if cls.__instance is None:
27
+ cls.__instance = super(Inf, cls).__new__(cls, "inf")
28
+ return cls.__instance
29
+
30
+ def __gt__(self, other):
31
+ return False
32
+
33
+ def __str__(self):
34
+ return "无穷大"
35
+
36
+ def __neg__(self):
37
+ return NegInf()
38
+
39
+ def __invert__(self):
40
+ return NegInf()
41
+
42
+ def __floordiv__(self, other):
43
+ return self
44
+
45
+ def __truediv__(self, other):
46
+ return self
47
+
48
+
49
+ class NegInf(float):
50
+ __instance = None
51
+
52
+ def __new__(cls, *args, **kwargs):
53
+ if cls.__instance is None:
54
+ cls.__instance = super(NegInf, cls).__new__(cls, "-inf")
55
+ return cls.__instance
56
+
57
+ def __gt__(self, other):
58
+ return True
59
+
60
+ def __str__(self):
61
+ return "无穷小"
62
+
63
+ def __neg__(self):
64
+ return Inf()
65
+
66
+ def __invert__(self):
67
+ return Inf()
68
+
69
+
70
+ inf = Inf()
71
+
72
+ # print("<<<<<<<<<<<<<基类被加载")
73
+
74
+
75
+ class Field(object):
76
+ """
77
+ 这是一个基类字段
78
+ """
79
+
80
+ def __init__(self, argType=AnyType, required=True, default=None, checkFunc=None, transformFunc=None):
81
+ self.argType = argType
82
+ # 当一个字段设置了默认值,那么设置成必传就没有意义
83
+ self.required = False if default else required
84
+ self.default = default
85
+ self.checkFunc = checkFunc
86
+ self.transformFunc = transformFunc
87
+
88
+ self.name = None
89
+
90
+ def check(self, value):
91
+ if self.required and value is None:
92
+ raise TlConfigException("该字段必传! field={f}".format(f=self.name))
93
+ if self.argType is not AnyType and not isinstance(value, self.argType):
94
+ raise TlConfigException(
95
+ "该参数应该传入的数据类型是={at}, 收到的数据类型={vt}! 值={v}, 字段名={f}".format(
96
+ at=self.argType.__name__, vt=type(value).__name__, v=str(value), f=self.__class__.__name__
97
+ )
98
+ )
99
+ if callable(self.checkFunc):
100
+ self.checkFunc(value)
101
+
102
+ def transform(self, value):
103
+ if value is NoneType:
104
+ return value
105
+ if callable(self.transformFunc):
106
+ try:
107
+ return self.transformFunc(value)
108
+ except Exception as e:
109
+ raise e
110
+ return value
111
+
112
+
113
+ # print("Field: {}".format(id(Field)))
114
+
115
+
116
+ class StringField(Field):
117
+ """
118
+ 字符串字段
119
+ """
120
+
121
+ DEFAULT_MAX_LEN = 65535
122
+ DEFAULT_MIN_LEN = 0
123
+
124
+ def __init__(
125
+ self,
126
+ argType=str,
127
+ required=True,
128
+ default=None,
129
+ maxLen=DEFAULT_MAX_LEN,
130
+ minLen=DEFAULT_MIN_LEN,
131
+ transformFunc=str,
132
+ ):
133
+ super(StringField, self).__init__(
134
+ argType=argType, required=required, default=default, checkFunc=self.stringCheck, transformFunc=transformFunc
135
+ )
136
+
137
+ self.maxLen = maxLen
138
+ self.minLen = minLen
139
+
140
+ def lengthCheck(self, value, maxLen, minLen):
141
+ if minLen == maxLen and len(value) != minLen:
142
+ raise TlConfigException("{name}的长度应该是 {minLen}".format(name=self.name, minLen=minLen))
143
+ if not minLen <= len(value) <= maxLen:
144
+ raise TlConfigException(
145
+ "{name}的长度必须介于 {minLen} 到 {maxLen} 之前".format(name=self.name, minLen=minLen, maxLen=maxLen)
146
+ )
147
+
148
+ def stringCheck(self, value):
149
+ self.lengthCheck(value, maxLen=self.maxLen, minLen=self.minLen)
150
+
151
+
152
+ class IntField(Field):
153
+ DEFAULT_MAX_NUM = inf
154
+ DEFAULT_MIN_NUM = -inf
155
+
156
+ def __init__(self, argType=int, required=True, maxNum=DEFAULT_MAX_NUM, minNum=DEFAULT_MIN_NUM, default=None):
157
+ super(IntField, self).__init__(
158
+ argType=argType, required=required, default=default, checkFunc=self.intCheck, transformFunc=self.toInt
159
+ )
160
+
161
+ self.maxNum = maxNum
162
+ self.minNum = minNum
163
+
164
+ def rangeCheck(self, value, maxNum, minNum):
165
+ if not minNum <= value <= maxNum:
166
+ raise TlConfigException(
167
+ "{name} 的取值范围是 {minNum} 到 {maxNum}".format(name=self.name, minNum=minNum, maxNum=maxNum)
168
+ )
169
+
170
+ def toInt(self, value):
171
+ if isinstance(value, str):
172
+ if not value.isnumeric():
173
+ raise TlConfigException("{name} 必须传入数字".format(name=self.name))
174
+ return int(value)
175
+
176
+ def intCheck(self, value):
177
+ self.rangeCheck(value=value, maxNum=self.maxNum, minNum=self.minNum)
jit_utils/convert.py ADDED
@@ -0,0 +1,169 @@
1
+ # -*-coding:utf-8-*-
2
+ """
3
+ Created on 2022/12/27
4
+
5
+ @author: lyon
6
+
7
+ @desc:
8
+ """
9
+
10
+ from jit.commons.utils.logger import log
11
+
12
+
13
+ class Converter(object):
14
+
15
+ def __init__(self):
16
+ self._globals = {}
17
+
18
+ def getFuncSubClasses(self, baseCls):
19
+ for subCls in baseCls.__subclasses__():
20
+ if hasattr(subCls, "function"):
21
+ self._globals[subCls.function] = subCls
22
+ self.getFuncSubClasses(subCls)
23
+
24
+ def getExprSubClasses(self, baseCls):
25
+ for subCls in baseCls.__subclasses__():
26
+ self._globals[subCls.__name__] = subCls
27
+ self.getExprSubClasses(subCls)
28
+
29
+ def eval(self, expression):
30
+ # t表达式里面有 "T(modelPath)xxx"
31
+ # 加载FUNC子类
32
+ from models.Meta import Expression
33
+
34
+ self.getExprSubClasses(Expression)
35
+ Sql = app.getElement("globals.Sql")
36
+ self._globals["Calc"] = Sql
37
+ self._globals["null"] = None
38
+ return eval(expression, self._globals)
39
+
40
+
41
+ converter = Converter()
42
+
43
+
44
+ class MemoryCompiler(object):
45
+ """
46
+ Q表达式内存计算判断
47
+ """
48
+
49
+ def __init__(self, expression, data=None):
50
+ self.expression = expression
51
+ self.data = data
52
+
53
+ def parse(self):
54
+ from models.Meta import Func
55
+
56
+ if isinstance(self.expression, Func):
57
+ result = FuncParser(self.expression).getMemory(self)
58
+ else:
59
+ # 根据类名选择对应的解析器(解析器需要我们自己手动去完成构建)
60
+ Parser = globals()[self.expression.__class__.__name__ + "Parser"]
61
+ result = Parser(self.expression).getMemory(self)
62
+ return result
63
+
64
+ def evalQ(self):
65
+ try:
66
+ result = self.parse()
67
+ return converter.eval("lambda x: %s" % result)(self.data)
68
+ except Exception as e:
69
+ log.error(e)
70
+ return False
71
+
72
+
73
+ class ExpressionParser(object):
74
+
75
+ def __init__(self, *args, **kwargs):
76
+ self.quoteCache = {"*": "*"}
77
+
78
+ def getMemory(self, compiler):
79
+ raise NotImplementedError
80
+
81
+
82
+ class QParser(ExpressionParser):
83
+ """
84
+ Q表达式解析
85
+ """
86
+
87
+ def __init__(self, q):
88
+ super(QParser, self).__init__(q)
89
+ self.q = q
90
+
91
+ def getMemory(self, compiler):
92
+ from models.Meta import QAND, QOR, getLookup
93
+
94
+ result = []
95
+ if self.q.sourceExpressions:
96
+ # 嵌套结构
97
+ for expr in self.q.sourceExpressions:
98
+ if isinstance(expr, (QAND, QOR)):
99
+ result.append(expr())
100
+ else:
101
+ result.append(self.__class__(expr).getMemory(compiler))
102
+ else:
103
+ # 非嵌套结构
104
+ lookup = getLookup(self.q.compareName)
105
+ if lookup:
106
+ result.append(LookupParser(lookup(self.q.lhs, self.q.rhs)).getMemory(compiler))
107
+ return "({})".format(" ".join(result))
108
+
109
+
110
+ class LookupParser(ExpressionParser):
111
+
112
+ def __init__(self, lookup):
113
+ super(LookupParser, self).__init__(lookup)
114
+ self.lookup = lookup
115
+
116
+ def getMemory(self, compiler):
117
+ ls = MemoryCompiler(self.lookup.lhs, compiler.data).parse()
118
+ rs = MemoryCompiler(self.lookup.rhs, compiler.data).parse()
119
+ if "{ls}" in self.lookup.memory:
120
+ return self.lookup.memory.format(ls=ls, rs=rs)
121
+ return "(%s %s %s)" % (ls, self.lookup.memory, rs)
122
+
123
+
124
+ class FuncParser(ExpressionParser):
125
+
126
+ def __init__(self, func):
127
+ super(FuncParser, self).__init__(func)
128
+ self.func = func
129
+
130
+ def getMemory(self, compiler):
131
+ exps = [str(MemoryCompiler(exp, compiler.data).parse()) for exp in self.func.sourceExpressions]
132
+ return "%s(%s)" % (self.func.memory, ", ".join(exps))
133
+
134
+
135
+ class FParser(ExpressionParser):
136
+
137
+ def __init__(self, f):
138
+ super(FParser, self).__init__(f)
139
+ self.f = f
140
+
141
+ def getMemory(self, compiler):
142
+ """
143
+ 如果有数据, 就返回值
144
+ 没有, 就返回 x.字段
145
+ """
146
+ # TODO: 暂时先只做一层
147
+ return repr(compiler.data.get(self.f.fieldId, "x.%s" % self.f.fieldId))
148
+
149
+
150
+ class ValueParser(ExpressionParser):
151
+
152
+ def __init__(self, value):
153
+ super(ValueParser, self).__init__(value)
154
+ self.value = value
155
+
156
+ def getMemory(self, compiler):
157
+ return repr(self.value.value)
158
+
159
+
160
+ class CombinedExpressionParser(ExpressionParser):
161
+
162
+ def __init__(self, combine):
163
+ super(CombinedExpressionParser, self).__init__(combine)
164
+ self.combine = combine
165
+
166
+ def getMemory(self, compiler):
167
+ left = MemoryCompiler(self.combine.lhs, compiler.data).parse()
168
+ right = MemoryCompiler(self.combine.rhs, compiler.data).parse()
169
+ return "(%s %s %s)" % (left, self.combine.connector, right)
jit_utils/decorator.py ADDED
@@ -0,0 +1,58 @@
1
+ import inspect
2
+ import json
3
+
4
+ import requests
5
+
6
+
7
+ def forward(fullName):
8
+ def inner(func):
9
+ def wrapper(self, *args, **kwargs):
10
+ appRule = app.env.getRuleByAppId(app.appId)
11
+ # 当前APP, 不需要转发
12
+ authApp = appRule.variables.get("authApp")
13
+ if not authApp:
14
+ return func(self, *args, **kwargs)
15
+ else:
16
+ if not app.env.envEntryList:
17
+ raise Exception("无环境入口")
18
+ entry = app.domain
19
+ uri = "{}/api/{}/{}/{}".format(
20
+ entry.strip("/"), authApp.replace(".", "/"), fullName.replace(".", "/"), func.__name__
21
+ )
22
+ argDict = {}
23
+ f = inspect.getfullargspec(func)
24
+ fargs = f.args
25
+ fargs.pop(0)
26
+ for key, value in zip(fargs, args):
27
+ argDict[key] = value
28
+ if len(args) > len(f.args):
29
+ argDict[f.varargs] = args[len(f.args) - 1 :]
30
+ for key, value in kwargs.items():
31
+ argDict[key] = value
32
+
33
+ argDict = {"argDict": argDict}
34
+
35
+ # 这里headers要把Token传过去
36
+ try:
37
+ argDict = json.dumps(argDict)
38
+ response = requests.post(
39
+ uri,
40
+ data=argDict,
41
+ headers={"Content-Type": "application/json", "token": app.request.headers.get("token")},
42
+ )
43
+ print("===========================")
44
+ print(" uri: ", uri)
45
+ print(" data: ", argDict)
46
+ print(" response: ", response.text)
47
+ print("===========================")
48
+ resp = json.loads(response.text)
49
+ except Exception:
50
+ raise Exception("响应无效")
51
+ if resp["errcode"] != 0:
52
+ raise Exception(resp["errmsg"])
53
+ data = resp["data"]
54
+ return data
55
+
56
+ return wrapper
57
+
58
+ return inner
@@ -0,0 +1,113 @@
1
+ # -*-coding:utf-8-*-
2
+ """
3
+ Created on 2025/1/13 15:54
4
+
5
+ @author: 'wuhao'
6
+
7
+ @desc:
8
+ """
9
+ import os
10
+ import traceback
11
+
12
+ from jit.commons.utils.logger import log
13
+ from jit.errcode import ElementErrCode
14
+
15
+
16
+ class BaseElementException(object):
17
+ PREFIX = "exc"
18
+
19
+ def __init__(self, fullName, title):
20
+ self.fullName = fullName
21
+ self.title = title
22
+
23
+ def getTrace(self, exc):
24
+ trace = traceback.extract_tb(exc.__traceback__)[-1]
25
+ filename, lineno, func, text = trace
26
+ filename = filename.replace(os.environ["rootPath"], "").replace(os.sep, ".")
27
+ return filename, lineno, func, text
28
+
29
+ # def other(self,exc):
30
+ # """
31
+ # 遇到未定义的异常类型处理时调用
32
+ # :param exc:
33
+ # :return:
34
+ # """
35
+
36
+ def handleException(self, exc):
37
+ exceptionName = type(exc).__name__
38
+ log.exception(exc)
39
+ handler = getattr(self, self.PREFIX + exceptionName, None)
40
+ if handler:
41
+ code = handler(exc)
42
+ return code
43
+ # 遇到使用者为定义的异常类型处理时调用
44
+ elif hasattr(self, "other"):
45
+ code = self.other(exc)
46
+ return code
47
+ # 没定义任何处理
48
+ else:
49
+ return None
50
+
51
+ def excAttributeError(self, exc):
52
+ filename, lineno, func, text = self.getTrace(exc)
53
+ errMsg = "访问了{objName}对象不存在的属性{attrName},在文件{filename}第{lineno}行,异常代码:{text}".format(
54
+ objName=exc.obj, attrName=exc.name, filename=filename, lineno=lineno, text=text
55
+ )
56
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
57
+ return code
58
+
59
+ def excValueError(self, exc):
60
+ filename, lineno, func, text = self.getTrace(exc)
61
+ errMsg = "无效的值,在文件{filename}第{lineno}行,异常代码:{text}".format(
62
+ filename=filename, lineno=lineno, text=text
63
+ )
64
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
65
+ return code
66
+
67
+ def excTypeError(self, exc):
68
+ filename, lineno, func, text = self.getTrace(exc)
69
+ errMsg = "不支持的类型操作,在文件{filename}第{lineno}行,异常代码:{text}".format(
70
+ filename=filename, lineno=lineno, text=text
71
+ )
72
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
73
+ return code
74
+
75
+ def excIndexError(self, exc):
76
+ filename, lineno, func, text = self.getTrace(exc)
77
+ errMsg = "索引越界,在文件{filename}第{lineno}行,异常代码:{text}".format(
78
+ filename=filename, lineno=lineno, text=text
79
+ )
80
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
81
+ return code
82
+
83
+ def excKeyError(self, exc):
84
+ filename, lineno, func, text = self.getTrace(exc)
85
+ errMsg = "字典没有这个key,在文件{filename}第{lineno}行,异常代码:{text}".format(
86
+ filename=filename, lineno=lineno, text=text
87
+ )
88
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
89
+ return code
90
+
91
+ def excNameError(self, exc):
92
+ filename, lineno, func, text = self.getTrace(exc)
93
+ errMsg = "没有定义的变量,在文件{filename}第{lineno}行,异常代码:{text}".format(
94
+ filename=filename, lineno=lineno, text=text
95
+ )
96
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
97
+ return code
98
+
99
+ def excSyntaxError(self, exc):
100
+ filename, lineno, func, text = self.getTrace(exc)
101
+ errMsg = "语法错误,在文件{filename}第{lineno}行,异常代码:{text}".format(
102
+ filename=filename, lineno=lineno, text=text
103
+ )
104
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
105
+ return code
106
+
107
+ def excZeroDivisionError(self, exc):
108
+ filename, lineno, func, text = self.getTrace(exc)
109
+ errMsg = "除数为0,在文件{filename}第{lineno}行,异常代码:{text}".format(
110
+ filename=filename, lineno=lineno, text=text
111
+ )
112
+ code = ElementErrCode.ELEMENT_ERROR.formatReason(fullName=self.fullName, title=self.title, errMsg=errMsg)
113
+ return code
jit_utils/forwarder.py ADDED
@@ -0,0 +1,113 @@
1
+ # -*-coding:utf-8-*-
2
+ """
3
+ Created on 2024/12/11
4
+
5
+ @author: 臧韬
6
+
7
+ @desc: 默认描述
8
+ """
9
+
10
+ import inspect
11
+ import types
12
+
13
+
14
+ class MethodForwarder(object):
15
+ """
16
+ cls方法转换器,可以将这个函数的所有方法都转换成目标函数,可以在不修改原始类的任何代码情况进行装饰。
17
+ 使用方法:
18
+ def myfunc(args, kwargs, extends):
19
+ # 目标函数
20
+ return 2
21
+
22
+ class MyClass(object):
23
+ def func(self):
24
+ return 1
25
+
26
+ @ClsForward(myFunc)
27
+ class ForwardClass(MyClass):
28
+ pass
29
+
30
+ >> MyClass().func()
31
+ 1
32
+
33
+ >> ForwardClass().func()
34
+ 2
35
+
36
+ 特点:
37
+ 1. 目标函数中如果返回了 ClsForward.DoNotForward,则会执行原来的函数或者方法
38
+ 2. 目标函数的入参必须是 args, kwargs, extend
39
+ args, kwargs 是调用这个函数的参数
40
+ extend是一个字典,包含3个参数
41
+ cls -> 类对象
42
+ self -> 如果是通过实例化的对象调用的函数或方法,这里会传入实例对象
43
+ func -> 执行的函数对象,如果是类方法,则返回的绑定到这个类的method对象。如果是成员方法和静态方法,则传入的是function对象。
44
+ 3. 可以在装饰器的入参中指定excludeFunc,函数名满足这个函数则不会转发
45
+ 参考:
46
+ def excludeFunc(name):
47
+ return name == "view" and name.startswith("_")
48
+
49
+ @ClsForward(myFunc, excludeFunc=excludeFunc)
50
+ class ForwardClass(MyClass):
51
+ pass
52
+
53
+ 这样这个类在遇到view函数和开头为下划线的函数,则不会转换。
54
+ excludeFunc是选传的,默认情况下忽略下划线开头的函数。
55
+ """
56
+
57
+ DoNotForward = object()
58
+
59
+ def __init__(self, targetFunc, excludeFunc=None):
60
+ self.targetFunc = targetFunc
61
+ self.clss = None
62
+ self.excludeFunc = excludeFunc or self.defaultExcludeFunc
63
+
64
+ def __call__(self, clss):
65
+ self.clss = clss
66
+
67
+ for name in dir(clss):
68
+ if callable(self.excludeFunc):
69
+ if self.excludeFunc(name):
70
+ continue
71
+ func = getattr(clss, name)
72
+ if inspect.ismethod(func):
73
+ setattr(clss, name, classmethod(self.classForward(func, self.targetFunc)))
74
+ if inspect.isfunction(func):
75
+ setattr(clss, name, self.classForward(func, self.targetFunc))
76
+ return clss
77
+
78
+ def classForward(self, func, targetFunc):
79
+
80
+ def wrapper(*args, **kwargs):
81
+ # 如果是实例调用方法,args第一个会传入对象
82
+ if args and (isinstance(args[0], self.clss) or issubclass(args[0], self.clss)):
83
+ sf, *rArgs = args
84
+ rArgs = tuple(rArgs)
85
+ else:
86
+ sf = None
87
+ rArgs = args
88
+
89
+ extend = {
90
+ "clss": self.clss,
91
+ "self": sf,
92
+ "func": func,
93
+ }
94
+ result = targetFunc(rArgs, kwargs, extend)
95
+ if result is self.DoNotForward:
96
+ if sf:
97
+ if inspect.isfunction(func):
98
+ # 实例方法
99
+ return types.MethodType(func, sf)(*rArgs, **kwargs)
100
+ else:
101
+ # 类方法
102
+ return types.MethodType(func.__func__, sf)(*rArgs, **kwargs)
103
+ else:
104
+ # 静态方法
105
+ return func(*rArgs, **kwargs)
106
+
107
+ return result
108
+
109
+ return wrapper
110
+
111
+ @staticmethod
112
+ def defaultExcludeFunc(name):
113
+ return name.startswith("_")