cloudoll 2.2.15__tar.gz → 2.2.17__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.15 → cloudoll-2.2.17}/PKG-INFO +1 -1
- cloudoll-2.2.17/cloudoll/__init__.py +1 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/cli.py +12 -10
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/model.py +31 -26
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/utils/watch.py +1 -1
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/web/__init__.py +36 -62
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/web/settings.py +1 -1
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll.egg-info/PKG-INFO +1 -1
- {cloudoll-2.2.15 → cloudoll-2.2.17}/setup.py +1 -1
- cloudoll-2.2.15/cloudoll/__init__.py +0 -1
- {cloudoll-2.2.15 → cloudoll-2.2.17}/LICENSE +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/README.md +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/__main__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/error/__init__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/error/errors.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/logging/__init__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/mail/__init__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/mail/smtp.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/__init__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/base.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/err.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/field.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/mysql.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/parse.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/orm/postgres.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/robot/__init__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/robot/dingtalk.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/robot/feishu.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/robot/slack.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/utils/__init__.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/utils/common.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/utils/m2d.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/utils/patch_loop.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/web/exception.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/web/html.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/web/http.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll/web/jwt.py +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll.egg-info/SOURCES.txt +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll.egg-info/dependency_links.txt +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll.egg-info/entry_points.txt +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll.egg-info/requires.txt +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/cloudoll.egg-info/top_level.txt +0 -0
- {cloudoll-2.2.15 → cloudoll-2.2.17}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.17"
|
|
@@ -27,11 +27,11 @@ life_cycle = ["on_startup", "on_shutdown", "on_cleanup", "cleanup_ctx"]
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
@cli.command()
|
|
30
|
-
@click.option("-p", "--path",help="Model's relative path,save models or create tables",default="models.py",)
|
|
30
|
+
@click.option("-p", "--path", help="Model's relative path,save models or create tables", default="models.py",)
|
|
31
31
|
@click.option("-c", "--create", help="For create model or table, model / table", default="model")
|
|
32
|
-
@click.option("-t", "--table",help="Table's name or Model's name, split by `,` or 'ALL'",required=True,)
|
|
32
|
+
@click.option("-t", "--table", help="Table's name or Model's name, split by `,` or 'ALL'", required=True,)
|
|
33
33
|
@click.option("-env", "--environment", help="Environment, local / test / prod", default="local")
|
|
34
|
-
@click.option("-db", "--database",help="Database name, pick the database in conf.{env}.yaml",default="mysql",)
|
|
34
|
+
@click.option("-db", "--database", help="Database name, pick the database in conf.{env}.yaml", default="mysql",)
|
|
35
35
|
def gen(path, create, table, environment, database) -> None:
|
|
36
36
|
"""Help to create models or tables."""
|
|
37
37
|
|
|
@@ -76,15 +76,15 @@ def gen(path, create, table, environment, database) -> None:
|
|
|
76
76
|
|
|
77
77
|
@cli.command()
|
|
78
78
|
@click.option("-env", "--environment", help="Environment, local / test / prod", default="local")
|
|
79
|
-
@click.option("-p", "--port", help="Server's port", default=
|
|
80
|
-
@click.option("-h", "--host", help="Server's host", default=
|
|
79
|
+
@click.option("-p", "--port", help="Server's port", default=None)
|
|
80
|
+
@click.option("-h", "--host", help="Server's host", default=None)
|
|
81
81
|
@click.option("-m", "--mode", help="development or production mode", default='development')
|
|
82
|
-
@click.option("-path", "--path",help="Unix file system path to serve on. Specifying a path will cause hostname and port arguments to be ignored.",)
|
|
82
|
+
@click.option("-path", "--path", help="Unix file system path to serve on. Specifying a path will cause hostname and port arguments to be ignored.",)
|
|
83
83
|
@click.option("-e", "--entry", help="Entry point model name. delfault name app", default="app")
|
|
84
84
|
def start(environment, host, port, mode, path, entry) -> None:
|
|
85
85
|
"""Start a services."""
|
|
86
86
|
try:
|
|
87
|
-
print_info("Current mode: "
|
|
87
|
+
print_info("Current mode: ", mode)
|
|
88
88
|
config = get_config(environment)
|
|
89
89
|
# print(environment, host, port, mode, path, entry)
|
|
90
90
|
# return
|
|
@@ -95,8 +95,10 @@ def start(environment, host, port, mode, path, entry) -> None:
|
|
|
95
95
|
aux_app = web.Application(
|
|
96
96
|
logger=None,
|
|
97
97
|
)
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
defaults = {"host": "0.0.0.0", "port": 9001, "path": None}
|
|
99
|
+
conf_server = config.get("server", {})
|
|
100
|
+
env_server = {"host": host, "port": port, "path": path}
|
|
101
|
+
server = chainMap(defaults, conf_server, env_server)
|
|
100
102
|
config["server"] = server
|
|
101
103
|
|
|
102
104
|
aux_port = int(server.port) + 1
|
|
@@ -114,7 +116,7 @@ def start(environment, host, port, mode, path, entry) -> None:
|
|
|
114
116
|
sys.exit(0)
|
|
115
117
|
except Exception as e:
|
|
116
118
|
# print_error(e)
|
|
117
|
-
print_error(traceback.format_exc())
|
|
119
|
+
# print_error(traceback.format_exc())
|
|
118
120
|
sys.exit(0)
|
|
119
121
|
|
|
120
122
|
|
|
@@ -2,7 +2,8 @@ from .field import Field, Function, Expression
|
|
|
2
2
|
from ..logging import print_warn
|
|
3
3
|
from functools import reduce
|
|
4
4
|
import operator
|
|
5
|
-
import copy
|
|
5
|
+
import copy
|
|
6
|
+
import datetime
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class ModelMetaclass(type):
|
|
@@ -31,8 +32,8 @@ class ModelMetaclass(type):
|
|
|
31
32
|
if primary_key:
|
|
32
33
|
print_warn(f"Duplicate primary key for {table_name}")
|
|
33
34
|
primary_key = k
|
|
34
|
-
else:
|
|
35
|
-
|
|
35
|
+
# else:
|
|
36
|
+
fields.append(k)
|
|
36
37
|
|
|
37
38
|
if not primary_key:
|
|
38
39
|
print_warn(f"{table_name} Missing primary key")
|
|
@@ -217,6 +218,8 @@ class Model(metaclass=ModelMetaclass):
|
|
|
217
218
|
f = getattr(self, k)
|
|
218
219
|
x = f.value
|
|
219
220
|
data[k] = x
|
|
221
|
+
elif args and isinstance(args, dict):
|
|
222
|
+
data = args
|
|
220
223
|
else:
|
|
221
224
|
for item in args:
|
|
222
225
|
md = item
|
|
@@ -230,10 +233,13 @@ class Model(metaclass=ModelMetaclass):
|
|
|
230
233
|
params = []
|
|
231
234
|
for k, v in data.items():
|
|
232
235
|
if isinstance(v, Field):
|
|
233
|
-
value = v.value
|
|
234
|
-
if value is
|
|
235
|
-
if
|
|
236
|
+
value = v.value
|
|
237
|
+
if value is None:
|
|
238
|
+
if v.created_generated == True or v.update_generated == True:
|
|
236
239
|
value = datetime.datetime.now()
|
|
240
|
+
else:
|
|
241
|
+
value = v.default
|
|
242
|
+
if value is not None:
|
|
237
243
|
keys.append("`%s`=?" % k)
|
|
238
244
|
params.append(value)
|
|
239
245
|
elif v is not None: # fix sql format %s
|
|
@@ -299,19 +305,19 @@ class Model(metaclass=ModelMetaclass):
|
|
|
299
305
|
self._reset()
|
|
300
306
|
return await self.__pool__.all(sql, args)
|
|
301
307
|
|
|
302
|
-
async def update(self, *args) -> bool:
|
|
308
|
+
async def update(self, *args, **kw) -> bool:
|
|
303
309
|
"""
|
|
304
310
|
Update data
|
|
305
311
|
"""
|
|
306
312
|
table = self.__table__
|
|
307
|
-
where = self.__where__
|
|
313
|
+
# where = self.__where__
|
|
314
|
+
where = self._literal("WHERE", self.__where__)
|
|
308
315
|
|
|
309
|
-
keys, params, md = self._get_key_args(args)
|
|
316
|
+
keys, params, md = self._get_key_args(args or kw)
|
|
310
317
|
|
|
311
|
-
sql = f"update `{table}` set {keys}"
|
|
318
|
+
sql = f"update `{table}` set {keys} {where}"
|
|
312
319
|
|
|
313
|
-
if where is not None:
|
|
314
|
-
sql += f' where {" and ".join(f for f in where)}'
|
|
320
|
+
if where is not None and where != "":
|
|
315
321
|
params += self.__params__
|
|
316
322
|
else:
|
|
317
323
|
pk, pkv = self._get_primary()
|
|
@@ -327,7 +333,7 @@ class Model(metaclass=ModelMetaclass):
|
|
|
327
333
|
params.append(pkv)
|
|
328
334
|
else:
|
|
329
335
|
raise "Need where or primary key"
|
|
330
|
-
|
|
336
|
+
self._reset()
|
|
331
337
|
return await self.__pool__.update(sql, params)
|
|
332
338
|
|
|
333
339
|
async def delete(self) -> bool:
|
|
@@ -335,24 +341,23 @@ class Model(metaclass=ModelMetaclass):
|
|
|
335
341
|
Delete data
|
|
336
342
|
"""
|
|
337
343
|
table = self.__table__
|
|
338
|
-
where = self.__where__
|
|
344
|
+
where = self._literal("WHERE", self.__where__)
|
|
339
345
|
args = self.__params__
|
|
340
|
-
sql = f"delete from `{table}`"
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
raise "need where or primary"
|
|
346
|
+
sql = f"delete from `{table}` {where}"
|
|
347
|
+
|
|
348
|
+
if where is None or where == "":
|
|
349
|
+
pk, pkv = self._get_primary()
|
|
350
|
+
if pkv is not None:
|
|
351
|
+
sql += f" where `{pk}`=?"
|
|
352
|
+
args = [pkv]
|
|
353
|
+
else:
|
|
354
|
+
raise "need where or primary key"
|
|
350
355
|
self._reset()
|
|
351
356
|
return await self.__pool__.delete(sql, args)
|
|
352
357
|
|
|
353
|
-
async def insert(self, *args):
|
|
358
|
+
async def insert(self, *args, **kw):
|
|
354
359
|
table = self.__table__
|
|
355
|
-
keys, params, md = self._get_key_args(args)
|
|
360
|
+
keys, params, md = self._get_key_args(args or kw)
|
|
356
361
|
sql = f"insert into `{table}` set {keys}"
|
|
357
362
|
self._reset()
|
|
358
363
|
return await self.__pool__.create(sql, params)
|
|
@@ -34,7 +34,7 @@ class WatchTask:
|
|
|
34
34
|
async def start(self, app: Application) -> None:
|
|
35
35
|
self._app = app
|
|
36
36
|
self.stopper = asyncio.Event()
|
|
37
|
-
ignore_dirs = self._config["server"]
|
|
37
|
+
ignore_dirs = self._config["server"].get("ignore_dirs", [])
|
|
38
38
|
self._awatch = awatch(
|
|
39
39
|
self._path,
|
|
40
40
|
stop_event=self.stopper,
|
|
@@ -12,8 +12,6 @@ import importlib
|
|
|
12
12
|
import inspect
|
|
13
13
|
import json
|
|
14
14
|
from errno import EADDRINUSE
|
|
15
|
-
import pkgutil
|
|
16
|
-
import sys
|
|
17
15
|
from urllib import parse
|
|
18
16
|
from aiohttp import web
|
|
19
17
|
from aiohttp.web import Response
|
|
@@ -37,6 +35,7 @@ from decimal import Decimal
|
|
|
37
35
|
from datetime import datetime, date
|
|
38
36
|
from ..utils.common import chainMap, Object
|
|
39
37
|
from ..orm import create_engine, parse_coon
|
|
38
|
+
import uuid
|
|
40
39
|
|
|
41
40
|
# from ..orm.mysql import Mysql
|
|
42
41
|
from typing import Optional, Iterable
|
|
@@ -59,7 +58,7 @@ __ALL__ = (
|
|
|
59
58
|
)
|
|
60
59
|
|
|
61
60
|
|
|
62
|
-
class
|
|
61
|
+
class RequestHandler(object):
|
|
63
62
|
def __init__(self, cls, fn):
|
|
64
63
|
self.cls = cls
|
|
65
64
|
self.fn = fn
|
|
@@ -69,12 +68,12 @@ class _Handler(object):
|
|
|
69
68
|
# 获取函数参数的名称和默认值
|
|
70
69
|
props = inspect.getfullargspec(self.fn)
|
|
71
70
|
if len(props.args) == 2 and content_type == "multipart/form-data":
|
|
72
|
-
await
|
|
71
|
+
await set_session_route(request)
|
|
73
72
|
multipart = await request.multipart()
|
|
74
73
|
field = await multipart.next()
|
|
75
74
|
result = await self.fn(request, field)
|
|
76
75
|
elif len(props.args) == 1:
|
|
77
|
-
await
|
|
76
|
+
await set_session_route(request)
|
|
78
77
|
if content_type == "multipart/form-data":
|
|
79
78
|
data = await request.post()
|
|
80
79
|
elif content_type == "application/json":
|
|
@@ -109,7 +108,7 @@ class _Handler(object):
|
|
|
109
108
|
return render_json(result)
|
|
110
109
|
|
|
111
110
|
|
|
112
|
-
async def
|
|
111
|
+
async def set_session_route(request):
|
|
113
112
|
params = dict()
|
|
114
113
|
# match
|
|
115
114
|
rt = request.match_info
|
|
@@ -121,29 +120,6 @@ async def _set_session_route(request):
|
|
|
121
120
|
request.session = session
|
|
122
121
|
|
|
123
122
|
|
|
124
|
-
def _get_modules(fd):
|
|
125
|
-
modules = set()
|
|
126
|
-
temp = os.path.join(os.path.abspath("."), fd)
|
|
127
|
-
if not os.path.exists(temp):
|
|
128
|
-
print_info("Routers not detected")
|
|
129
|
-
return modules
|
|
130
|
-
s = find_packages(temp)
|
|
131
|
-
for pkg in s:
|
|
132
|
-
# modules.add(pkg)
|
|
133
|
-
pkg_path = temp + "/" + pkg.replace(".", "/")
|
|
134
|
-
if sys.version_info.major == 2 or (
|
|
135
|
-
sys.version_info.major == 3 and sys.version_info.minor < 6
|
|
136
|
-
):
|
|
137
|
-
for _, name, ispkg in pkgutil.iter_modules([pkg_path]):
|
|
138
|
-
if not ispkg:
|
|
139
|
-
modules.add(f".{pkg}.{name}")
|
|
140
|
-
else:
|
|
141
|
-
for info in pkgutil.iter_modules([pkg_path]):
|
|
142
|
-
if not info.ispkg:
|
|
143
|
-
modules.add(f".{pkg}.{info.name}")
|
|
144
|
-
return modules
|
|
145
|
-
|
|
146
|
-
|
|
147
123
|
async def check_port_open(port: int, delay: float = 1) -> None:
|
|
148
124
|
loop = asyncio.get_running_loop()
|
|
149
125
|
# the "s = socket.socket; s.bind" approach sometimes says a port is in use when it's not
|
|
@@ -165,21 +141,27 @@ async def check_port_open(port: int, delay: float = 1) -> None:
|
|
|
165
141
|
raise Exception("The port {} is already is use".format(port))
|
|
166
142
|
|
|
167
143
|
|
|
168
|
-
def
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if not os.path.exists(mid_dir):
|
|
173
|
-
print_info("Middlewares not detected")
|
|
144
|
+
def auto_reg_module(module_dir: str):
|
|
145
|
+
module_path = os.path.join(os.path.abspath("."), module_dir)
|
|
146
|
+
if not os.path.exists(module_path):
|
|
147
|
+
print_info(f"{module_dir} not detected")
|
|
174
148
|
return
|
|
175
|
-
for
|
|
176
|
-
if
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
149
|
+
for filename in os.listdir(module_dir):
|
|
150
|
+
if filename.startswith("__") or filename.startswith("."):
|
|
151
|
+
continue
|
|
152
|
+
full_path = os.path.join(os.path.abspath("."), module_dir, filename)
|
|
153
|
+
if os.path.isdir(full_path):
|
|
154
|
+
auto_reg_module(module_dir + os.sep + filename)
|
|
155
|
+
elif filename.endswith(".py"):
|
|
156
|
+
module_name = (
|
|
157
|
+
module_dir.replace(os.sep, ".")
|
|
158
|
+
+ "."
|
|
159
|
+
+ filename[:-3].replace(os.sep, ".")
|
|
160
|
+
)
|
|
161
|
+
importlib.import_module(module_name)
|
|
180
162
|
|
|
181
163
|
|
|
182
|
-
def
|
|
164
|
+
def parse_int(num):
|
|
183
165
|
return eval(num) if isinstance(num, str) else num
|
|
184
166
|
|
|
185
167
|
|
|
@@ -234,7 +216,7 @@ class Application(object):
|
|
|
234
216
|
self.config = config
|
|
235
217
|
|
|
236
218
|
# middlewares
|
|
237
|
-
|
|
219
|
+
auto_reg_module("middlewares")
|
|
238
220
|
|
|
239
221
|
conf_server = config.get("server")
|
|
240
222
|
client_max_size = 1024**2 * 2
|
|
@@ -244,7 +226,7 @@ class Application(object):
|
|
|
244
226
|
logger=None,
|
|
245
227
|
loop=loop,
|
|
246
228
|
middlewares=self._middleware,
|
|
247
|
-
client_max_size=
|
|
229
|
+
client_max_size=parse_int(client_max_size),
|
|
248
230
|
)
|
|
249
231
|
# database
|
|
250
232
|
self.app.db = Object()
|
|
@@ -257,10 +239,11 @@ class Application(object):
|
|
|
257
239
|
self.app.on_startup.append(self._init_session)
|
|
258
240
|
# self._init_session()
|
|
259
241
|
# router:
|
|
260
|
-
|
|
242
|
+
auto_reg_module("controllers")
|
|
243
|
+
self.app.add_routes(self._route_table)
|
|
261
244
|
|
|
262
245
|
# load life
|
|
263
|
-
entry = conf_server.get(
|
|
246
|
+
entry = conf_server.get("entry", entry_model)
|
|
264
247
|
self._load_life_cycle(entry)
|
|
265
248
|
|
|
266
249
|
# static
|
|
@@ -333,7 +316,7 @@ class Application(object):
|
|
|
333
316
|
storage = redis_storage.RedisStorage(
|
|
334
317
|
redis,
|
|
335
318
|
cookie_name=cookie_name,
|
|
336
|
-
max_age=
|
|
319
|
+
max_age=parse_int(max_age),
|
|
337
320
|
httponly=httponly,
|
|
338
321
|
secure=secure,
|
|
339
322
|
)
|
|
@@ -348,7 +331,7 @@ class Application(object):
|
|
|
348
331
|
storage = memcached_storage.MemcachedStorage(
|
|
349
332
|
mc,
|
|
350
333
|
cookie_name=cookie_name,
|
|
351
|
-
max_age=
|
|
334
|
+
max_age=parse_int(max_age),
|
|
352
335
|
httponly=httponly,
|
|
353
336
|
secure=secure,
|
|
354
337
|
)
|
|
@@ -365,23 +348,12 @@ class Application(object):
|
|
|
365
348
|
storage = cookie_storage.EncryptedCookieStorage(
|
|
366
349
|
secret_key,
|
|
367
350
|
cookie_name=cookie_name,
|
|
368
|
-
max_age=
|
|
351
|
+
max_age=parse_int(max_age),
|
|
369
352
|
httponly=httponly,
|
|
370
353
|
)
|
|
371
354
|
setup(apps, storage)
|
|
372
355
|
print_info("start local cookie.")
|
|
373
356
|
|
|
374
|
-
def _reg_router(self):
|
|
375
|
-
fd = "controllers"
|
|
376
|
-
modules = _get_modules(fd)
|
|
377
|
-
for module in modules:
|
|
378
|
-
# print(module)
|
|
379
|
-
importlib.import_module(module, fd)
|
|
380
|
-
|
|
381
|
-
self.app.add_routes(self._route_table)
|
|
382
|
-
# for route in self._routes:
|
|
383
|
-
# self.app.router.add_route(**route)
|
|
384
|
-
|
|
385
357
|
def run(self, **kw):
|
|
386
358
|
"""
|
|
387
359
|
run app
|
|
@@ -417,7 +389,7 @@ class Application(object):
|
|
|
417
389
|
|
|
418
390
|
def add_router(self, path, method, name):
|
|
419
391
|
def inner(handler):
|
|
420
|
-
handler =
|
|
392
|
+
handler = RequestHandler(self, handler)
|
|
421
393
|
self.app.router.add_route(method, path, handler, name=name)
|
|
422
394
|
return handler
|
|
423
395
|
|
|
@@ -478,6 +450,8 @@ class JsonEncoder(json.JSONEncoder):
|
|
|
478
450
|
return list(obj)
|
|
479
451
|
elif isinstance(obj, Model):
|
|
480
452
|
return obj.__dict__
|
|
453
|
+
elif isinstance(obj, uuid.UUID):
|
|
454
|
+
return str(obj)
|
|
481
455
|
else:
|
|
482
456
|
return super(JsonEncoder, self).default(obj)
|
|
483
457
|
|
|
@@ -556,8 +530,8 @@ def render_json(data, **kw) -> Response:
|
|
|
556
530
|
res["data"] = data
|
|
557
531
|
status = kw.get("status", 200)
|
|
558
532
|
if status == 200:
|
|
559
|
-
res["message"] = "OK"
|
|
560
|
-
res["code"] = 200
|
|
533
|
+
res["message"] = kw.get("message", "OK")
|
|
534
|
+
res["code"] = kw.get("code", 200)
|
|
561
535
|
|
|
562
536
|
res["timestamp"] = int(datetime.now().timestamp() * 1000)
|
|
563
537
|
text = json.dumps(res, ensure_ascii=False, cls=JsonEncoder)
|
|
@@ -11,6 +11,6 @@ def get_config(env):
|
|
|
11
11
|
if not os.path.exists(conf_path):
|
|
12
12
|
print_error(f"Configuration file does not exist: {conf_path}")
|
|
13
13
|
return {}
|
|
14
|
-
with open(conf_path) as f:
|
|
14
|
+
with open(conf_path, "r", encoding="utf-8") as f:
|
|
15
15
|
config = yaml.safe_load(f)
|
|
16
16
|
return config or {}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.15"
|
|
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
|