CheeseAPI 1.1.4__tar.gz → 1.2.0__tar.gz
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.
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/__init__.py +1 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/handle.py +1 -1
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/protocol.py +2 -1
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/schedule.py +4 -4
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/text.py +2 -2
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/validator.py +23 -22
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/PKG-INFO +3 -2
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/README.md +2 -1
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/pyproject.toml +1 -1
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/.gitignore +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/app.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/cors.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/exception.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/file.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/request.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/response.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/route.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/server.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/signal.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/websocket.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/CheeseAPI/workspace.py +0 -0
- {cheeseapi-1.1.4 → cheeseapi-1.2.0}/LICENSE +0 -0
|
@@ -87,7 +87,7 @@ class Handle:
|
|
|
87
87
|
|
|
88
88
|
def loadLocalModules(self):
|
|
89
89
|
foldernames = self._app.localModules.copy()
|
|
90
|
-
for foldername in self._app.preferred_localModules:
|
|
90
|
+
for foldername in reversed(self._app.preferred_localModules):
|
|
91
91
|
if foldername in foldernames:
|
|
92
92
|
foldernames.remove(foldername)
|
|
93
93
|
foldernames.insert(0, foldername)
|
|
@@ -62,7 +62,8 @@ class HttpProtocol(asyncio.Protocol):
|
|
|
62
62
|
self.request._body = b''
|
|
63
63
|
self.request._body += body
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
def on_message_complete(self):
|
|
66
|
+
if not self.parser.should_upgrade():
|
|
66
67
|
self.request._parseBody()
|
|
67
68
|
asyncio.get_event_loop().create_task(app._handle.http(self))
|
|
68
69
|
|
|
@@ -233,7 +233,7 @@ class Scheduler:
|
|
|
233
233
|
if fn:
|
|
234
234
|
self._app._managers_['schedules'][key] = {
|
|
235
235
|
'timer': timer,
|
|
236
|
-
'fn': dill.dumps(fn),
|
|
236
|
+
'fn': dill.dumps(fn, recurse = True),
|
|
237
237
|
'startTimer': startTimer,
|
|
238
238
|
'expected_repetition_num': expected_repetition_num,
|
|
239
239
|
'total_repetition_num': 0,
|
|
@@ -242,10 +242,10 @@ class Scheduler:
|
|
|
242
242
|
}
|
|
243
243
|
return
|
|
244
244
|
|
|
245
|
-
def
|
|
245
|
+
def wrapper(fn):
|
|
246
246
|
self._app._managers_['schedules'][key] = {
|
|
247
247
|
'timer': timer,
|
|
248
|
-
'fn': dill.dumps(fn),
|
|
248
|
+
'fn': dill.dumps(fn, recurse = True),
|
|
249
249
|
'startTimer': startTimer,
|
|
250
250
|
'expected_repetition_num': expected_repetition_num,
|
|
251
251
|
'total_repetition_num': 0,
|
|
@@ -253,7 +253,7 @@ class Scheduler:
|
|
|
253
253
|
'active': True
|
|
254
254
|
}
|
|
255
255
|
return fn
|
|
256
|
-
return
|
|
256
|
+
return wrapper
|
|
257
257
|
|
|
258
258
|
@overload
|
|
259
259
|
def remove(self, fn: Callable):
|
|
@@ -153,8 +153,8 @@ Static: <cyan>{self._app.server.static}</cyan>''' if self._app.workspace.static
|
|
|
153
153
|
def validator_requiredMessage(self, scope: str, key: str) -> str:
|
|
154
154
|
return f'The {scope}.{key} is required'
|
|
155
155
|
|
|
156
|
-
def validator_typeMessage(self, scope: str, key: str, expected_type:
|
|
157
|
-
return f'The {scope}.{key} cannot be converted to {expected_type
|
|
156
|
+
def validator_typeMessage(self, scope: str, key: str, expected_type: str) -> str:
|
|
157
|
+
return f'The {scope}.{key} cannot be converted to {expected_type}'
|
|
158
158
|
|
|
159
159
|
def validator_patternMessage(self, scope: str, key: str) -> str:
|
|
160
160
|
return f'The {scope}.{key} regular check error'
|
|
@@ -9,12 +9,12 @@ if TYPE_CHECKING:
|
|
|
9
9
|
from CheeseAPI.app import App
|
|
10
10
|
|
|
11
11
|
class ValidateError(Exception):
|
|
12
|
-
def __init__(self, response: BaseResponse =
|
|
12
|
+
def __init__(self, response: BaseResponse | None = None):
|
|
13
13
|
'''
|
|
14
14
|
在自定义校验函数中抛出此错误,可结束校验并直接返回响应体。
|
|
15
15
|
'''
|
|
16
16
|
|
|
17
|
-
self.response = response
|
|
17
|
+
self.response: BaseResponse | None = response
|
|
18
18
|
|
|
19
19
|
class Bool:
|
|
20
20
|
'''
|
|
@@ -40,8 +40,8 @@ class Validator:
|
|
|
40
40
|
*,
|
|
41
41
|
required: bool = False,
|
|
42
42
|
default: Any = None,
|
|
43
|
-
type: List[object | Callable] | object | Callable
|
|
44
|
-
expected_type:
|
|
43
|
+
type: List[object | Callable] | object | Callable = str,
|
|
44
|
+
expected_type: str | None = None,
|
|
45
45
|
pattern: str | None = None,
|
|
46
46
|
min: object | None = None,
|
|
47
47
|
max: object | None = None,
|
|
@@ -57,7 +57,7 @@ class Validator:
|
|
|
57
57
|
|
|
58
58
|
from CheeseAPI import Validator
|
|
59
59
|
|
|
60
|
-
Validator('form', 'date', type = [ float, datetime.datetime.fromtimestamp ], expected_type =
|
|
60
|
+
Validator('form', 'date', type = [ float, datetime.datetime.fromtimestamp ], expected_type = 'timestamp')
|
|
61
61
|
|
|
62
62
|
Validator('form', 'gender', enum = [ 'man', 'woman', None ])
|
|
63
63
|
|
|
@@ -70,7 +70,7 @@ class Validator:
|
|
|
70
70
|
|
|
71
71
|
- type: 遵循`self.type(value) -> object`的类或函数;支持list按顺序转换类型。
|
|
72
72
|
|
|
73
|
-
- expected_type:
|
|
73
|
+
- expected_type: 期望的数据类型,不参与校验,仅供提示。
|
|
74
74
|
|
|
75
75
|
- default: 默认值;该值仍会执行校验流程,而不是直接应用。
|
|
76
76
|
|
|
@@ -101,7 +101,7 @@ class Validator:
|
|
|
101
101
|
self._scope: Literal['form', 'headers', 'args', 'path', 'cookie'] = scope
|
|
102
102
|
self.key: str = key
|
|
103
103
|
self._type: List[object | Callable] | object | Callable = type
|
|
104
|
-
self._expected_type:
|
|
104
|
+
self._expected_type: str = type.__name__ if expected_type is None else expected_type
|
|
105
105
|
self.required: bool = required
|
|
106
106
|
self._default: Any = default
|
|
107
107
|
self._pattern: str | None = pattern
|
|
@@ -132,8 +132,6 @@ class Validator:
|
|
|
132
132
|
validatedForm[f'{self.scope}.{self.key}'] = type(validatedForm[f'{self.scope}.{self.key}'])
|
|
133
133
|
else:
|
|
134
134
|
validatedForm[f'{self.scope}.{self.key}'] = self.type(validatedForm[f'{self.scope}.{self.key}'])
|
|
135
|
-
if not isinstance(validatedForm[f'{self.scope}.{self.key}'], self.expected_type):
|
|
136
|
-
raise Exception()
|
|
137
135
|
except:
|
|
138
136
|
raise ValidateError(self.response or Response(app._text.validator_typeMessage(self.scope, self.key, self.expected_type), 400))
|
|
139
137
|
|
|
@@ -150,13 +148,16 @@ class Validator:
|
|
|
150
148
|
raise ValidateError(self.response or Response(app._text.validator_enumMessage(self.scope, self.key, self.enum), 400))
|
|
151
149
|
|
|
152
150
|
if self.fn:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
151
|
+
try:
|
|
152
|
+
_value = await self.fn(*args, **{
|
|
153
|
+
'request': request,
|
|
154
|
+
'validatedForm': validatedForm,
|
|
155
|
+
**kwargs
|
|
156
|
+
})
|
|
157
|
+
if _value is not None:
|
|
158
|
+
validatedForm[f'{self.scope}.{self.key}'] = _value
|
|
159
|
+
except ValidateError as e:
|
|
160
|
+
raise ValidateError(e.response or self.response or Response(status = 500))
|
|
160
161
|
|
|
161
162
|
@property
|
|
162
163
|
def scope(self) -> Literal['form', 'headers', 'args', 'path', 'cookie']:
|
|
@@ -193,16 +194,16 @@ class Validator:
|
|
|
193
194
|
self._type = value
|
|
194
195
|
|
|
195
196
|
@property
|
|
196
|
-
def expected_type(self) ->
|
|
197
|
+
def expected_type(self) -> str:
|
|
197
198
|
'''
|
|
198
|
-
|
|
199
|
+
期望的数据类型,不参与校验,仅供提示。
|
|
199
200
|
'''
|
|
200
201
|
|
|
201
202
|
return self._expected_type
|
|
202
203
|
|
|
203
204
|
@expected_type.setter
|
|
204
|
-
def expected_type(self, value:
|
|
205
|
-
self._expected_type = self.type if value is None else value
|
|
205
|
+
def expected_type(self, value: str | None):
|
|
206
|
+
self._expected_type = self.type.__name__ if value is None else value
|
|
206
207
|
|
|
207
208
|
@property
|
|
208
209
|
def default(self) -> Any:
|
|
@@ -303,7 +304,7 @@ def validator(validators: List[Validator]):
|
|
|
303
304
|
@app.route.get('/')
|
|
304
305
|
@validator([
|
|
305
306
|
Validator('form', 'name', required = True),
|
|
306
|
-
Validator('form', 'birthDate', type = [ float, datetime.datetime.fromtimestamp ], expected_type =
|
|
307
|
+
Validator('form', 'birthDate', type = [ float, datetime.datetime.fromtimestamp ], expected_type = 'timestamp', fn = birthDateValidator),
|
|
307
308
|
Validator('form', 'gender', enum = [ 'man', 'woman', None ]),
|
|
308
309
|
Validator('form', 'idCard', pattern = r'^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\\d|3[0-1])\\d{3}[\\dXx]$', response = Response('身份证格式错误', 400))
|
|
309
310
|
])
|
|
@@ -327,7 +328,7 @@ def validator(validators: List[Validator]):
|
|
|
327
328
|
@app.route.get('/')
|
|
328
329
|
@validator([
|
|
329
330
|
Validator('form', 'name', required = True),
|
|
330
|
-
Validator('form', 'birthDate', type = [ float, datetime.datetime.fromtimestamp ], expected_type =
|
|
331
|
+
Validator('form', 'birthDate', type = [ float, datetime.datetime.fromtimestamp ], expected_type = 'timestamp'),
|
|
331
332
|
Validator('form', 'gender', enum = [ 'man', 'woman', None ]),
|
|
332
333
|
Validator('form', 'idCard', pattern = r'^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\\d|3[0-1])\\d{3}[\\dXx]$', response = Response('身份证格式错误', 400)),
|
|
333
334
|
Validator('form', 'birthDate', fn = birthDateValidator)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: CheeseAPI
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: 一款web协程框架。
|
|
5
5
|
Project-URL: Source, https://github.com/CheeseUnknown/CheeseAPI
|
|
6
6
|
Author-email: Cheese Unknown <cheese@cheese.ren>
|
|
@@ -96,7 +96,8 @@ from CheeseAPI import app, Response
|
|
|
96
96
|
async def index(**kwargs):
|
|
97
97
|
return Response('这里是CheeseAPI!')
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
if __name__ == '__main__':
|
|
100
|
+
app.run()
|
|
100
101
|
```
|
|
101
102
|
|
|
102
103
|
运行`app.py`,可以看到打印了一些服务器的基本信息:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|