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.
@@ -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
- ipaddress.IPv4Address(self._app.server.host)
118
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
119
- except ipaddress.AddressValueError:
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
- self.server_afterStopping()
143
- if self._app.signal.server_afterStopping.receivers:
144
- self._app.signal.server_afterStopping.send()
145
-
146
- logger.destroy()
147
-
148
- os.killpg(os.getpid(), signal.SIGKILL)
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
- if not master:
156
- setproctitle.setproctitle(self._app._text.workerProcess_title)
160
+ try:
161
+ if not master:
162
+ setproctitle.setproctitle(self._app._text.workerProcess_title)
157
163
 
158
- self.worker_beforeStarting()
159
- if self._app.signal.worker_beforeStarting.receivers:
160
- self._app.signal.worker_beforeStarting.send()
164
+ self.worker_beforeStarting()
165
+ if self._app.signal.worker_beforeStarting.receivers:
166
+ self._app.signal.worker_beforeStarting.send()
161
167
 
162
- asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
163
- asyncio.run(self.worker_run(sock, master))
168
+ asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
169
+ asyncio.run(self.worker_run(sock, master))
164
170
 
165
- with self._app._managers_['lock']:
166
- self._app._managers_['server.workers'].value -= 1
171
+ with self._app._managers_['lock']:
172
+ self._app._managers_['server.workers'].value -= 1
167
173
 
168
- for text in self._app._text.worker_stopping():
169
- logger.debug(text[0], text[1])
174
+ for text in self._app._text.worker_stopping():
175
+ logger.debug(text[0], text[1])
170
176
 
171
- self.worker_afterStopping()
172
- if self._app.signal.worker_afterStopping.receivers:
173
- self._app.signal.worker_afterStopping.send()
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 BaseException as e:
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 BaseException as e:
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 KeyError as e:
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
- if e.args[0] == 0:
482
- await self.websocket_404(protocol)
483
- if self._app.signal.websocket_404.receivers:
484
- await self._app.signal.websocket_404.async_send(**{
485
- 'request': protocol.request,
486
- 'response': protocol.response,
487
- **protocol.kwargs
488
- })
489
- return await self.websocket_response(protocol)
490
-
491
- elif e.args[0] == 1:
492
- await self.websocket_405(protocol)
493
- if self._app.signal.websocket_405.receivers:
494
- await self._app.signal.websocket_405.async_send(**{
495
- 'request': protocol.request,
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
- raise e
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._process_title: str = 'CheeseAPI'
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
- validatedForm[f'{self.scope}.{self.key}'] = self.default
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: CheeseAPI
3
- Version: 1.2.1
3
+ Version: 1.2.3
4
4
  Summary: 一款web协程框架。
5
5
  Project-URL: Source, https://github.com/CheeseUnknown/CheeseAPI
6
6
  Author-email: Cheese Unknown <cheese@cheese.ren>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "CheeseAPI"
7
- version = "1.2.1"
7
+ version = "1.2.3"
8
8
  description = "一款web协程框架。"
9
9
  readme = "README.md"
10
10
  license-files = { paths = [ "LICENSE" ] }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes