CheeseAPI 0.3.5__tar.gz → 0.3.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.
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/app.py +50 -45
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/handle.py +8 -85
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/protocol.py +5 -7
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/signal.py +3 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/workspace.py +5 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/PKG-INFO +13 -15
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/README.md +11 -14
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/pyproject.toml +3 -2
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/.gitignore +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/__init__.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/cors.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/exception.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/file.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/module.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/request.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/response.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/route.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/server.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/websocket.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/CheeseAPI/worker.py +0 -0
- {cheeseapi-0.3.5 → cheeseapi-0.3.6}/LICENSE +0 -0
|
@@ -18,41 +18,43 @@ class App:
|
|
|
18
18
|
|
|
19
19
|
self.workspace: Workspace = Workspace()
|
|
20
20
|
self.server: Server = Server()
|
|
21
|
-
self.httpWorker: HttpWorker = HttpWorker()
|
|
22
|
-
self.websocketWorker: WebsocketWorker = WebsocketWorker()
|
|
23
21
|
self.routeBus: RouteBus = RouteBus()
|
|
24
22
|
self.route: Route = Route()
|
|
25
23
|
self.cors: Cors = Cors()
|
|
26
|
-
self.
|
|
24
|
+
self.g: Dict[str, Any] = {}
|
|
25
|
+
self.managers: Dict[str, Any] = {
|
|
26
|
+
'lock': multiprocessing.Lock()
|
|
27
|
+
}
|
|
27
28
|
|
|
28
29
|
self.modules: List[str] = []
|
|
29
30
|
self.localModules: List[str] | Literal[True] = True
|
|
30
31
|
self.exclude_localModules: List[str] = []
|
|
31
32
|
self.preferred_localModules: List[str] = []
|
|
32
33
|
|
|
33
|
-
self.
|
|
34
|
-
self.
|
|
34
|
+
self.httpWorker: HttpWorker = HttpWorker()
|
|
35
|
+
self.websocketWorker: WebsocketWorker = WebsocketWorker()
|
|
36
|
+
self._handle: Handle = Handle()
|
|
37
|
+
self._managers: Dict[str, Any] = {
|
|
38
|
+
'firstRequest': multiprocessing.Value('b', False),
|
|
39
|
+
'startedWorkerNum': multiprocessing.Value('i', 0)
|
|
40
|
+
}
|
|
35
41
|
|
|
36
42
|
def init(self):
|
|
37
43
|
try:
|
|
38
|
-
self.
|
|
44
|
+
self._handle._initHandle(self)
|
|
39
45
|
except Exception as e:
|
|
40
46
|
sys.excepthook(Exception, e, sys.exc_info()[2])
|
|
41
47
|
|
|
42
|
-
def run(self, *, managers: Dict[str,
|
|
48
|
+
def run(self, *, managers: Dict[str, Any] = {}):
|
|
43
49
|
if 'startTimer' not in app.g:
|
|
44
|
-
logger.error('The app has not yet been initiated
|
|
50
|
+
logger.error('The app has not yet been initiated')
|
|
45
51
|
else:
|
|
46
52
|
try:
|
|
47
53
|
self.managers.update(managers)
|
|
48
54
|
manager = multiprocessing.Manager()
|
|
49
|
-
self.
|
|
50
|
-
self.managers['startedWorkerNum'] = manager.Value(int, 0)
|
|
51
|
-
self.managers['firstRequest'] = manager.Value(bool, False)
|
|
55
|
+
self._managers['workspace.logger'] = manager.Value(str, self.workspace.logger)
|
|
52
56
|
|
|
53
|
-
self.
|
|
54
|
-
for server_beforeStartingHandle in self.handle.server_beforeStartingHandles:
|
|
55
|
-
server_beforeStartingHandle()
|
|
57
|
+
self._handle._server_beforeStartingHandle(self)
|
|
56
58
|
if signal.receiver('server_beforeStartingHandle'):
|
|
57
59
|
signal.send('server_beforeStartingHandle')
|
|
58
60
|
|
|
@@ -63,70 +65,73 @@ class App:
|
|
|
63
65
|
|
|
64
66
|
multiprocessing.allow_connection_pickling()
|
|
65
67
|
for i in range(0, self.server.workers - 1):
|
|
66
|
-
process = multiprocessing.Process(target = run, args = (self, sock), name = f'
|
|
68
|
+
process = multiprocessing.Process(target = run, args = (self, sock), name = f'CheeseAPI_subprocess')
|
|
67
69
|
process.start()
|
|
68
70
|
|
|
69
71
|
run(self, sock, True)
|
|
70
72
|
|
|
71
|
-
while self.
|
|
72
|
-
time.sleep(0.
|
|
73
|
+
while self._managers['startedWorkerNum'].value != 0:
|
|
74
|
+
time.sleep(0.01)
|
|
73
75
|
except Exception as e:
|
|
74
76
|
sys.excepthook(Exception, e, sys.exc_info()[2])
|
|
75
77
|
|
|
76
78
|
if signal.receiver('server_beforeStoppingHandle'):
|
|
77
79
|
signal.send('server_beforeStoppingHandle')
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
self.handle._server_beforeStoppingHandle(self)
|
|
81
|
-
logger.destory()
|
|
80
|
+
self._handle._server_beforeStoppingHandle(self)
|
|
81
|
+
logger.destroy()
|
|
82
82
|
|
|
83
83
|
app = App()
|
|
84
84
|
|
|
85
|
-
async def _run(
|
|
85
|
+
async def _run(_app: App, sock: socket.socket, master: bool = False):
|
|
86
86
|
from CheeseAPI.protocol import HttpProtocol
|
|
87
87
|
|
|
88
|
-
app.
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
app.g = _app.g
|
|
89
|
+
app.managers = _app.managers
|
|
90
|
+
app._managers = _app._managers
|
|
91
|
+
|
|
92
|
+
app.workspace.logger = app._managers['workspace.logger'].value
|
|
93
|
+
|
|
94
|
+
app._handle._worker_beforeStartingHandle()
|
|
91
95
|
if signal.receiver('worker_beforeStartingHandle'):
|
|
92
|
-
signal.
|
|
96
|
+
await signal.async_send('worker_beforeStartingHandle')
|
|
93
97
|
|
|
94
|
-
HttpProtocol.managers = app.
|
|
98
|
+
HttpProtocol.managers = app._managers
|
|
95
99
|
|
|
96
100
|
loop = asyncio.get_running_loop()
|
|
97
101
|
server = await loop.create_server(HttpProtocol, sock = sock)
|
|
98
|
-
loop.add_signal_handler(pySignal.SIGINT, app.
|
|
99
|
-
loop.add_signal_handler(pySignal.SIGTERM, app.
|
|
102
|
+
loop.add_signal_handler(pySignal.SIGINT, app._handle._exitSignalHandle, server)
|
|
103
|
+
loop.add_signal_handler(pySignal.SIGTERM, app._handle._exitSignalHandle, server)
|
|
100
104
|
|
|
101
|
-
for worker_afterStartingHandle in app.handle.worker_afterStartingHandles:
|
|
102
|
-
worker_afterStartingHandle()
|
|
103
105
|
if signal.receiver('worker_afterStartingHandle'):
|
|
104
|
-
signal.
|
|
106
|
+
await signal.async_send('worker_afterStartingHandle')
|
|
105
107
|
|
|
106
108
|
with app.managers['lock']:
|
|
107
|
-
app.
|
|
108
|
-
if app.
|
|
109
|
-
app.
|
|
110
|
-
for server_afterStartingHandle in app.handle.server_afterStartingHandles:
|
|
111
|
-
server_afterStartingHandle()
|
|
109
|
+
app._managers['startedWorkerNum'].value += 1
|
|
110
|
+
if app._managers['startedWorkerNum'].value == app.server.workers:
|
|
111
|
+
app._handle._server_afterStartingHandle(app)
|
|
112
112
|
if signal.receiver('server_afterStartingHandle'):
|
|
113
|
-
signal.
|
|
113
|
+
await signal.async_send('server_afterStartingHandle')
|
|
114
114
|
|
|
115
115
|
while server.is_serving():
|
|
116
|
-
|
|
116
|
+
if app._managers['workspace.logger'].value != app.workspace.logger:
|
|
117
|
+
app.workspace.logger = app._managers['workspace.logger'].value
|
|
118
|
+
|
|
119
|
+
await asyncio.sleep(0.01)
|
|
117
120
|
|
|
118
121
|
if signal.receiver('worker_beforeStoppingHandle'):
|
|
119
|
-
signal.
|
|
120
|
-
|
|
121
|
-
worker_beforeStoppingHandle()
|
|
122
|
-
app.handle._worker_beforeStoppingHandle(app)
|
|
122
|
+
await signal.async_send('worker_beforeStoppingHandle')
|
|
123
|
+
app._handle._worker_beforeStoppingHandle(app)
|
|
123
124
|
|
|
124
125
|
with app.managers['lock']:
|
|
125
|
-
app.
|
|
126
|
+
app._managers['startedWorkerNum'].value -= 1
|
|
126
127
|
|
|
127
128
|
if not master:
|
|
128
|
-
logger.
|
|
129
|
+
logger.destroy()
|
|
129
130
|
|
|
130
131
|
def run(app, sock, master: bool = False):
|
|
132
|
+
import setproctitle
|
|
133
|
+
|
|
134
|
+
setproctitle.setproctitle('CheeseAPI_masterProcess' if master else 'CheeseAPI_subprocess')
|
|
135
|
+
|
|
131
136
|
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
132
137
|
asyncio.run(_run(app, sock, master))
|
|
@@ -14,20 +14,6 @@ if TYPE_CHECKING:
|
|
|
14
14
|
from CheeseAPI.protocol import WebsocketProtocol, Protocol
|
|
15
15
|
|
|
16
16
|
class Handle:
|
|
17
|
-
def __init__(self):
|
|
18
|
-
self.afterInitHandles: List[Callable] = []
|
|
19
|
-
self.server_beforeStartingHandles: List[Callable] = []
|
|
20
|
-
self.worker_beforeStartingHandles: List[Callable] = []
|
|
21
|
-
self.worker_afterStartingHandles: List[Callable] = []
|
|
22
|
-
self.server_afterStartingHandles: List[Callable] = []
|
|
23
|
-
self.context_beforeFirstRequestHandles: List[Callable] = []
|
|
24
|
-
self.http_beforeRequestHandles: List[Callable] = []
|
|
25
|
-
self.http_afterResponseHandles: List[Callable] = []
|
|
26
|
-
self.websocket_beforeConnectionHandles: List[Callable] = []
|
|
27
|
-
self.websocket_afterDisconnectionHandles: List[Callable] = []
|
|
28
|
-
self.worker_beforeStoppingHandles: List[Callable] = []
|
|
29
|
-
self.server_beforeStoppingHandles: List[Callable] = []
|
|
30
|
-
|
|
31
17
|
async def _httpHandle(self, protocol: 'Protocol', app: 'App'):
|
|
32
18
|
try:
|
|
33
19
|
if app.server.static and protocol.request.path.startswith(app.server.static) and protocol.request.method == http.HTTPMethod.GET:
|
|
@@ -40,8 +26,6 @@ class Handle:
|
|
|
40
26
|
try:
|
|
41
27
|
func, kwargs = app.routeBus._match(protocol.request.path, protocol.request.method)
|
|
42
28
|
|
|
43
|
-
for http_beforeRequestHandle in self.http_beforeRequestHandles:
|
|
44
|
-
await http_beforeRequestHandle(**{ 'request': protocol.request })
|
|
45
29
|
if signal.receiver('http_beforeRequestHandle'):
|
|
46
30
|
await signal.async_send('http_beforeRequestHandle', { 'request': protocol.request })
|
|
47
31
|
|
|
@@ -99,16 +83,6 @@ class Handle:
|
|
|
99
83
|
|
|
100
84
|
if signal.receiver('afterInitHandle'):
|
|
101
85
|
signal.send('afterInitHandle')
|
|
102
|
-
for afterInitHandle in app.handle.afterInitHandles:
|
|
103
|
-
afterInitHandle()
|
|
104
|
-
|
|
105
|
-
def afterInitHandle(self, func: Callable):
|
|
106
|
-
self.afterInitHandles.append(func)
|
|
107
|
-
return func
|
|
108
|
-
|
|
109
|
-
def server_beforeStartingHandle(self, func: Callable):
|
|
110
|
-
self.server_beforeStartingHandles.append(func)
|
|
111
|
-
return func
|
|
112
86
|
|
|
113
87
|
def _server_beforeStartingHandle(self, app: 'App'):
|
|
114
88
|
logger.starting(f'The master process {os.getpid()} started', f'The master process <blue>{os.getpid()}</blue> started')
|
|
@@ -136,39 +110,19 @@ Workers: <blue>{app.server.workers}</blue>''' + (f'''
|
|
|
136
110
|
Static: <cyan>{app.server.static}</cyan>''' if app.server.static else ''))
|
|
137
111
|
|
|
138
112
|
if app.modules:
|
|
139
|
-
logger.
|
|
113
|
+
logger.loaded(f'''Modules:
|
|
140
114
|
''' + ' | '.join(app.modules))
|
|
141
115
|
|
|
142
116
|
if app.localModules:
|
|
143
|
-
logger.
|
|
117
|
+
logger.loaded(f'''Local Modules:
|
|
144
118
|
''' + ' | '.join(app.localModules))
|
|
145
119
|
|
|
146
|
-
def worker_beforeStartingHandle(self, func: Callable):
|
|
147
|
-
self.worker_beforeStartingHandles.append(func)
|
|
148
|
-
return func
|
|
149
|
-
|
|
150
120
|
def _worker_beforeStartingHandle(self):
|
|
151
121
|
logger.debug(f'The subprocess {os.getpid()} started', f'The subprocess <blue>{os.getpid()}</blue> started')
|
|
152
122
|
|
|
153
|
-
def worker_afterStartingHandle(self, func: Callable):
|
|
154
|
-
self.worker_afterStartingHandles.append(func)
|
|
155
|
-
return func
|
|
156
|
-
|
|
157
|
-
def server_afterStartingHandle(self, func: Callable):
|
|
158
|
-
self.server_afterStartingHandles.append(func)
|
|
159
|
-
return func
|
|
160
|
-
|
|
161
123
|
def _server_afterStartingHandle(self, app: 'App'):
|
|
162
124
|
logger.starting(f'The server started on http://{app.server.host}:{app.server.port}', f'The server started on <cyan><underline>http://{app.server.host}:{app.server.port}</underline></cyan>')
|
|
163
125
|
|
|
164
|
-
def context_beforeFirstRequestHandle(self, func: Callable):
|
|
165
|
-
self.context_beforeFirstRequestHandles.append(func)
|
|
166
|
-
return func
|
|
167
|
-
|
|
168
|
-
def http_beforeRequestHandle(self, func: Callable):
|
|
169
|
-
self.http_beforeRequestHandles.append(func)
|
|
170
|
-
return func
|
|
171
|
-
|
|
172
126
|
async def _http_staticHandle(self, protocol: 'Protocol', app: 'App'):
|
|
173
127
|
return FileResponse(app.workspace.static[:-1] + protocol.request.path)
|
|
174
128
|
|
|
@@ -203,11 +157,6 @@ A usable BaseResponse is not returned''')
|
|
|
203
157
|
'response': response,
|
|
204
158
|
'request': protocol.request
|
|
205
159
|
})
|
|
206
|
-
for http_afterResponseHandle in self.http_afterResponseHandles:
|
|
207
|
-
await http_afterResponseHandle(**{
|
|
208
|
-
'response': response,
|
|
209
|
-
'request': protocol.request
|
|
210
|
-
})
|
|
211
160
|
|
|
212
161
|
if app.cors.origin == '*':
|
|
213
162
|
response.headers['Access-Control-Allow-Origin'] = app.cors.origin
|
|
@@ -241,17 +190,13 @@ A usable BaseResponse is not returned''')
|
|
|
241
190
|
if protocol.deque:
|
|
242
191
|
_protocol = protocol.deque.popleft()
|
|
243
192
|
_protocol.transport.resume_reading()
|
|
244
|
-
protocol.task = asyncio.get_event_loop().create_task(app.
|
|
193
|
+
protocol.task = asyncio.get_event_loop().create_task(app._handle._httpHandle(_protocol, app))
|
|
245
194
|
protocol.task.add_done_callback(app.httpWorker.tasks.discard)
|
|
246
195
|
app.httpWorker.tasks.add(protocol.task)
|
|
247
196
|
|
|
248
197
|
return True
|
|
249
198
|
return False
|
|
250
199
|
|
|
251
|
-
def http_afterResponseHandle(self, func: Callable):
|
|
252
|
-
self.http_afterResponseHandles.append(func)
|
|
253
|
-
return func
|
|
254
|
-
|
|
255
200
|
async def _websocket_requestHandle(self, protocol: 'WebsocketProtocol', app: 'App') -> Tuple[Callable, Dict[str, Any]] | HTTPResponse:
|
|
256
201
|
try:
|
|
257
202
|
func, kwargs = app.routeBus._match(protocol.request.path, 'WEBSOCKET')
|
|
@@ -270,14 +215,12 @@ A usable BaseResponse is not returned''')
|
|
|
270
215
|
async def _websocket_405Handle(self, protocol: 'WebsocketProtocol', app: 'App') -> Response:
|
|
271
216
|
return Response(status = http.HTTPStatus.METHOD_NOT_ALLOWED)
|
|
272
217
|
|
|
273
|
-
async def _websocket_responseHandle(self, protocol: 'WebsocketProtocol', app: 'App', response) -> HTTPResponse:
|
|
274
|
-
|
|
275
|
-
|
|
218
|
+
async def _websocket_responseHandle(self, protocol: 'WebsocketProtocol', app: 'App', response: BaseResponse) -> HTTPResponse:
|
|
219
|
+
if signal.receiver('http_afterResponseHandle'):
|
|
220
|
+
await signal.async_send('http_afterResponseHandle', {
|
|
276
221
|
'response': response,
|
|
277
222
|
'request': protocol.request
|
|
278
223
|
})
|
|
279
|
-
if isinstance(_response, BaseResponse):
|
|
280
|
-
response = _response
|
|
281
224
|
|
|
282
225
|
logger.http(f'The {protocol.request.headers.get("X-Forwarded-For").split(", ")[0]} accessed WEBSOCKET {protocol.request.fullPath} and returned {response.status}', f'The <cyan>{protocol.request.headers.get("X-Forwarded-For").split(", ")[0]}</cyan> accessed <cyan>WEBSOCKET ' + logger.encode(protocol.request.fullPath) + f'</cyan> and returned <blue>{response.status}</blue>')
|
|
283
226
|
|
|
@@ -290,10 +233,6 @@ A usable BaseResponse is not returned''')
|
|
|
290
233
|
})
|
|
291
234
|
return protocol.func[0].subprotocolHandle(**kwargs)
|
|
292
235
|
|
|
293
|
-
def websocket_beforeConnectionHandle(self, func: Callable):
|
|
294
|
-
self.websocket_beforeConnectionHandles.append(func)
|
|
295
|
-
return func
|
|
296
|
-
|
|
297
236
|
async def _websocket_connectionHandle(self, protocol: 'WebsocketProtocol', app: 'App'):
|
|
298
237
|
try:
|
|
299
238
|
logger.websocket(f'The {protocol.request.headers.get("X-Forwarded-For").split(", ")[0]} connected WEBSOCKET {protocol.request.fullPath}', f'The <cyan>{protocol.request.headers.get("X-Forwarded-For").split(", ")[0]}</cyan> connected <cyan>WEBSOCKET {protocol.request.fullPath}</cyan>')
|
|
@@ -307,15 +246,13 @@ A usable BaseResponse is not returned''')
|
|
|
307
246
|
|
|
308
247
|
async def _websocket_handler(self, protocol: 'WebsocketProtocol', app: 'App'):
|
|
309
248
|
try:
|
|
310
|
-
for websocket_beforeConnectionHandle in app.handle.websocket_beforeConnectionHandles:
|
|
311
|
-
await websocket_beforeConnectionHandle(**protocol.func[1])
|
|
312
249
|
if signal.receiver('websocket_beforeConnectionHandle'):
|
|
313
250
|
await signal.async_send('websocket_beforeConnectionHandle', protocol.func[1])
|
|
314
251
|
|
|
315
|
-
await app.
|
|
252
|
+
await app._handle._websocket_connectionHandle(protocol, app)
|
|
316
253
|
|
|
317
254
|
while not protocol.closed:
|
|
318
|
-
await app.
|
|
255
|
+
await app._handle._websocket_messageHandle(protocol, app)
|
|
319
256
|
except:
|
|
320
257
|
message = logger.encode(traceback.format_exc()[:-1])
|
|
321
258
|
logger.danger(f'''An error occurred while receiving WEBSOCKET {protocol.request.fullPath} message:
|
|
@@ -341,10 +278,6 @@ A usable BaseResponse is not returned''')
|
|
|
341
278
|
{message}''', f'''An error occurred while receiving <cyan>WEBSOCKET {protocol.request.fullPath}</cyan> message:
|
|
342
279
|
{message}''')
|
|
343
280
|
|
|
344
|
-
def websocket_afterDisconnectionHandle(self, func: Callable):
|
|
345
|
-
self.websocket_afterDisconnectionHandles.append(func)
|
|
346
|
-
return func
|
|
347
|
-
|
|
348
281
|
def _websocket_disconnectionHandle(self, protocol: 'WebsocketProtocol', app: 'App'):
|
|
349
282
|
if not protocol.func:
|
|
350
283
|
return
|
|
@@ -356,25 +289,15 @@ A usable BaseResponse is not returned''')
|
|
|
356
289
|
|
|
357
290
|
if signal.receiver('websocket_afterDisconnectionHandle'):
|
|
358
291
|
signal.send('websocket_afterDisconnectionHandle', protocol.func[1])
|
|
359
|
-
for websocket_afterDisconnectionHandle in app.handle.websocket_afterDisconnectionHandles:
|
|
360
|
-
websocket_afterDisconnectionHandle(**protocol.func[1])
|
|
361
292
|
except:
|
|
362
293
|
message = logger.encode(traceback.format_exc()[:-1])
|
|
363
294
|
logger.danger(f'''An error occurred while disconnecting WEBSOCKET {protocol.request.fullPath}:
|
|
364
295
|
{message}''', f'''An error occurred while disconnecting <cyan>WEBSOCKET {protocol.request.fullPath}</cyan>:
|
|
365
296
|
{message}''')
|
|
366
297
|
|
|
367
|
-
def worker_beforeStoppingHandle(self, func: Callable):
|
|
368
|
-
self.worker_beforeStoppingHandles.append(func)
|
|
369
|
-
return func
|
|
370
|
-
|
|
371
298
|
def _worker_beforeStoppingHandle(self, app: 'App'):
|
|
372
299
|
logger.debug(f'The {os.getpid()} subprocess stopped', f'The <blue>{os.getpid()}</blue> subprocess stopped')
|
|
373
300
|
|
|
374
|
-
def server_beforeStoppingHandle(self, func: Callable):
|
|
375
|
-
self.server_beforeStoppingHandles.append(func)
|
|
376
|
-
return func
|
|
377
|
-
|
|
378
301
|
def _server_beforeStoppingHandle(self, app: 'App'):
|
|
379
302
|
timer = time.time() - app.g['startTimer']
|
|
380
303
|
message = 'The server runs for a total of '
|
|
@@ -48,7 +48,7 @@ class WebsocketProtocol(WebSocketServerProtocol):
|
|
|
48
48
|
super().connection_made(transport)
|
|
49
49
|
|
|
50
50
|
async def process_request(self, *args, **kwargs) -> HTTPResponse | None:
|
|
51
|
-
result = await app.
|
|
51
|
+
result = await app._handle._websocket_requestHandle(self, app)
|
|
52
52
|
if len(result) == 3:
|
|
53
53
|
return result
|
|
54
54
|
self.func = result
|
|
@@ -56,13 +56,13 @@ class WebsocketProtocol(WebSocketServerProtocol):
|
|
|
56
56
|
self.func[0].close = self.close
|
|
57
57
|
|
|
58
58
|
def process_subprotocol(self, *args, **kwargs) -> str:
|
|
59
|
-
self.func[1]['subprotocol'] = app.
|
|
59
|
+
self.func[1]['subprotocol'] = app._handle._websocket_subprotocolHandle(self, app)
|
|
60
60
|
if self.func[1]['subprotocol'] not in self.request.headers.get('Sec-Websocket-Protocol', '').split(', '):
|
|
61
61
|
raise InvalidHandshake()
|
|
62
62
|
return self.func[1]['subprotocol']
|
|
63
63
|
|
|
64
64
|
async def ws_handler(self, *args, **kwargs):
|
|
65
|
-
await app.
|
|
65
|
+
await app._handle._websocket_handler(self, app)
|
|
66
66
|
|
|
67
67
|
def connection_lost(self, exc: Exception | None) -> None:
|
|
68
68
|
app.websocketWorker.connections.discard(self)
|
|
@@ -70,7 +70,7 @@ class WebsocketProtocol(WebSocketServerProtocol):
|
|
|
70
70
|
if exc is None:
|
|
71
71
|
self.transport.close()
|
|
72
72
|
|
|
73
|
-
app.
|
|
73
|
+
app._handle._websocket_disconnectionHandle(self, app)
|
|
74
74
|
|
|
75
75
|
class Protocol:
|
|
76
76
|
def __init__(self, parser):
|
|
@@ -87,8 +87,6 @@ class HttpProtocol(asyncio.Protocol):
|
|
|
87
87
|
|
|
88
88
|
def __init__(self):
|
|
89
89
|
if not HttpProtocol.managers['firstRequest'].value:
|
|
90
|
-
for context_beforeFirstRequestHandle in app.handle.context_beforeFirstRequestHandles:
|
|
91
|
-
context_beforeFirstRequestHandle()
|
|
92
90
|
if signal.receiver('context_beforeFirstRequestHandle'):
|
|
93
91
|
signal.send('context_beforeFirstRequestHandle')
|
|
94
92
|
HttpProtocol.managers['firstRequest'].value = True
|
|
@@ -149,7 +147,7 @@ class HttpProtocol(asyncio.Protocol):
|
|
|
149
147
|
self.protocol.transport.pause_reading()
|
|
150
148
|
self.protocol.deque.append(self.protocol)
|
|
151
149
|
else:
|
|
152
|
-
self.protocol.task = asyncio.get_event_loop().create_task(app.
|
|
150
|
+
self.protocol.task = asyncio.get_event_loop().create_task(app._handle._httpHandle(self.protocol, app))
|
|
153
151
|
self.protocol.task.add_done_callback(app.httpWorker.tasks.discard)
|
|
154
152
|
app.httpWorker.tasks.add(self.protocol.task)
|
|
155
153
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import blinker
|
|
2
|
+
from ordered_set import OrderedSet
|
|
2
3
|
|
|
3
4
|
class Signal(dict):
|
|
4
5
|
def register(self, name: str):
|
|
@@ -32,6 +33,8 @@ class Signal(dict):
|
|
|
32
33
|
|
|
33
34
|
await self[name].send_async(*args, **kwargs)
|
|
34
35
|
|
|
36
|
+
blinker.Signal.set_class = OrderedSet
|
|
37
|
+
|
|
35
38
|
signal = Signal()
|
|
36
39
|
|
|
37
40
|
signal.register('afterInitHandle')
|
|
@@ -16,6 +16,8 @@ class Workspace:
|
|
|
16
16
|
|
|
17
17
|
@logger.setter
|
|
18
18
|
def logger(self, value: str | bool):
|
|
19
|
+
from CheeseAPI import app
|
|
20
|
+
|
|
19
21
|
if value is True:
|
|
20
22
|
self._logger = datetime.datetime.now().strftime('%Y_%m_%d-%H_%M_%S.log')
|
|
21
23
|
elif value is False:
|
|
@@ -24,3 +26,6 @@ class Workspace:
|
|
|
24
26
|
else:
|
|
25
27
|
self._logger = datetime.datetime.now().strftime(str(value))
|
|
26
28
|
logger.filePath = self.log + self._logger
|
|
29
|
+
|
|
30
|
+
if 'workspace.logger' in app._managers and app._managers['workspace.logger'].value != logger.filePath:
|
|
31
|
+
app._managers['workspace.logger'].value = self.logger
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CheeseAPI
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: 一款web协程框架。
|
|
5
5
|
Project-URL: Source, https://github.com/CheeseUnknown/CheeseAPI
|
|
6
6
|
Author-email: Cheese Unknown <cheese@cheese.ren>
|
|
@@ -8,6 +8,7 @@ License-File: LICENSE
|
|
|
8
8
|
Requires-Dist: blinker
|
|
9
9
|
Requires-Dist: cheeselog
|
|
10
10
|
Requires-Dist: httptools
|
|
11
|
+
Requires-Dist: ordered-set
|
|
11
12
|
Requires-Dist: uvloop
|
|
12
13
|
Requires-Dist: websockets
|
|
13
14
|
Requires-Dist: xmltodict
|
|
@@ -111,31 +112,28 @@ CheeseAPI采用类Django的结构:
|
|
|
111
112
|
| model.py | 模型类 |
|
|
112
113
|
| api.py | api接口 |
|
|
113
114
|
| service.py | 业务逻辑实现 |
|
|
115
|
+
| handle.py | 初始化逻辑 |
|
|
114
116
|
|
|
115
117
|
## **更多...**
|
|
116
118
|
|
|
117
|
-
### 1. [
|
|
119
|
+
### 1. [**App**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App.md)
|
|
118
120
|
|
|
119
|
-
|
|
121
|
+
#### 1.1 [**Workspace**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App/Workspace.md)
|
|
120
122
|
|
|
121
|
-
#### 2
|
|
123
|
+
#### 1.2 [**Server**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App/Server.md)
|
|
122
124
|
|
|
123
|
-
####
|
|
125
|
+
#### 1.3 [**Cors**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App/Cors.md)
|
|
124
126
|
|
|
125
|
-
|
|
127
|
+
### 2. [**Route**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Route.md)
|
|
126
128
|
|
|
127
|
-
|
|
129
|
+
### 3. [**Request**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Request.md)
|
|
128
130
|
|
|
129
|
-
###
|
|
131
|
+
### 4. [**Response**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Response.md)
|
|
130
132
|
|
|
131
|
-
###
|
|
133
|
+
### 5. [**Websocket**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Websocket.md)
|
|
132
134
|
|
|
133
|
-
###
|
|
135
|
+
### 6. [**Module**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Module.md)
|
|
134
136
|
|
|
135
|
-
###
|
|
136
|
-
|
|
137
|
-
### 7. [**Module**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Module.md)
|
|
137
|
+
### 7. [**Signal**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Signal.md)
|
|
138
138
|
|
|
139
139
|
### 8. [**File**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/File.md)
|
|
140
|
-
|
|
141
|
-
### 9. [**Signal**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Signal.md)
|
|
@@ -96,31 +96,28 @@ CheeseAPI采用类Django的结构:
|
|
|
96
96
|
| model.py | 模型类 |
|
|
97
97
|
| api.py | api接口 |
|
|
98
98
|
| service.py | 业务逻辑实现 |
|
|
99
|
+
| handle.py | 初始化逻辑 |
|
|
99
100
|
|
|
100
101
|
## **更多...**
|
|
101
102
|
|
|
102
|
-
### 1. [
|
|
103
|
+
### 1. [**App**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App.md)
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
#### 1.1 [**Workspace**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App/Workspace.md)
|
|
105
106
|
|
|
106
|
-
#### 2
|
|
107
|
+
#### 1.2 [**Server**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App/Server.md)
|
|
107
108
|
|
|
108
|
-
####
|
|
109
|
+
#### 1.3 [**Cors**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/App/Cors.md)
|
|
109
110
|
|
|
110
|
-
|
|
111
|
+
### 2. [**Route**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Route.md)
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
### 3. [**Request**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Request.md)
|
|
113
114
|
|
|
114
|
-
###
|
|
115
|
+
### 4. [**Response**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Response.md)
|
|
115
116
|
|
|
116
|
-
###
|
|
117
|
+
### 5. [**Websocket**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Websocket.md)
|
|
117
118
|
|
|
118
|
-
###
|
|
119
|
+
### 6. [**Module**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Module.md)
|
|
119
120
|
|
|
120
|
-
###
|
|
121
|
-
|
|
122
|
-
### 7. [**Module**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Module.md)
|
|
121
|
+
### 7. [**Signal**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Signal.md)
|
|
123
122
|
|
|
124
123
|
### 8. [**File**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/File.md)
|
|
125
|
-
|
|
126
|
-
### 9. [**Signal**](https://github.com/CheeseUnknown/CheeseAPI/blob/master/documents/Signal.md)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "CheeseAPI"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.6"
|
|
8
8
|
description = "一款web协程框架。"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [
|
|
@@ -16,7 +16,8 @@ dependencies = [
|
|
|
16
16
|
"blinker",
|
|
17
17
|
"websockets",
|
|
18
18
|
"uvloop",
|
|
19
|
-
"httptools"
|
|
19
|
+
"httptools",
|
|
20
|
+
"ordered_set"
|
|
20
21
|
]
|
|
21
22
|
|
|
22
23
|
[project.urls]
|
|
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
|