cloudoll 3.0.5__tar.gz → 3.0.6__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-3.0.5 → cloudoll-3.0.6}/PKG-INFO +1 -1
- cloudoll-3.0.6/cloudoll/__init__.py +1 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/__init__.py +10 -9
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/base.py +13 -4
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/field.py +4 -1
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/model.py +1 -1
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/mysql.py +2 -4
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/postgres.py +5 -6
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/utils/snowflake.py +18 -19
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/core.py +2 -3
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll.egg-info/PKG-INFO +1 -1
- {cloudoll-3.0.5 → cloudoll-3.0.6}/pyproject.toml +1 -1
- cloudoll-3.0.5/cloudoll/__init__.py +0 -1
- {cloudoll-3.0.5 → cloudoll-3.0.6}/LICENSE +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/README.md +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/__main__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/cli.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/clitool/__init__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/clitool/cli_main.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/clitool/m2d.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/clitool/process.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/clitool/spinner.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/clitool/watch.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/logging/__init__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/mail/__init__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/mail/smtp.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/err.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/parse.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/orm/test_sql.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/template/__init__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/utils/__init__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/utils/common.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/__init__.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/exception.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/html.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/jwt.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/requests.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll/web/settings.py +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll.egg-info/SOURCES.txt +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll.egg-info/dependency_links.txt +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll.egg-info/entry_points.txt +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll.egg-info/requires.txt +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/cloudoll.egg-info/top_level.txt +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/setup.cfg +0 -0
- {cloudoll-3.0.5 → cloudoll-3.0.6}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudoll
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.6
|
|
4
4
|
Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
|
|
5
5
|
Home-page: https://github.com/smallerqiu/cloudoll-py
|
|
6
6
|
Author: Qiu
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.0.6"
|
|
@@ -9,6 +9,7 @@ from aiomysql import Pool as MYPool
|
|
|
9
9
|
|
|
10
10
|
import aiopg as pg
|
|
11
11
|
from aiopg.pool import Pool as PGPool
|
|
12
|
+
from typing import Optional
|
|
12
13
|
|
|
13
14
|
__all__ = ["create_engine"]
|
|
14
15
|
|
|
@@ -46,7 +47,7 @@ async def create_engine(**kw):
|
|
|
46
47
|
|
|
47
48
|
class Postgres(MeteBase):
|
|
48
49
|
def __init__(self, pool=None):
|
|
49
|
-
self.pool: PGPool = pool
|
|
50
|
+
# self.pool: Optional[PGPool] = pool
|
|
50
51
|
self.driver = "postgres"
|
|
51
52
|
|
|
52
53
|
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
|
@@ -61,7 +62,7 @@ class Postgres(MeteBase):
|
|
|
61
62
|
|
|
62
63
|
async with self.pool.acquire() as conn:
|
|
63
64
|
if conn.echo:
|
|
64
|
-
info("sql", sql, params)
|
|
65
|
+
info("sql: %s ,%s", sql, params)
|
|
65
66
|
|
|
66
67
|
async with conn.cursor() as cursor:
|
|
67
68
|
# current_cursor = getattr(cursor, 'lastrowid', None)
|
|
@@ -75,18 +76,18 @@ class Postgres(MeteBase):
|
|
|
75
76
|
await cursor.execute(sql, params)
|
|
76
77
|
|
|
77
78
|
result = None
|
|
78
|
-
|
|
79
|
-
if query_type == QueryTypes.ALL:
|
|
79
|
+
|
|
80
|
+
if query_type == QueryTypes.ALL and cursor.description is not None:
|
|
80
81
|
columns = [desc[0] for desc in cursor.description]
|
|
81
82
|
rows = await cursor.fetchall()
|
|
82
83
|
result = [dict(zip(columns, row)) for row in rows]
|
|
83
84
|
return result
|
|
84
|
-
elif query_type == QueryTypes.ONE:
|
|
85
|
+
elif query_type == QueryTypes.ONE and cursor.description is not None:
|
|
85
86
|
columns = [desc[0] for desc in cursor.description]
|
|
86
87
|
row = await cursor.fetchone()
|
|
87
88
|
result = dict(zip(columns, row)) if row else {}
|
|
88
89
|
return result
|
|
89
|
-
elif query_type == QueryTypes.MANY:
|
|
90
|
+
elif query_type == QueryTypes.MANY and cursor.description is not None:
|
|
90
91
|
columns = [desc[0] for desc in cursor.description]
|
|
91
92
|
rows = await cursor.fetchmany(size)
|
|
92
93
|
result = [dict(zip(columns, row)) for row in rows]
|
|
@@ -160,14 +161,14 @@ class AttrDictCursor(aiomysql.DictCursor):
|
|
|
160
161
|
|
|
161
162
|
class Mysql(MeteBase):
|
|
162
163
|
def __init__(self, pool=None):
|
|
163
|
-
self.pool: MYPool = pool
|
|
164
|
+
# self.pool: Optional[MYPool] = pool
|
|
164
165
|
self.driver = "mysql"
|
|
165
166
|
|
|
166
167
|
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
|
167
168
|
self.__init__(*args, **kwds)
|
|
168
169
|
return self
|
|
169
170
|
|
|
170
|
-
async def query(self, sql, params=None, query_type: QueryTypes =
|
|
171
|
+
async def query(self, sql, params=None, query_type: QueryTypes = QueryTypes.ONE, size: int = 10):
|
|
171
172
|
sql = sql.replace("?", "%s")
|
|
172
173
|
if not self.pool:
|
|
173
174
|
raise ValueError("must be create_engine first.")
|
|
@@ -175,7 +176,7 @@ class Mysql(MeteBase):
|
|
|
175
176
|
return None
|
|
176
177
|
async with self.pool.acquire() as conn:
|
|
177
178
|
if conn.echo:
|
|
178
|
-
info("sql", sql, params)
|
|
179
|
+
info("sql: %s , %s", sql, params)
|
|
179
180
|
|
|
180
181
|
async with conn.cursor() as cursor:
|
|
181
182
|
# current_cursor = getattr(cursor, 'lastrowid', None)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
1
2
|
from enum import Enum
|
|
2
|
-
from typing import Tuple
|
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
4
|
+
from aiomysql.pool import Pool as MyPool
|
|
5
|
+
from aiopg import Pool as PGPool
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
class QueryTypes(Enum):
|
|
@@ -16,6 +19,10 @@ class QueryTypes(Enum):
|
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
class MeteBase:
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self.pool: Optional[MyPool | PGPool] = None
|
|
24
|
+
# self.cursor: Optional[Cursor] = None
|
|
25
|
+
# self.conn: Optional[Connection] = None
|
|
19
26
|
|
|
20
27
|
async def __aexit__(self):
|
|
21
28
|
await self.close()
|
|
@@ -46,9 +53,10 @@ class MeteBase:
|
|
|
46
53
|
# if cursor:
|
|
47
54
|
# await cursor.close()
|
|
48
55
|
# self.pool.release(conn)
|
|
56
|
+
@abstractmethod
|
|
49
57
|
async def query(
|
|
50
|
-
self, sql, params=None, query_type: QueryTypes =
|
|
51
|
-
): ...
|
|
58
|
+
self, sql, params=None, query_type: QueryTypes = QueryTypes.ONE, size: int = 10
|
|
59
|
+
) -> Union[None, int, Tuple[Any, Any], Dict, List[Dict]]: ...
|
|
52
60
|
|
|
53
61
|
async def all(self, sql, params):
|
|
54
62
|
return await self.query(sql, params, QueryTypes.ALL)
|
|
@@ -61,6 +69,7 @@ class MeteBase:
|
|
|
61
69
|
|
|
62
70
|
async def count(self, sql, params):
|
|
63
71
|
return await self.query(sql, params, QueryTypes.COUNT)
|
|
72
|
+
|
|
64
73
|
async def group_count(self, sql, params):
|
|
65
74
|
return await self.query(sql, params, QueryTypes.GROUP_COUNT)
|
|
66
75
|
|
|
@@ -73,7 +82,7 @@ class MeteBase:
|
|
|
73
82
|
async def delete(self, sql, params):
|
|
74
83
|
return await self.query(sql, params, QueryTypes.DELETE)
|
|
75
84
|
|
|
76
|
-
async def create(self, sql, params)
|
|
85
|
+
async def create(self, sql, params):
|
|
77
86
|
return await self.query(sql, params, QueryTypes.CREATE)
|
|
78
87
|
|
|
79
88
|
async def create_batch(self, sql, params):
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class objdict(dict):
|
|
2
5
|
def __getattr__(self, attr):
|
|
3
6
|
try:
|
|
@@ -502,7 +505,7 @@ class Field(FieldBase):
|
|
|
502
505
|
**kwargs,
|
|
503
506
|
):
|
|
504
507
|
super().__init__()
|
|
505
|
-
self.full_name = None
|
|
508
|
+
self.full_name: Optional[str] = None
|
|
506
509
|
self._value = None
|
|
507
510
|
self.name = name
|
|
508
511
|
self.column_type = column_type
|
|
@@ -150,7 +150,7 @@ class Model(metaclass=ModelMetaclass):
|
|
|
150
150
|
@classmethod
|
|
151
151
|
def use(cls, pool=None):
|
|
152
152
|
cls.__pool__ = pool
|
|
153
|
-
cls.__ispg =
|
|
153
|
+
cls.__ispg = pool.driver == "postgres" if pool else False
|
|
154
154
|
return cls()
|
|
155
155
|
|
|
156
156
|
def select(cls, *args):
|
|
@@ -24,9 +24,7 @@ result = await pool.query("sql")
|
|
|
24
24
|
"""
|
|
25
25
|
__author__ = "Qiu / smallerqiu@gmail.com"
|
|
26
26
|
|
|
27
|
-
from typing import Any
|
|
28
27
|
from aiomysql import create_pool, DictCursor
|
|
29
|
-
from aiomysql.pool import Pool
|
|
30
28
|
|
|
31
29
|
# from aiomysql.cursors import Cursor
|
|
32
30
|
# from aiomysql.connection import Connection
|
|
@@ -51,8 +49,8 @@ class AttrDictCursor(DictCursor):
|
|
|
51
49
|
|
|
52
50
|
|
|
53
51
|
class Mysql(MeteBase):
|
|
54
|
-
def __init__(self):
|
|
55
|
-
self.pool: Pool = None
|
|
52
|
+
# def __init__(self):
|
|
53
|
+
# self.pool: Optional[Pool] = None
|
|
56
54
|
# self.cursor: Cursor = None
|
|
57
55
|
# self.conn: Connection = None
|
|
58
56
|
# self.__MODELS__ = []
|
|
@@ -25,17 +25,16 @@ result = await pool.query("sql")
|
|
|
25
25
|
"""
|
|
26
26
|
__author__ = "Qiu / smallerqiu@gmail.com"
|
|
27
27
|
|
|
28
|
-
from aiopg import create_pool
|
|
28
|
+
from aiopg import create_pool
|
|
29
29
|
from cloudoll.logging import error
|
|
30
30
|
from cloudoll.orm.base import MeteBase
|
|
31
|
-
from typing import Any, Optional
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
class Postgres(MeteBase):
|
|
35
|
-
def __init__(self):
|
|
36
|
-
|
|
37
|
-
self.cursor: Optional[Cursor] = None
|
|
38
|
-
self.conn: Optional[Connection] = None
|
|
34
|
+
# def __init__(self):
|
|
35
|
+
# self.pool: Optional[Pool] = None
|
|
36
|
+
# self.cursor: Optional[Cursor] = None
|
|
37
|
+
# self.conn: Optional[Connection] = None
|
|
39
38
|
# self.__MODELS__ = []
|
|
40
39
|
|
|
41
40
|
# def __call__(cls, *args: Any, **kwds: Any) -> Any:
|
|
@@ -1,34 +1,30 @@
|
|
|
1
|
-
|
|
2
1
|
import time
|
|
3
2
|
import threading
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
"""
|
|
7
|
-
雪花算法(全局唯一id)
|
|
8
|
-
|
|
9
|
-
# 最早是Twitter公司在其内部用于分布式环境下生成唯一ID
|
|
10
|
-
|
|
11
6
|
# Twitter's Snowflake algorithm implementation which is used to generate distributed IDs.
|
|
12
|
-
|
|
13
7
|
# https://github.com/twitter-archive/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala
|
|
14
8
|
"""
|
|
15
9
|
|
|
16
10
|
|
|
17
11
|
class IdWorker:
|
|
18
12
|
def __init__(self, worker_id, datacenter_id, sequence=0):
|
|
19
|
-
|
|
13
|
+
# 位移值
|
|
20
14
|
self.worker_id_bits = 5
|
|
21
15
|
self.datacenter_id_bits = 5
|
|
22
16
|
self.sequence_bits = 12
|
|
23
|
-
|
|
17
|
+
|
|
24
18
|
self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
|
|
25
19
|
self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
|
|
26
20
|
|
|
27
21
|
# 参数校验
|
|
28
22
|
if worker_id > self.max_worker_id or worker_id < 0:
|
|
29
|
-
raise ValueError(f
|
|
23
|
+
raise ValueError(f"worker_id must be between 0 and {self.max_worker_id}")
|
|
30
24
|
if datacenter_id > self.max_datacenter_id or datacenter_id < 0:
|
|
31
|
-
raise ValueError(
|
|
25
|
+
raise ValueError(
|
|
26
|
+
f"datacenter_id must be between 0 and {self.max_datacenter_id}"
|
|
27
|
+
)
|
|
32
28
|
|
|
33
29
|
self.worker_id = worker_id
|
|
34
30
|
self.datacenter_id = datacenter_id
|
|
@@ -38,12 +34,11 @@ class IdWorker:
|
|
|
38
34
|
# Twitter Epoch (2010-11-04 01:42:54 UTC)
|
|
39
35
|
self.twepoch = 1288834974657
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
37
|
self.worker_id_shift = self.sequence_bits
|
|
45
38
|
self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
|
|
46
|
-
self.timestamp_left_shift =
|
|
39
|
+
self.timestamp_left_shift = (
|
|
40
|
+
self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
|
|
41
|
+
)
|
|
47
42
|
self.sequence_mask = -1 ^ (-1 << self.sequence_bits)
|
|
48
43
|
|
|
49
44
|
self.last_timestamp = -1
|
|
@@ -62,7 +57,9 @@ class IdWorker:
|
|
|
62
57
|
timestamp = self._time_gen()
|
|
63
58
|
|
|
64
59
|
if timestamp < self.last_timestamp:
|
|
65
|
-
raise Exception(
|
|
60
|
+
raise Exception(
|
|
61
|
+
f"Clock moved backwards. Refusing to generate id for {self.last_timestamp - timestamp} milliseconds"
|
|
62
|
+
)
|
|
66
63
|
|
|
67
64
|
if self.last_timestamp == timestamp:
|
|
68
65
|
self.sequence = (self.sequence + 1) & self.sequence_mask
|
|
@@ -73,10 +70,12 @@ class IdWorker:
|
|
|
73
70
|
|
|
74
71
|
self.last_timestamp = timestamp
|
|
75
72
|
|
|
76
|
-
id = (
|
|
77
|
-
(self.
|
|
78
|
-
(self.
|
|
79
|
-
self.
|
|
73
|
+
id = (
|
|
74
|
+
((timestamp - self.twepoch) << self.timestamp_left_shift)
|
|
75
|
+
| (self.datacenter_id << self.datacenter_id_shift)
|
|
76
|
+
| (self.worker_id << self.worker_id_shift)
|
|
77
|
+
| self.sequence
|
|
78
|
+
)
|
|
80
79
|
|
|
81
80
|
return id
|
|
82
81
|
|
|
@@ -6,7 +6,6 @@ __author__ = "Qiu / smallerqiu@gmail.com"
|
|
|
6
6
|
import argparse
|
|
7
7
|
import asyncio
|
|
8
8
|
import hashlib
|
|
9
|
-
import os
|
|
10
9
|
import base64
|
|
11
10
|
import importlib.util
|
|
12
11
|
import inspect
|
|
@@ -17,7 +16,7 @@ import time
|
|
|
17
16
|
from urllib import parse
|
|
18
17
|
from aiohttp import web, hdrs
|
|
19
18
|
from aiohttp.web import Response
|
|
20
|
-
from aiohttp.web_ws import WebSocketResponse,
|
|
19
|
+
from aiohttp.web_ws import WebSocketResponse,WSMsgType
|
|
21
20
|
from aiohttp.web_response import StreamResponse
|
|
22
21
|
from aiohttp.web_request import Request
|
|
23
22
|
from aiohttp.typedefs import LooseHeaders
|
|
@@ -157,7 +156,7 @@ class Application(object):
|
|
|
157
156
|
def __init__(self):
|
|
158
157
|
self._loop = None
|
|
159
158
|
self.env = None
|
|
160
|
-
self.app: web.Application = None
|
|
159
|
+
self.app: Optional[web.Application] = None
|
|
161
160
|
self._route_table = web.RouteTableDef()
|
|
162
161
|
self._middleware = []
|
|
163
162
|
self.config = {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudoll
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.6
|
|
4
4
|
Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
|
|
5
5
|
Home-page: https://github.com/smallerqiu/cloudoll-py
|
|
6
6
|
Author: Qiu
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cloudoll"
|
|
7
|
-
version = "3.0.
|
|
7
|
+
version = "3.0.6"
|
|
8
8
|
description = "Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use."
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Qiu", email = "smallerqiu@gmail.com"},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "3.0.5"
|
|
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
|