CheeseAPI 1.2.1__tar.gz → 1.2.3__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.2.1 → cheeseapi-1.2.3}/CheeseAPI/app.py +4 -1
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/handle.py +87 -74
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/text.py +1 -14
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/validator.py +4 -1
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/PKG-INFO +1 -1
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/pyproject.toml +1 -1
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/.gitignore +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/__init__.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/cors.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/exception.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/file.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/protocol.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/request.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/response.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/route.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/schedule.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/server.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/signal.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/websocket.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/CheeseAPI/workspace.py +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/LICENSE +0 -0
- {cheeseapi-1.2.1 → cheeseapi-1.2.3}/README.md +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import multiprocessing, os
|
|
1
|
+
import multiprocessing, os, setproctitle, sys
|
|
2
2
|
from typing import Dict, Any, List
|
|
3
3
|
|
|
4
4
|
from CheeseAPI.text import Text
|
|
@@ -276,4 +276,7 @@ class App:
|
|
|
276
276
|
|
|
277
277
|
return self._preferred_localModules
|
|
278
278
|
|
|
279
|
+
if ' '.join(sys.argv) in setproctitle.getproctitle():
|
|
280
|
+
setproctitle.setproctitle('CheeseAPI')
|
|
281
|
+
|
|
279
282
|
app: App = App()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import time, os, inspect, socket, multiprocessing, signal, http, ipaddress, datetime
|
|
1
|
+
import time, os, inspect, socket, multiprocessing, signal, http, ipaddress, datetime, traceback
|
|
2
2
|
from typing import TYPE_CHECKING, Dict, Tuple, List
|
|
3
3
|
|
|
4
4
|
import asyncio, uvloop, setproctitle, websockets
|
|
@@ -109,68 +109,78 @@ class Handle:
|
|
|
109
109
|
logger.loaded(text[0], text[1], refreshed = True)
|
|
110
110
|
|
|
111
111
|
def server_start(self):
|
|
112
|
-
self._app._handle.server_beforeStarting()
|
|
113
|
-
if self._app.signal.server_beforeStarting.receivers:
|
|
114
|
-
self._app.signal.server_beforeStarting.send()
|
|
115
|
-
|
|
116
112
|
try:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
|
121
|
-
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
122
|
-
sock.bind((self._app.server.host, self._app.server.port))
|
|
123
|
-
sock.listen(self._app.server.backlog)
|
|
124
|
-
sock.set_inheritable(True)
|
|
125
|
-
|
|
126
|
-
processes: List[multiprocessing.Process] = []
|
|
127
|
-
multiprocessing.allow_connection_pickling()
|
|
128
|
-
for i in range(self._app.server.workers - 1):
|
|
129
|
-
process = multiprocessing.Process(target = self.worker_start, args = (sock,), name = self._app._text.workerProcess_title)
|
|
130
|
-
process.start()
|
|
131
|
-
processes.append(process)
|
|
132
|
-
|
|
133
|
-
self.worker_start(sock, True)
|
|
134
|
-
|
|
135
|
-
for process in processes:
|
|
136
|
-
process.terminate()
|
|
137
|
-
process.join()
|
|
138
|
-
|
|
139
|
-
for text in self._app._text.server_stopping():
|
|
140
|
-
logger.ending(text[0], text[1])
|
|
113
|
+
self._app._handle.server_beforeStarting()
|
|
114
|
+
if self._app.signal.server_beforeStarting.receivers:
|
|
115
|
+
self._app.signal.server_beforeStarting.send()
|
|
141
116
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
117
|
+
try:
|
|
118
|
+
ipaddress.IPv4Address(self._app.server.host)
|
|
119
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
120
|
+
except ipaddress.AddressValueError:
|
|
121
|
+
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
|
122
|
+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
123
|
+
sock.bind((self._app.server.host, self._app.server.port))
|
|
124
|
+
sock.listen(self._app.server.backlog)
|
|
125
|
+
sock.set_inheritable(True)
|
|
126
|
+
|
|
127
|
+
processes: List[multiprocessing.Process] = []
|
|
128
|
+
multiprocessing.allow_connection_pickling()
|
|
129
|
+
for i in range(self._app.server.workers - 1):
|
|
130
|
+
process = multiprocessing.Process(target = self.worker_start, args = (sock,), name = self._app._text.workerProcess_title)
|
|
131
|
+
process.start()
|
|
132
|
+
processes.append(process)
|
|
133
|
+
|
|
134
|
+
self.worker_start(sock, True)
|
|
135
|
+
|
|
136
|
+
for process in processes:
|
|
137
|
+
process.terminate()
|
|
138
|
+
process.join()
|
|
139
|
+
|
|
140
|
+
for text in self._app._text.server_stopping():
|
|
141
|
+
logger.ending(text[0], text[1])
|
|
142
|
+
|
|
143
|
+
self.server_afterStopping()
|
|
144
|
+
if self._app.signal.server_afterStopping.receivers:
|
|
145
|
+
self._app.signal.server_afterStopping.send()
|
|
146
|
+
except KeyboardInterrupt:
|
|
147
|
+
...
|
|
148
|
+
except:
|
|
149
|
+
logger.error(f'''
|
|
150
|
+
{logger.encode(traceback.format_exc()[:-1])}''')
|
|
151
|
+
finally:
|
|
152
|
+
logger.destroy()
|
|
153
|
+
os.killpg(os.getpid(), signal.SIGKILL)
|
|
149
154
|
|
|
150
155
|
def worker_beforeStarting(self):
|
|
151
156
|
for text in self._app._text.worker_starting():
|
|
152
157
|
logger.debug(text[0], text[1])
|
|
153
158
|
|
|
154
159
|
def worker_start(self, sock, master: bool = False):
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
try:
|
|
161
|
+
if not master:
|
|
162
|
+
setproctitle.setproctitle(self._app._text.workerProcess_title)
|
|
157
163
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
164
|
+
self.worker_beforeStarting()
|
|
165
|
+
if self._app.signal.worker_beforeStarting.receivers:
|
|
166
|
+
self._app.signal.worker_beforeStarting.send()
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
169
|
+
asyncio.run(self.worker_run(sock, master))
|
|
164
170
|
|
|
165
|
-
|
|
166
|
-
|
|
171
|
+
with self._app._managers_['lock']:
|
|
172
|
+
self._app._managers_['server.workers'].value -= 1
|
|
167
173
|
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
for text in self._app._text.worker_stopping():
|
|
175
|
+
logger.debug(text[0], text[1])
|
|
170
176
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
177
|
+
self.worker_afterStopping()
|
|
178
|
+
if self._app.signal.worker_afterStopping.receivers:
|
|
179
|
+
self._app.signal.worker_afterStopping.send()
|
|
180
|
+
except:
|
|
181
|
+
logger.error(f'''The process {os.getpid()} stopped
|
|
182
|
+
{logger.encode(traceback.format_exc()[:-1])}''', f'''The process <blue>{os.getpid()}</blue> stopped
|
|
183
|
+
{logger.encode(traceback.format_exc()[:-1])}''')
|
|
174
184
|
|
|
175
185
|
async def worker_run(self, sock, master: bool):
|
|
176
186
|
from CheeseAPI.app import app
|
|
@@ -344,7 +354,7 @@ class Handle:
|
|
|
344
354
|
})
|
|
345
355
|
|
|
346
356
|
await self.http_response(protocol)
|
|
347
|
-
except
|
|
357
|
+
except Exception as e:
|
|
348
358
|
try:
|
|
349
359
|
await self.http_500(protocol, e)
|
|
350
360
|
if self._app.signal.http_500.receivers:
|
|
@@ -355,13 +365,13 @@ class Handle:
|
|
|
355
365
|
**protocol.kwargs
|
|
356
366
|
})
|
|
357
367
|
await self.http_response(protocol)
|
|
358
|
-
except
|
|
368
|
+
except Exception as e:
|
|
359
369
|
await self.http_500(protocol, e, True)
|
|
360
370
|
await self.http_response(protocol, True)
|
|
361
371
|
|
|
362
372
|
async def http_static(self, protocol: 'HttpProtocol'):
|
|
363
373
|
if self._app.server.static and self._app.workspace.static and protocol.request.path.startswith(self._app.server.static) and protocol.request.method == http.HTTPMethod.GET:
|
|
364
|
-
for key in [ '', '.html', '/index.html' ]:
|
|
374
|
+
for key in [ '', '.html', 'index.html', '/index.html' ]:
|
|
365
375
|
try:
|
|
366
376
|
protocol.response = FileResponse(os.path.join(self._app.workspace.static, protocol.request.path[1:] + key))
|
|
367
377
|
|
|
@@ -470,7 +480,7 @@ class Handle:
|
|
|
470
480
|
try:
|
|
471
481
|
Server, kwargs = self._app.routeBus._match(protocol.request.path, 'WEBSOCKET')
|
|
472
482
|
protocol.kwargs.update(kwargs)
|
|
473
|
-
except
|
|
483
|
+
except Route_404_Exception as e:
|
|
474
484
|
await self.websocket_afterRequest(protocol)
|
|
475
485
|
if self._app.signal.websocket_afterRequest.receivers:
|
|
476
486
|
await self._app.signal.websocket_afterRequest.async_send(**{
|
|
@@ -478,27 +488,30 @@ class Handle:
|
|
|
478
488
|
**protocol.kwargs
|
|
479
489
|
})
|
|
480
490
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
await self.
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
'response': protocol.response,
|
|
497
|
-
**protocol.kwargs
|
|
498
|
-
})
|
|
499
|
-
return await self.websocket_response(protocol)
|
|
491
|
+
await self.websocket_404(protocol)
|
|
492
|
+
if self._app.signal.websocket_404.receivers:
|
|
493
|
+
await self._app.signal.websocket_404.async_send(**{
|
|
494
|
+
'request': protocol.request,
|
|
495
|
+
'response': protocol.response,
|
|
496
|
+
**protocol.kwargs
|
|
497
|
+
})
|
|
498
|
+
return await self.websocket_response(protocol)
|
|
499
|
+
except Route_405_Exception as e:
|
|
500
|
+
await self.websocket_afterRequest(protocol)
|
|
501
|
+
if self._app.signal.websocket_afterRequest.receivers:
|
|
502
|
+
await self._app.signal.websocket_afterRequest.async_send(**{
|
|
503
|
+
'request': protocol.request,
|
|
504
|
+
**protocol.kwargs
|
|
505
|
+
})
|
|
500
506
|
|
|
501
|
-
|
|
507
|
+
await self.websocket_405(protocol)
|
|
508
|
+
if self._app.signal.websocket_405.receivers:
|
|
509
|
+
await self._app.signal.websocket_405.async_send(**{
|
|
510
|
+
'request': protocol.request,
|
|
511
|
+
'response': protocol.response,
|
|
512
|
+
**protocol.kwargs
|
|
513
|
+
})
|
|
514
|
+
return await self.websocket_response(protocol)
|
|
502
515
|
|
|
503
516
|
protocol.server = Server()
|
|
504
517
|
|
|
@@ -14,12 +14,9 @@ class Text:
|
|
|
14
14
|
self.progressBar: ProgressBar = ProgressBar()
|
|
15
15
|
|
|
16
16
|
self.response_server: str = 'CheeseAPI'
|
|
17
|
-
self.
|
|
18
|
-
self.workerProcess_title: str = 'CheeseAPI:Process'
|
|
17
|
+
self.workerProcess_title: str = f'{setproctitle.getproctitle()}:Process'
|
|
19
18
|
self.logger: str = '%Y_%m_%d.log'
|
|
20
19
|
|
|
21
|
-
setproctitle.setproctitle(self._process_title)
|
|
22
|
-
|
|
23
20
|
def server_information(self) -> List[Tuple[str, str]]:
|
|
24
21
|
return [
|
|
25
22
|
(f'The master process {os.getpid()} started', f'The master process <blue>{os.getpid()}</blue> started'),
|
|
@@ -167,13 +164,3 @@ Static: <cyan>{self._app.server.static}</cyan>''' if self._app.workspace.static
|
|
|
167
164
|
|
|
168
165
|
def validator_enumMessage(self, scope: str, key: str, enum: List[Any]) -> str:
|
|
169
166
|
return f'The {scope}.{key} cannot be a value other than {enum}'
|
|
170
|
-
|
|
171
|
-
@property
|
|
172
|
-
def process_title(self) -> str:
|
|
173
|
-
return self._process_title
|
|
174
|
-
|
|
175
|
-
@process_title.setter
|
|
176
|
-
def process_title(self, value: str):
|
|
177
|
-
self._process_title = value
|
|
178
|
-
|
|
179
|
-
setproctitle.setproctitle(self._process_title)
|
|
@@ -123,7 +123,10 @@ class Validator:
|
|
|
123
123
|
if validatedForm[f'{self.scope}.{self.key}'] is None:
|
|
124
124
|
if self.required:
|
|
125
125
|
raise ValidateError(self.response or Response(app._text.validator_requiredMessage(self.scope, self.key), 400))
|
|
126
|
-
|
|
126
|
+
if callable(self.default):
|
|
127
|
+
validatedForm[f'{self.scope}.{self.key}'] = self.default()
|
|
128
|
+
else:
|
|
129
|
+
validatedForm[f'{self.scope}.{self.key}'] = self.default
|
|
127
130
|
|
|
128
131
|
if validatedForm[f'{self.scope}.{self.key}'] is not None:
|
|
129
132
|
if self.type is not None:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|