CheeseAPI 2.0.6b3__tar.gz → 2.0.7__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.
@@ -334,7 +334,8 @@ class AppProxy:
334
334
  async def get_response(self, request: Request) -> Response:
335
335
  if inspect.isfunction(request.fn):
336
336
  try:
337
- if 'request' in inspect.signature(request.fn).parameters:
337
+ signature = inspect.signature(request.fn)
338
+ if 'request' in signature.parameters or any(p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values()):
338
339
  return await request.fn(request = request)
339
340
  else:
340
341
  return await request.fn()
@@ -258,11 +258,11 @@ class SchedulerProxy:
258
258
  coro.close()
259
259
 
260
260
  def _start_pubsub(self, app: 'CheeseAPI'):
261
- pubsub = redis.Redis(connection_pool = static.scheduler_sync_servers[0]).pubsub()
262
- pubsub.subscribe('CheeseAPI_scheduler')
263
261
  try:
264
262
  while True:
265
263
  try:
264
+ pubsub = redis.Redis(connection_pool = static.scheduler_sync_servers[0]).pubsub()
265
+ pubsub.subscribe('CheeseAPI_scheduler')
266
266
  for message in pubsub.listen():
267
267
  if message['type'] == 'message':
268
268
  data = json.loads(message['data'])
@@ -278,9 +278,7 @@ class SchedulerProxy:
278
278
  elif data[0] == 'remove':
279
279
  self.remove(data[1])
280
280
  except redis.exceptions.RedisError:
281
- pubsub.close()
282
281
  time.sleep(app.sync_server_timeout)
283
- self._start_pubsub(app)
284
282
  except (KeyboardInterrupt, SystemExit):
285
283
  ...
286
284
 
@@ -353,49 +351,36 @@ class SchedulerProxy:
353
351
 
354
352
  def task_processing(self, key: str, queue: multiprocessing.Queue, fn, *args, **kwargs):
355
353
  try:
356
- task = self.get_task(key)
357
- if not task:
358
- return
359
-
360
354
  queue.get()
361
- first_run = True
362
355
 
356
+ task = self.get_task(key)
357
+ if static.scheduler_sync_servers:
358
+ task._queue.get()
363
359
  if task.first_run_timer:
364
360
  time.sleep(max(0, task.first_run_timer.timestamp() - time.time()))
365
361
 
366
362
  while not queue.qsize():
367
- if static.scheduler_sync_servers:
368
- task = self.get_task(key)
369
- if (not task or (not first_run and task._queue.qsize())):
370
- break
371
-
372
363
  now = time.time()
373
364
 
374
365
  try:
375
- if 'app' in inspect.signature(fn).parameters:
366
+ signature = inspect.signature(fn)
367
+ has_kwargs = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values())
368
+ if 'app' in signature.parameters or has_kwargs:
376
369
  fn(*args, app = self.app, **kwargs)
377
370
  else:
378
371
  fn(*args, **kwargs)
379
372
  except Exception as e:
380
373
  self.app.printer.scheduler_error(e, task)
381
374
 
382
- if static.scheduler_sync_servers:
383
- task = self.get_task(key)
384
-
385
- if task:
386
- task._last_run_time = time.time() - now
387
- task._last_run_timer = datetime.datetime.fromtimestamp(now)
388
- task._run_num += 1
389
-
390
- if static.scheduler_sync_servers:
391
- sync_server = redis.Redis(connection_pool = static.scheduler_sync_servers[0])
392
- sync_server.hset('CheeseAPI_scheduler_tasks', key, json.dumps(task._to_dict()))
393
- sync_server.hpexpire('CheeseAPI_scheduler_tasks', int(task.timeout * 1000), key)
375
+ task._last_run_time = time.time() - now
376
+ task._last_run_timer = datetime.datetime.fromtimestamp(now)
377
+ task._run_num += 1
394
378
 
395
- if (not task or task._queue.qsize()) or task.run_num_completed:
396
- break
379
+ if static.scheduler_sync_servers:
380
+ sync_server = redis.Redis(connection_pool = static.scheduler_sync_servers[0])
381
+ sync_server.hset('CheeseAPI_scheduler_tasks', key, json.dumps(task._to_dict()))
382
+ sync_server.hpexpire('CheeseAPI_scheduler_tasks', int(task.timeout * 1000), key)
397
383
 
398
- first_run = False
399
384
  time.sleep(max(0, task.interval_time - time.time() + now))
400
385
  except (KeyboardInterrupt, SystemExit):
401
386
  ...
@@ -404,52 +389,42 @@ class SchedulerProxy:
404
389
  redis.Redis(connection_pool = static.scheduler_sync_servers[0]).hpersist('CheeseAPI_scheduler_tasks', key)
405
390
 
406
391
  async def async_task_processing(self, key: str, queue: multiprocessing.Queue, fn, *args, **kwargs):
407
- task = self.get_task(key)
408
- if not task:
409
- return
410
-
411
392
  queue.get()
412
- first_run = True
413
393
 
394
+ task = await self.async_get_task(key)
395
+ if static.scheduler_sync_servers:
396
+ task._queue.get()
414
397
  if task.first_run_timer:
415
398
  await asyncio.sleep(max(0, task.first_run_timer.timestamp() - time.time()))
416
399
 
417
400
  while not queue.qsize():
418
- if static.scheduler_sync_servers:
419
- task = await self.async_get_task(key)
420
- if (not task or (not first_run and task._queue.qsize())):
421
- break
422
-
423
401
  now = time.time()
424
402
 
425
403
  try:
426
- if 'app' in inspect.signature(fn).parameters:
404
+ signature = inspect.signature(fn)
405
+ has_kwargs = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values())
406
+ if 'app' in signature.parameters or has_kwargs:
427
407
  await fn(*args, app = self.app, **kwargs)
428
408
  else:
429
409
  await fn(*args, **kwargs)
430
410
  except Exception as e:
431
411
  self.app.printer.scheduler_error(e, task)
432
412
 
433
- if static.scheduler_sync_servers:
434
- task = await self.async_get_task(key)
413
+ task._last_run_time = time.time() - now
414
+ task._last_run_timer = datetime.datetime.fromtimestamp(now)
415
+ task._run_num += 1
435
416
 
436
- if task:
437
- task._last_run_time = time.time() - now
438
- task._last_run_timer = datetime.datetime.fromtimestamp(now)
439
- task._run_num += 1
440
-
441
- if static.scheduler_sync_servers:
442
- sync_server = redis.asyncio.Redis(connection_pool = static.scheduler_sync_servers[1])
443
- await sync_server.hset('CheeseAPI_scheduler_tasks', key, json.dumps(task._to_dict()))
444
- await sync_server.hpexpire('CheeseAPI_scheduler_tasks', int(task.timeout * 1000), key)
417
+ if static.scheduler_sync_servers:
418
+ sync_server = redis.asyncio.Redis(connection_pool = static.scheduler_sync_servers[1])
419
+ await sync_server.hset('CheeseAPI_scheduler_tasks', key, json.dumps(task._to_dict()))
420
+ await sync_server.hpexpire('CheeseAPI_scheduler_tasks', int(task.timeout * 1000), key)
445
421
 
446
- if (not task or task._queue.qsize()) or task.run_num_completed:
422
+ if task.run_num_completed:
447
423
  break
448
424
 
449
- first_run = False
450
425
  await asyncio.sleep(max(0, task.interval_time - time.time() + now))
451
426
 
452
- if not task or task.auto_remove:
427
+ if task.auto_remove:
453
428
  self._tasks.pop(key, None)
454
429
  if static.scheduler_sync_servers is not None:
455
430
  await redis.asyncio.Redis(connection_pool = static.scheduler_sync_servers[1]).hdel('CheeseAPI_scheduler_tasks', key)
@@ -526,6 +501,7 @@ class SchedulerProxy:
526
501
  if static.scheduler_sync_servers:
527
502
  redis.Redis(connection_pool = static.scheduler_sync_servers[0]).publish('CheeseAPI_scheduler', json.dumps(['remove', key]))
528
503
  else:
504
+ _task._queue.put(None)
529
505
  self._tasks.pop(key, None)
530
506
  if static.scheduler_sync_servers:
531
507
  redis.Redis(connection_pool = static.scheduler_sync_servers[0]).hdel('CheeseAPI_scheduler_tasks', key)
@@ -556,6 +532,7 @@ class SchedulerProxy:
556
532
  if static.scheduler_sync_servers:
557
533
  await redis.asyncio.Redis(connection_pool = static.scheduler_sync_servers[1]).publish('CheeseAPI_scheduler', json.dumps(['remove', key]))
558
534
  else:
535
+ _task._queue.put(None)
559
536
  self._tasks.pop(key, None)
560
537
  if static.scheduler_sync_servers:
561
538
  await redis.asyncio.Redis(connection_pool = static.scheduler_sync_servers[1]).hdel('CheeseAPI_scheduler_tasks', key)
@@ -1,4 +1,4 @@
1
- import json
1
+ import json, inspect
2
2
  from typing import Callable, TYPE_CHECKING
3
3
  from functools import wraps
4
4
 
@@ -20,10 +20,8 @@ def validator(*, json_model: pydantic.BaseModel | None = None, form_model: pydan
20
20
 
21
21
  def wrapper(fn: Callable) -> Callable:
22
22
  @wraps(fn)
23
- async def decorator(*args, **kwargs):
23
+ async def decorator(*args, request: 'Request', **kwargs):
24
24
  try:
25
- request: 'Request' = kwargs.get('request', None)
26
-
27
25
  json_data = None
28
26
  if json_model is not None:
29
27
  json_data = json_model.model_validate(request.json or {}, by_alias = True)
@@ -59,6 +57,10 @@ def validator(*, json_model: pydantic.BaseModel | None = None, form_model: pydan
59
57
  else:
60
58
  return Response(json.loads(e.json()), 400)
61
59
 
62
- return await fn(*args, **kwargs)
60
+ signature = inspect.signature(fn)
61
+ if 'request' in signature.parameters or any(p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values()):
62
+ return await fn(*args, request = request, **kwargs)
63
+ else:
64
+ return await fn(*args, **kwargs)
63
65
  return decorator
64
66
  return wrapper
@@ -2,7 +2,7 @@ import base64, hashlib, asyncio, ssl, struct, json
2
2
  from functools import partial
3
3
  from typing import TYPE_CHECKING, AsyncIterable, Self
4
4
 
5
- import redis
5
+ import redis, redis.exceptions
6
6
 
7
7
  from CheeseAPI import static
8
8
  from CheeseAPI.response import Response
@@ -246,35 +246,43 @@ class WebsocketProxy:
246
246
  await self.websocket.on_connect()
247
247
 
248
248
  async def sync_server_running(self):
249
- if self.app.sync_server_url.startswith('redis'):
250
- pubsub = static.websocket_sync_server[self.websocket.request.path].pubsub()
251
- await pubsub.subscribe(self.websocket.request.path)
252
- async for message in pubsub.listen():
253
- if message['type'] != 'message':
254
- continue
255
-
256
- connectors = Websocket.connectors.get(self.websocket.request.path)
257
- if not connectors:
258
- continue
259
-
260
- message = message['data']
261
- if static.websocket_data_decode is not None:
262
- message = static.websocket_data_decode(message)
263
- message = json.loads(message.decode())
264
- if isinstance(message['key'], list):
265
- connectors = [connector for connector in connectors if connector.key in message['key']]
266
- elif isinstance(message['key'], str):
267
- connectors = [connector for connector in connectors if connector.key == message['key']]
268
- else:
269
- connectors = [connector for connector in connectors]
270
-
271
- if connectors:
272
- if message['event'] == 'send':
273
- for connector in connectors:
274
- asyncio.create_task(connector.send(message['data']))
275
- elif message['event'] == 'close':
276
- for connector in connectors:
277
- asyncio.create_task(connector.close())
249
+ try:
250
+ if self.app.sync_server_url.startswith('redis'):
251
+ while True:
252
+ try:
253
+ pubsub = static.websocket_sync_server[self.websocket.request.path].pubsub()
254
+ await pubsub.subscribe(self.websocket.request.path)
255
+ async for message in pubsub.listen():
256
+ print(message)
257
+ if message['type'] != 'message':
258
+ continue
259
+
260
+ connectors = Websocket.connectors.get(self.websocket.request.path)
261
+ if not connectors:
262
+ continue
263
+
264
+ message = message['data']
265
+ if static.websocket_data_decode is not None:
266
+ message = static.websocket_data_decode(message)
267
+ message = json.loads(message.decode())
268
+ if isinstance(message['key'], list):
269
+ connectors = [connector for connector in connectors if connector.key in message['key']]
270
+ elif isinstance(message['key'], str):
271
+ connectors = [connector for connector in connectors if connector.key == message['key']]
272
+ else:
273
+ connectors = [connector for connector in connectors]
274
+
275
+ if connectors:
276
+ if message['event'] == 'send':
277
+ for connector in connectors:
278
+ asyncio.create_task(connector.send(message['data']))
279
+ elif message['event'] == 'close':
280
+ for connector in connectors:
281
+ asyncio.create_task(connector.close())
282
+ except redis.exceptions.RedisError:
283
+ await asyncio.sleep(self.app.sync_server_timeout)
284
+ except (KeyboardInterrupt, SystemExit, asyncio.CancelledError):
285
+ ...
278
286
 
279
287
  async def message(self):
280
288
  while True:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CheeseAPI
3
- Version: 2.0.6b3
3
+ Version: 2.0.7
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 = "2.0.6-beta.3"
7
+ version = "2.0.7"
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