cloudoll 2.2.33__tar.gz → 2.2.35__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.
- {cloudoll-2.2.33 → cloudoll-2.2.35}/PKG-INFO +1 -1
- cloudoll-2.2.35/cloudoll/__init__.py +1 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/cli.py +2 -2
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/web/__init__.py +67 -12
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/web/settings.py +8 -4
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll.egg-info/PKG-INFO +1 -1
- cloudoll-2.2.33/cloudoll/__init__.py +0 -1
- {cloudoll-2.2.33 → cloudoll-2.2.35}/LICENSE +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/README.md +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/__main__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/error/__init__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/error/errors.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/logging/__init__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/mail/__init__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/mail/smtp.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/__init__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/base.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/err.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/field.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/model.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/mysql.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/parse.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/orm/postgres.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/robot/__init__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/robot/dingtalk.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/robot/feishu.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/robot/slack.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/utils/__init__.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/utils/common.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/utils/m2d.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/utils/patch_loop.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/utils/snowflake.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/utils/watch.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/web/exception.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/web/html.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/web/http.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll/web/jwt.py +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll.egg-info/SOURCES.txt +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll.egg-info/dependency_links.txt +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll.egg-info/entry_points.txt +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll.egg-info/requires.txt +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/cloudoll.egg-info/top_level.txt +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/setup.cfg +0 -0
- {cloudoll-2.2.33 → cloudoll-2.2.35}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.35"
|
|
@@ -115,8 +115,8 @@ def start(environment, host, port, mode, path, entry) -> None:
|
|
|
115
115
|
except KeyboardInterrupt:
|
|
116
116
|
sys.exit(0)
|
|
117
117
|
except Exception as e:
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
print_error(e)
|
|
119
|
+
print_error(traceback.format_exc())
|
|
120
120
|
sys.exit(0)
|
|
121
121
|
|
|
122
122
|
|
|
@@ -13,7 +13,7 @@ import inspect
|
|
|
13
13
|
import json
|
|
14
14
|
from errno import EADDRINUSE
|
|
15
15
|
from urllib import parse
|
|
16
|
-
from aiohttp import web
|
|
16
|
+
from aiohttp import web, hdrs
|
|
17
17
|
from aiohttp.web import Response
|
|
18
18
|
from aiohttp.web_ws import WebSocketResponse, StreamResponse, WSMsgType
|
|
19
19
|
from aiohttp.web_response import LooseHeaders
|
|
@@ -24,7 +24,6 @@ from aiohttp_session import (
|
|
|
24
24
|
memcached_storage,
|
|
25
25
|
cookie_storage,
|
|
26
26
|
)
|
|
27
|
-
from setuptools import find_packages
|
|
28
27
|
from .settings import get_config
|
|
29
28
|
import aiomcache
|
|
30
29
|
from redis import asyncio as aioredis
|
|
@@ -38,7 +37,7 @@ from ..orm import create_engine, parse_coon
|
|
|
38
37
|
import uuid
|
|
39
38
|
|
|
40
39
|
# from ..orm.mysql import Mysql
|
|
41
|
-
from typing import Optional, Iterable
|
|
40
|
+
from typing import Optional, Iterable, Callable, Awaitable
|
|
42
41
|
|
|
43
42
|
__ALL__ = (
|
|
44
43
|
"app",
|
|
@@ -46,21 +45,22 @@ __ALL__ = (
|
|
|
46
45
|
"Response",
|
|
47
46
|
"WebStream",
|
|
48
47
|
"WSMsgType",
|
|
49
|
-
"
|
|
48
|
+
"View",
|
|
49
|
+
"routes" "get",
|
|
50
50
|
"put",
|
|
51
51
|
"delete",
|
|
52
|
+
"post",
|
|
52
53
|
"render_json",
|
|
53
54
|
"render_error",
|
|
54
|
-
"middleware",
|
|
55
55
|
"render_view",
|
|
56
|
+
"middleware",
|
|
56
57
|
"redirect",
|
|
57
58
|
"jwt",
|
|
58
59
|
)
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
class RequestHandler(object):
|
|
62
|
-
def __init__(self,
|
|
63
|
-
self.cls = cls
|
|
63
|
+
def __init__(self, fn):
|
|
64
64
|
self.fn = fn
|
|
65
65
|
|
|
66
66
|
async def __call__(self, request):
|
|
@@ -182,7 +182,7 @@ class Application(object):
|
|
|
182
182
|
return
|
|
183
183
|
entry = importlib.import_module(entry_model, ".")
|
|
184
184
|
|
|
185
|
-
life_cycle = ["on_startup", "on_shutdown", "on_cleanup", "
|
|
185
|
+
life_cycle = ["on_startup", "on_shutdown", "on_cleanup", "on_task"]
|
|
186
186
|
for cycle in life_cycle:
|
|
187
187
|
if hasattr(entry, cycle):
|
|
188
188
|
cy = getattr(self, cycle)
|
|
@@ -391,7 +391,7 @@ class Application(object):
|
|
|
391
391
|
|
|
392
392
|
def add_router(self, path, method, name):
|
|
393
393
|
def inner(handler):
|
|
394
|
-
handler = RequestHandler(
|
|
394
|
+
handler = RequestHandler(handler)
|
|
395
395
|
self.app.router.add_route(method, path, handler, name=name)
|
|
396
396
|
return handler
|
|
397
397
|
|
|
@@ -435,10 +435,66 @@ class Application(object):
|
|
|
435
435
|
return self.app.on_cleanup
|
|
436
436
|
|
|
437
437
|
@property
|
|
438
|
-
def
|
|
438
|
+
def on_task(self):
|
|
439
439
|
return self.app.cleanup_ctx
|
|
440
440
|
|
|
441
441
|
|
|
442
|
+
class View(web.View):
|
|
443
|
+
async def _iter(self) -> StreamResponse:
|
|
444
|
+
request = self.request
|
|
445
|
+
if request.method not in hdrs.METH_ALL:
|
|
446
|
+
self._raise_allowed_methods()
|
|
447
|
+
method: Optional[Callable[[], Awaitable[StreamResponse]]]
|
|
448
|
+
method = getattr(self, request.method.lower(), None)
|
|
449
|
+
if method is None:
|
|
450
|
+
self._raise_allowed_methods()
|
|
451
|
+
# result = await method()
|
|
452
|
+
# assert isinstance(ret, StreamResponse)
|
|
453
|
+
# return ret
|
|
454
|
+
content_type = request.content_type
|
|
455
|
+
# 获取函数参数的名称和默认值
|
|
456
|
+
props = inspect.getfullargspec(method)
|
|
457
|
+
if len(props.args) == 3 and content_type == "multipart/form-data":
|
|
458
|
+
await set_session_route(request)
|
|
459
|
+
multipart = await request.multipart()
|
|
460
|
+
field = await multipart.next()
|
|
461
|
+
result = await method(request, field)
|
|
462
|
+
elif len(props.args) == 2:
|
|
463
|
+
await set_session_route(request)
|
|
464
|
+
if content_type == "multipart/form-data":
|
|
465
|
+
data = await request.post()
|
|
466
|
+
elif content_type == "application/json":
|
|
467
|
+
data = await request.json()
|
|
468
|
+
else:
|
|
469
|
+
data = await request.post()
|
|
470
|
+
query_string = request.query_string
|
|
471
|
+
body = {}
|
|
472
|
+
for k in data:
|
|
473
|
+
body[k] = data[k]
|
|
474
|
+
qs = {}
|
|
475
|
+
if query_string:
|
|
476
|
+
for k, v in parse.parse_qs(query_string, True).items():
|
|
477
|
+
qs[k] = v[0]
|
|
478
|
+
request.qs = Object(qs)
|
|
479
|
+
request.body = Object(body)
|
|
480
|
+
result = await method(request)
|
|
481
|
+
else:
|
|
482
|
+
result = await method()
|
|
483
|
+
try:
|
|
484
|
+
if isinstance(result, Response):
|
|
485
|
+
return result
|
|
486
|
+
if isinstance(result, StreamResponse):
|
|
487
|
+
return result
|
|
488
|
+
if isinstance(result, WebSocketResponse): # maybe catch error
|
|
489
|
+
return result
|
|
490
|
+
if "content_type" in result and "text/html" in result["content_type"]:
|
|
491
|
+
return result
|
|
492
|
+
except:
|
|
493
|
+
pass
|
|
494
|
+
|
|
495
|
+
return render_json(result)
|
|
496
|
+
|
|
497
|
+
|
|
442
498
|
app = Application()
|
|
443
499
|
|
|
444
500
|
|
|
@@ -510,8 +566,7 @@ def delete(path: str, name=None):
|
|
|
510
566
|
return app.add_router(path, "DELETE", name)
|
|
511
567
|
|
|
512
568
|
|
|
513
|
-
def
|
|
514
|
-
# return app._actions(path, 'GET')
|
|
569
|
+
def routes(path: str):
|
|
515
570
|
return app.route_table.view(path)
|
|
516
571
|
|
|
517
572
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import yaml
|
|
2
2
|
import os
|
|
3
3
|
from ..logging import print_error, print_info
|
|
4
4
|
from envyaml import EnvYAML
|
|
@@ -12,7 +12,11 @@ def get_config(env):
|
|
|
12
12
|
if not os.path.exists(conf_path):
|
|
13
13
|
print_error(f"Configuration file does not exist: {conf_path}")
|
|
14
14
|
return {}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
with open(conf_path, "r", encoding="utf-8") as f:
|
|
16
|
+
config = yaml.safe_load(f)
|
|
17
|
+
try:
|
|
18
|
+
config_ori = EnvYAML(conf_path, strict=False)
|
|
19
|
+
config = dict(config_ori)
|
|
20
|
+
except BaseException as e:
|
|
21
|
+
print_error(e)
|
|
18
22
|
return config or {}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.33"
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|