CheeseAPI 0.0.4__tar.gz → 0.0.6__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.
Files changed (25) hide show
  1. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/__init__.py +1 -1
  2. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/app.py +22 -22
  3. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/command.py +37 -4
  4. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/request.py +18 -44
  5. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/server.py +6 -3
  6. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI.egg-info/PKG-INFO +5 -3
  7. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/PKG-INFO +5 -3
  8. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/README.md +4 -2
  9. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/setup.py +1 -1
  10. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/cSignal.py +0 -0
  11. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/exception.py +0 -0
  12. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/file.py +0 -0
  13. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/module.py +0 -0
  14. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/response.py +0 -0
  15. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/route.py +0 -0
  16. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/system.py +0 -0
  17. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/websocket.py +0 -0
  18. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI/workspace.py +0 -0
  19. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI.egg-info/SOURCES.txt +0 -0
  20. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI.egg-info/dependency_links.txt +0 -0
  21. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI.egg-info/entry_points.txt +0 -0
  22. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI.egg-info/requires.txt +0 -0
  23. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/CheeseAPI.egg-info/top_level.txt +0 -0
  24. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/LICENSE +0 -0
  25. {CheeseAPI-0.0.4 → CheeseAPI-0.0.6}/setup.cfg +0 -0
@@ -1,4 +1,4 @@
1
- from .app import app
1
+ from .app import app, doFunc
2
2
  from .route import Route
3
3
  from .response import Response, JsonResponse, RedirectResponse, FileResponse
4
4
  from .request import Request
@@ -14,6 +14,17 @@ from .websocket import websocket
14
14
  from .module import LocalModule, Module
15
15
  from .cSignal import signal
16
16
 
17
+ async def doFunc(func: Callable, kwargs: Dict[str, Any] = {}):
18
+ _kwargs = {}
19
+ sig = inspect.signature(func)
20
+ for key, value in kwargs.items():
21
+ if key in sig.parameters or 'kwargs' in sig.parameters:
22
+ _kwargs[key] = value
23
+ if inspect.iscoroutinefunction(func):
24
+ return await func(**_kwargs)
25
+ else:
26
+ return func(**_kwargs)
27
+
17
28
  class App:
18
29
  def __init__(self):
19
30
  self.startTimer: float = time.time()
@@ -128,7 +139,7 @@ class App:
128
139
  if signal.receiver('http_response404Handle'):
129
140
  await signal.send_async('http_response404Handle', kwargs)
130
141
  for http_response404Handle in self.http_response404Handles:
131
- _response = await self.doFunc(http_response404Handle, kwargs)
142
+ _response = await doFunc(http_response404Handle, kwargs)
132
143
  if isinstance(_response, BaseResponse):
133
144
  response = _response
134
145
  if not isinstance(response, BaseResponse):
@@ -139,7 +150,7 @@ class App:
139
150
  if signal.receiver('http_response405Handle'):
140
151
  await signal.send_async('http_response405Handle', kwargs)
141
152
  for http_response405Handle in self.http_response405Handles:
142
- _response = await self.doFunc(http_response405Handle, kwargs)
153
+ _response = await doFunc(http_response405Handle, kwargs)
143
154
  if isinstance(_response, BaseResponse):
144
155
  response = _response
145
156
  if not isinstance(response, BaseResponse):
@@ -150,20 +161,20 @@ class App:
150
161
  if signal.receiver('http_beforeRequestHandle'):
151
162
  await signal.send_async('http_beforeRequestHandle', kwargs)
152
163
  for http_beforeRequestHandle in self.http_beforeRequestHandles:
153
- _response = await self.doFunc(http_beforeRequestHandle, kwargs)
164
+ _response = await doFunc(http_beforeRequestHandle, kwargs)
154
165
  if isinstance(_response, BaseResponse):
155
166
  response = _response
156
167
 
157
168
  if not isinstance(response, BaseResponse):
158
169
  requestFunc = requestFunc[request.method]
159
- response = await self.doFunc(requestFunc, kwargs)
170
+ response = await doFunc(requestFunc, kwargs)
160
171
 
161
172
  if isinstance(response, BaseResponse):
162
173
  if signal.receiver('http_afterResponseHandle'):
163
174
  await signal.send_async('http_afterResponseHandle', kwargs)
164
175
  for http_afterResponseHandle in self.http_afterResponseHandles:
165
176
  kwargs['response'] = response
166
- _response = await self.doFunc(http_afterResponseHandle, kwargs)
177
+ _response = await doFunc(http_afterResponseHandle, kwargs)
167
178
  if isinstance(_response, BaseResponse):
168
179
  response = _response
169
180
  else:
@@ -175,7 +186,7 @@ class App:
175
186
  await signal.send_async('http_response500Handle', kwargs)
176
187
  for http_response500Handle in self.http_response500Handles:
177
188
  kwargs['exception'] = e
178
- _response = await self.doFunc(http_response500Handle, kwargs)
189
+ _response = await doFunc(http_response500Handle, kwargs)
179
190
  if isinstance(_response, BaseResponse):
180
191
  response = _response
181
192
  if not isinstance(response, BaseResponse):
@@ -236,14 +247,14 @@ class App:
236
247
  kwargs['request'] = request
237
248
  if requestFunc is None or 'WEBSOCKET' not in requestFunc:
238
249
  for websocket_notFoundHandle in self.websocket_notFoundHandles:
239
- await self.doFunc(websocket_notFoundHandle, kwargs)
250
+ await doFunc(websocket_notFoundHandle, kwargs)
240
251
  return
241
252
  requestFunc = requestFunc['WEBSOCKET']
242
253
 
243
254
  if signal.receiver('websocket_beforeConnectionHandle'):
244
255
  await signal.send_async('websocket_beforeConnectionHandle', kwargs)
245
256
  for websocket_beforeConnectionHandle in self.websocket_beforeConnectionHandles:
246
- await self.doFunc(websocket_beforeConnectionHandle, kwargs)
257
+ await doFunc(websocket_beforeConnectionHandle, kwargs)
247
258
 
248
259
  await send({
249
260
  'type': 'websocket.accept'
@@ -268,7 +279,7 @@ class App:
268
279
  kwargs['value'] = message['text']
269
280
  elif 'bytes' in message:
270
281
  kwargs['value'] = message['bytes']
271
- await self.doFunc(requestFunc, kwargs)
282
+ await doFunc(requestFunc, kwargs)
272
283
  elif message['type'] == 'websocket.disconnect':
273
284
  del websocket._CLIENTS[request.sid]
274
285
  task.cancel()
@@ -279,23 +290,12 @@ class App:
279
290
  if signal.receiver('websocket_afterDisconnectHandle'):
280
291
  await signal.send_async('websocket_afterDisconnectHandle', kwargs)
281
292
  for websocket_afterDisconnectHandle in self.websocket_afterDisconnectHandles:
282
- await self.doFunc(websocket_afterDisconnectHandle, kwargs)
293
+ await doFunc(websocket_afterDisconnectHandle, kwargs)
283
294
  except Exception as e:
284
295
  CheeseLog.danger(f'The error occured while accessing the WEBSOCKET {request.fullPath}\n{traceback.format_exc()}'[:-1], f'The error occured while accessing the \033[36mWEBSOCKET {request.fullPath}\033[0m\n{traceback.format_exc()}'[:-1])
285
296
  for websocket_errorHandle in self.websocket_errorHandles:
286
297
  kwargs['exception'] = e
287
- await self.doFunc(websocket_errorHandle, kwargs)
288
-
289
- async def doFunc(self, func: Callable, kwargs: Dict[str, Any] = {}):
290
- _kwargs = {}
291
- sig = inspect.signature(func)
292
- for key, value in kwargs.items():
293
- if key in sig.parameters or 'kwargs' in sig.parameters:
294
- _kwargs[key] = value
295
- if inspect.iscoroutinefunction(func):
296
- return await func(**_kwargs)
297
- else:
298
- return func(**_kwargs)
298
+ await doFunc(websocket_errorHandle, kwargs)
299
299
 
300
300
  def server_startingHandle(self, func: Callable):
301
301
  self.server_startingHandles.append(func)
@@ -1,7 +1,9 @@
1
- import argparse, time, os, traceback, json, shutil
1
+ import argparse, time, os, traceback, json, shutil, importlib, importlib.util
2
2
 
3
3
  import CheeseLog, uvicorn, CheeseType, CheeseType.network, uvicorn.importer
4
4
 
5
+ from .module import Module, LocalModule
6
+
5
7
  def command():
6
8
  from .app import app
7
9
  from .cSignal import signal
@@ -9,9 +11,9 @@ def command():
9
11
  parser = argparse.ArgumentParser()
10
12
  parser.add_argument('--app', nargs = '?', default = 'app:app', help = '服务器本服务【默认值:app:app】')
11
13
  parser.add_argument('--host', nargs = '?', default = '127.0.0.1', help = '服务器地址【默认值:127.0.0.1】')
12
- parser.add_argument('--port', nargs = '?', default = 5214, help = '端口号【默认值:5214】')
13
- parser.add_argument('--reload', nargs = '?', default = False, help = '热更新。与workers冲突【默认值:False】')
14
- parser.add_argument('--workers', nargs = '?', default = 1, help = 'workers为0时会自动设置为cpu核数*2。与reload冲突【默认值:1】')
14
+ parser.add_argument('--port', type = int, nargs = '?', default = 5214, help = '端口号【默认值:5214】')
15
+ parser.add_argument('--reload', action='store_true', help = '热更新。与workers冲突【默认值:False】')
16
+ parser.add_argument('--workers', type = int, nargs = '?', default = 1, help = 'workers为0时会自动设置为cpu核数*2。与reload冲突【默认值:1】')
15
17
  parser.add_argument('--log_path', nargs = '?', default = '/logs/', help = '日志文件夹的相对路径【默认值:/logs/】')
16
18
  parser.add_argument('--log_filename', nargs = '?', default = False, help = '日志文件名。当值为True时,自动设置为%%Y_%%m_%%d-%%H_%%M_%%S.log;当值为False,关闭日志文件记录;自定义文件名也是允许的【默认值:True】')
17
19
  args = parser.parse_args()
@@ -29,6 +31,9 @@ def command():
29
31
  except:
30
32
  ...
31
33
 
34
+ if reload:
35
+ workers = 1
36
+
32
37
  app.workspace.LOG_PATH = log_path
33
38
  app.server.LOG_FILENAME = log_filename
34
39
  app.server.HOST = host
@@ -101,6 +106,34 @@ current log file path: \033[4;36m.{app.logger.filePath[len(app.workspace.BASE_PA
101
106
 
102
107
  CheeseLog.starting(f'The server running on http://{app.server.HOST}:{app.server.PORT}', f'The server running on \033[4;36mhttp://{app.server.HOST}:{app.server.PORT}\033[0m')
103
108
 
109
+ import sys
110
+ sys.path.append(os.getcwd())
111
+ app = eval(f'__import__(\'{_app.split(":")[0]}\').{_app.split(":")[1]}')
112
+
113
+ _modules = set()
114
+ if len(app.modules):
115
+ CheeseLog.starting(f'Modules:\n{" | ".join(app.modules)}')
116
+ for module in app.modules:
117
+ _modules.add(Module(_modules, module))
118
+ app.modules = _modules
119
+
120
+ if app.localModules is True:
121
+ app.localModules = set()
122
+ for folderName in os.listdir(app.workspace.BASE_PATH):
123
+ if folderName[0] == '.':
124
+ continue
125
+ if folderName in app.exclude_localModules:
126
+ continue
127
+ folderPath = os.path.join(app.workspace.BASE_PATH, folderName)
128
+ if os.path.isdir(folderPath) and folderPath not in [ app.workspace.BASE_PATH + app.workspace.STATIC_PATH[:-1], app.workspace.BASE_PATH + app.workspace.MEDIA_PATH[:-1], app.workspace.BASE_PATH + app.workspace.LOG_PATH[:-1], app.workspace.BASE_PATH + '/__pycache__' ]:
129
+ app.localModules.add(folderName)
130
+ if len(app.localModules):
131
+ CheeseLog.starting(f'Local modules:\n{" | ".join(app.localModules)}')
132
+ _localModules = set()
133
+ for module in app.localModules:
134
+ _localModules.add(LocalModule(app.workspace.BASE_PATH, module))
135
+ app.localModules = _localModules
136
+
104
137
  if signal.receiver('server_startingHandle'):
105
138
  signal.send('server_startingHandle')
106
139
  for server_startingHandle in app.server_startingHandles:
@@ -16,46 +16,6 @@ class BaseItem:
16
16
  return default
17
17
  return self._values[key]
18
18
 
19
- class Args(BaseItem):
20
- def __init__(self, query: str):
21
- super().__init__()
22
-
23
- for q in query.split('&'):
24
- q = q.split('=')
25
- self._values[q[0]] = q[1] if len(q) > 1 else None
26
-
27
- class Form(BaseItem):
28
- @overload
29
- def __init__(self):
30
- ...
31
-
32
- @overload
33
- def __init__(self, body: str):
34
- ...
35
-
36
- @overload
37
- def __init__(self, body: bytes, spliter: bytes):
38
- ...
39
-
40
- def __init__(self, body: str | bytes | None = None, spliter: bytes | None = None):
41
- super().__init__()
42
-
43
- if body and not spliter:
44
- for s in body.split('&'):
45
- s = s.split('=')
46
- self._values[s[0]] = s[1]
47
-
48
- elif body and spliter:
49
- body = body[2:-4].split(spliter)[1:-1]
50
- for s in body:
51
- key = re.findall(rb'\bname="(.*?)"', s)[0].decode()
52
- value = s.split(b'\r\n\r\n')[1][:-4]
53
- filename = re.findall(rb'\bfilename="(.*?)"', s)
54
- if len(filename):
55
- self._values[key] = File(filename[0].decode(), value)
56
- else:
57
- self._values[key] = value.decode()
58
-
59
19
  class Request:
60
20
  def __init__(self, scope, body: bytes | None = None):
61
21
  query_string = scope['query_string'].decode()
@@ -69,9 +29,12 @@ class Request:
69
29
 
70
30
  if scope['type'] in [ 'http', 'https' ]:
71
31
  self.method: str = scope['method']
72
- self.args = Args(query_string)
32
+ self.args: Dict[str, str] = {}
33
+ for q in query_string.split('&'):
34
+ q = q.split('=')
35
+ self.args[q[0]] = q[1] if len(q) > 1 else None
73
36
  self.body = None
74
- self.form: Form = Form()
37
+ self.form: Dict[str, str] = {}
75
38
  for header in scope['headers']:
76
39
  key = header[0].decode()
77
40
  value = header[1].decode()
@@ -85,9 +48,20 @@ class Request:
85
48
  elif value in [ 'text/plain', 'text/html' ]:
86
49
  self.body = body.decode()
87
50
  elif value.startswith('multipart/form-data;'):
88
- self.form = Form(body, header[1].split(b'boundary=')[1].split(b';')[0])
51
+ spliter = header[1].split(b'boundary=')[1].split(b';')[0]
52
+ body = body[2:-4].split(spliter)[1:-1]
53
+ for s in body:
54
+ key = re.findall(rb'\bname="(.*?)"', s)[0].decode()
55
+ value = s.split(b'\r\n\r\n')[1][:-4]
56
+ filename = re.findall(rb'\bfilename="(.*?)"', s)
57
+ if len(filename):
58
+ self.form[key] = File(filename[0].decode(), value)
59
+ else:
60
+ self.form[key] = value.decode()
89
61
  elif value == 'application/x-www-form-urlencoded':
90
- self.form = Form(body.decode())
62
+ for s in body.decode().split('&'):
63
+ s = s.split('=')
64
+ self.form[s[0]] = s[1]
91
65
  except:
92
66
  CheeseLog.danger(f'{self.method} {self.fullPath} cannot parse request.body correctly:\n{traceback.format_exc()}'[:-1], f'\033[36m{self.method} {self.fullPath}\033[0m cannot parse request.body correctly:\n{traceback.format_exc()}'[:-1])
93
67
  else:
@@ -41,7 +41,8 @@ class Server:
41
41
  if not self._IS_DEBUG:
42
42
  self._app.logger.filter.add('DEBUG')
43
43
  elif self._IS_DEBUG:
44
- self._app.logger.filter.remove('DEBUG')
44
+ if 'DEBUG' in self._app.logger.filter:
45
+ self._app.logger.filter.remove('DEBUG')
45
46
 
46
47
  @property
47
48
  def IS_REQUEST_LOGGED(self) -> bool:
@@ -55,8 +56,10 @@ class Server:
55
56
  self._app.logger.filter.add('HTTP')
56
57
  self._app.logger.filter.add('WEBSOCKET')
57
58
  elif self._IS_REQUEST_LOGGED:
58
- self._app.logger.filter.remove('HTTP')
59
- self._app.logger.filter.add('WEBSOCKET')
59
+ if 'HTTP' in self._app.logger.filter:
60
+ self._app.logger.filter.remove('HTTP')
61
+ if 'WEBSOCKET' in self._app.logger.filter:
62
+ self._app.logger.filter.remove('WEBSOCKET')
60
63
 
61
64
  @property
62
65
  def LOG_FILENAME(self) -> str | bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CheeseAPI
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: 一款基于uvicorn的web协程框架
5
5
  Home-page: https://github.com/CheeseUnknown/CheeseAPI
6
6
  Author: Cheese Unknown
@@ -15,7 +15,9 @@ License-File: LICENSE
15
15
 
16
16
  # **CheeseAPI**
17
17
 
18
- 请注意,该文档是最新的beta版,如果你想要查看最新的发布版内容,请查看最新的tag。
18
+ 目前项目仍处于开发阶段,无法保证稳定性。
19
+
20
+ 该文档是最新的beta版,如果你想要查看最新的发布版内容,请查看最新的tag。
19
21
 
20
22
  ## **介绍**
21
23
 
@@ -217,7 +219,7 @@ route = Route('/User', app.route)
217
219
  def register(request: Request):
218
220
  nickname = request.form.get('nickname')
219
221
  password = request.form.get('password')
220
- gender = Gender(request.form.get('gender', 2))
222
+ gender = Gender(int(request.form.get('gender', 2)))
221
223
  service.register(nickname, password, gender)
222
224
  return Response('注册成功!')
223
225
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CheeseAPI
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: 一款基于uvicorn的web协程框架
5
5
  Home-page: https://github.com/CheeseUnknown/CheeseAPI
6
6
  Author: Cheese Unknown
@@ -15,7 +15,9 @@ License-File: LICENSE
15
15
 
16
16
  # **CheeseAPI**
17
17
 
18
- 请注意,该文档是最新的beta版,如果你想要查看最新的发布版内容,请查看最新的tag。
18
+ 目前项目仍处于开发阶段,无法保证稳定性。
19
+
20
+ 该文档是最新的beta版,如果你想要查看最新的发布版内容,请查看最新的tag。
19
21
 
20
22
  ## **介绍**
21
23
 
@@ -217,7 +219,7 @@ route = Route('/User', app.route)
217
219
  def register(request: Request):
218
220
  nickname = request.form.get('nickname')
219
221
  password = request.form.get('password')
220
- gender = Gender(request.form.get('gender', 2))
222
+ gender = Gender(int(request.form.get('gender', 2)))
221
223
  service.register(nickname, password, gender)
222
224
  return Response('注册成功!')
223
225
 
@@ -1,6 +1,8 @@
1
1
  # **CheeseAPI**
2
2
 
3
- 请注意,该文档是最新的beta版,如果你想要查看最新的发布版内容,请查看最新的tag。
3
+ 目前项目仍处于开发阶段,无法保证稳定性。
4
+
5
+ 该文档是最新的beta版,如果你想要查看最新的发布版内容,请查看最新的tag。
4
6
 
5
7
  ## **介绍**
6
8
 
@@ -202,7 +204,7 @@ route = Route('/User', app.route)
202
204
  def register(request: Request):
203
205
  nickname = request.form.get('nickname')
204
206
  password = request.form.get('password')
205
- gender = Gender(request.form.get('gender', 2))
207
+ gender = Gender(int(request.form.get('gender', 2)))
206
208
  service.register(nickname, password, gender)
207
209
  return Response('注册成功!')
208
210
 
@@ -5,7 +5,7 @@ with open('./README.md', 'r', encoding = 'utf-8') as f:
5
5
 
6
6
  setuptools.setup(
7
7
  name = 'CheeseAPI',
8
- version = '0.0.4',
8
+ version = '0.0.6',
9
9
  author = 'Cheese Unknown',
10
10
  author_email = 'cheese@cheese.ren',
11
11
  description = '一款基于uvicorn的web协程框架',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes