python3-commons 0.10.0__tar.gz → 0.10.1__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.
Potentially problematic release.
This version of python3-commons might be problematic. Click here for more details.
- {python3_commons-0.10.0 → python3_commons-0.10.1}/PKG-INFO +1 -1
- {python3_commons-0.10.0 → python3_commons-0.10.1}/pyproject.toml +3 -3
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/auth.py +1 -1
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/cache.py +10 -13
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/db/__init__.py +1 -2
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/helpers.py +5 -4
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/object_storage.py +1 -1
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/permissions.py +2 -4
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/json.py +3 -3
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/msgpack.py +5 -9
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/msgspec.py +5 -9
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/PKG-INFO +1 -1
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.coveragerc +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.github/workflows/checks.yml +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.github/workflows/release-on-tag-push.yml +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.gitignore +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.pre-commit-config.yaml +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/.python-version +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/AUTHORS.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/CHANGELOG.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/LICENSE +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/README.md +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/README.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/Makefile +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/_static/.gitignore +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/authors.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/changelog.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/conf.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/index.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/docs/license.rst +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/setup.cfg +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/api_client.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/audit.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/conf.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/db/helpers.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/db/models/__init__.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/db/models/auth.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/db/models/common.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/db/models/rbac.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/log/__init__.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/log/filters.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/log/formatters.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/common.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/SOURCES.txt +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/requires.txt +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/__init__.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/conftest.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/test_audit.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/test_cache.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/test_helpers.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/test_msgpack.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/tests/test_msgspec.py +0 -0
- {python3_commons-0.10.0 → python3_commons-0.10.1}/uv.lock +0 -0
|
@@ -114,9 +114,9 @@ select = [
|
|
|
114
114
|
"PT",
|
|
115
115
|
"PTH",
|
|
116
116
|
"Q",
|
|
117
|
-
|
|
117
|
+
"RET",
|
|
118
118
|
"RSE",
|
|
119
|
-
|
|
119
|
+
"RUF",
|
|
120
120
|
"S",
|
|
121
121
|
"SIM",
|
|
122
122
|
"SLF",
|
|
@@ -132,7 +132,7 @@ ignore = [
|
|
|
132
132
|
]
|
|
133
133
|
|
|
134
134
|
[tool.ruff.lint.per-file-ignores]
|
|
135
|
-
"tests/*.py" = ["S101"]
|
|
135
|
+
"tests/*.py" = ["DTZ", "S101"]
|
|
136
136
|
|
|
137
137
|
[tool.ruff.lint.flake8-quotes]
|
|
138
138
|
docstring-quotes = "double"
|
|
@@ -81,7 +81,7 @@ def get_token_verifier[T](
|
|
|
81
81
|
except jwt.ExpiredSignatureError as e:
|
|
82
82
|
raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail='Token has expired') from e
|
|
83
83
|
except JWTError as e:
|
|
84
|
-
raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail=f'Token is invalid: {
|
|
84
|
+
raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail=f'Token is invalid: {e!s}') from e
|
|
85
85
|
|
|
86
86
|
return token_data
|
|
87
87
|
|
|
@@ -37,8 +37,7 @@ class AsyncValkeyClient(metaclass=SingletonMeta):
|
|
|
37
37
|
def _get_keepalive_options():
|
|
38
38
|
if platform in {'linux', 'darwin'}:
|
|
39
39
|
return {socket.TCP_KEEPIDLE: 10, socket.TCP_KEEPINTVL: 5, socket.TCP_KEEPCNT: 5}
|
|
40
|
-
|
|
41
|
-
return {}
|
|
40
|
+
return {}
|
|
42
41
|
|
|
43
42
|
def _initialize_sentinel(self, dsn: RedisDsn):
|
|
44
43
|
sentinel = Sentinel(
|
|
@@ -89,7 +88,7 @@ async def delete(*names: str | bytes | memoryview):
|
|
|
89
88
|
await get_valkey_client().delete(*names)
|
|
90
89
|
|
|
91
90
|
|
|
92
|
-
async def store_bytes(name: str, data: bytes, ttl: int = None, *, if_not_set: bool = False):
|
|
91
|
+
async def store_bytes(name: str, data: bytes, ttl: int | None = None, *, if_not_set: bool = False):
|
|
93
92
|
r = get_valkey_client()
|
|
94
93
|
|
|
95
94
|
return await r.set(name, data, ex=ttl, nx=if_not_set)
|
|
@@ -101,18 +100,18 @@ async def get_bytes(name: str) -> bytes | None:
|
|
|
101
100
|
return await r.get(name)
|
|
102
101
|
|
|
103
102
|
|
|
104
|
-
async def store(name: str, obj: Any, ttl: int = None, *, if_not_set: bool = False):
|
|
103
|
+
async def store(name: str, obj: Any, ttl: int | None = None, *, if_not_set: bool = False):
|
|
105
104
|
return await store_bytes(name, serialize_msgpack_native(obj), ttl, if_not_set=if_not_set)
|
|
106
105
|
|
|
107
106
|
|
|
108
|
-
async def get(name: str, default=None, data_type: Any = None) -> Any:
|
|
107
|
+
async def get(name: str, default: Any | None = None, data_type: Any = None) -> Any | None:
|
|
109
108
|
if data := await get_bytes(name):
|
|
110
109
|
return deserialize_msgpack_native(data, data_type)
|
|
111
110
|
|
|
112
111
|
return default
|
|
113
112
|
|
|
114
113
|
|
|
115
|
-
async def store_string(name: str, data: str, ttl: int = None):
|
|
114
|
+
async def store_string(name: str, data: str, ttl: int | None = None):
|
|
116
115
|
await store_bytes(name, data.encode(), ttl)
|
|
117
116
|
|
|
118
117
|
|
|
@@ -123,7 +122,7 @@ async def get_string(name: str) -> str | None:
|
|
|
123
122
|
return None
|
|
124
123
|
|
|
125
124
|
|
|
126
|
-
async def store_sequence(name: str, data: Sequence, ttl: int = None):
|
|
125
|
+
async def store_sequence(name: str, data: Sequence, ttl: int | None = None):
|
|
127
126
|
if data:
|
|
128
127
|
try:
|
|
129
128
|
r = get_valkey_client()
|
|
@@ -142,7 +141,7 @@ async def get_sequence(name: str, _type: type = list) -> Sequence:
|
|
|
142
141
|
return _type(map(deserialize_msgpack_native, lrange))
|
|
143
142
|
|
|
144
143
|
|
|
145
|
-
async def store_dict(name: str, data: Mapping, ttl: int = None):
|
|
144
|
+
async def store_dict(name: str, data: Mapping, ttl: int | None = None):
|
|
146
145
|
if data:
|
|
147
146
|
try:
|
|
148
147
|
r = get_valkey_client()
|
|
@@ -159,14 +158,12 @@ async def get_dict(name: str, value_data_type=None) -> dict | None:
|
|
|
159
158
|
r = get_valkey_client()
|
|
160
159
|
|
|
161
160
|
if data := await r.hgetall(name):
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return data
|
|
161
|
+
return {k.decode(): deserialize_msgpack(v, value_data_type) for k, v in data.items()}
|
|
165
162
|
|
|
166
163
|
return None
|
|
167
164
|
|
|
168
165
|
|
|
169
|
-
async def set_dict(name: str, mapping: dict, ttl: int = None):
|
|
166
|
+
async def set_dict(name: str, mapping: dict, ttl: int | None = None):
|
|
170
167
|
if mapping:
|
|
171
168
|
try:
|
|
172
169
|
r = get_valkey_client()
|
|
@@ -209,7 +206,7 @@ async def delete_dict_item(name: str, *keys):
|
|
|
209
206
|
logger.exception('Failed to delete dict item from cache.')
|
|
210
207
|
|
|
211
208
|
|
|
212
|
-
async def store_set(name: str, value: set, ttl: int = None):
|
|
209
|
+
async def store_set(name: str, value: set, ttl: int | None = None):
|
|
213
210
|
try:
|
|
214
211
|
r = get_valkey_client()
|
|
215
212
|
await r.sadd(name, *map(serialize_msgpack_native, value))
|
|
@@ -38,9 +38,8 @@ class AsyncSessionManager:
|
|
|
38
38
|
'pool_timeout': db_settings.pool_timeout,
|
|
39
39
|
'pool_recycle': db_settings.pool_recycle,
|
|
40
40
|
}
|
|
41
|
-
engine = async_engine_from_config(configuration, prefix='')
|
|
42
41
|
|
|
43
|
-
return
|
|
42
|
+
return async_engine_from_config(configuration, prefix='')
|
|
44
43
|
|
|
45
44
|
def get_engine(self, name: str) -> AsyncEngine:
|
|
46
45
|
try:
|
|
@@ -6,12 +6,12 @@ import threading
|
|
|
6
6
|
import time
|
|
7
7
|
from abc import ABCMeta
|
|
8
8
|
from collections import defaultdict
|
|
9
|
-
from collections.abc import Mapping, Sequence
|
|
9
|
+
from collections.abc import Mapping, MutableMapping, Sequence
|
|
10
10
|
from datetime import date, datetime, timedelta
|
|
11
11
|
from decimal import ROUND_HALF_UP, Decimal
|
|
12
12
|
from http.cookies import BaseCookie
|
|
13
13
|
from json import dumps
|
|
14
|
-
from typing import Literal
|
|
14
|
+
from typing import ClassVar, Literal
|
|
15
15
|
from urllib.parse import urlencode
|
|
16
16
|
|
|
17
17
|
from python3_commons.serializers.json import CustomJSONEncoder
|
|
@@ -24,8 +24,8 @@ class SingletonMeta(ABCMeta):
|
|
|
24
24
|
A metaclass that creates a Singleton base class when called.
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
-
__instances = {}
|
|
28
|
-
__locks = defaultdict(threading.Lock)
|
|
27
|
+
__instances: ClassVar[MutableMapping] = {}
|
|
28
|
+
__locks: ClassVar[defaultdict] = defaultdict(threading.Lock)
|
|
29
29
|
|
|
30
30
|
def __call__(cls, *args, **kwargs):
|
|
31
31
|
try:
|
|
@@ -70,6 +70,7 @@ def tries(times):
|
|
|
70
70
|
except Exception:
|
|
71
71
|
if _time >= times:
|
|
72
72
|
raise
|
|
73
|
+
return None
|
|
73
74
|
|
|
74
75
|
return wrapper
|
|
75
76
|
|
|
@@ -150,7 +150,7 @@ async def remove_object(bucket_name: str, object_name: str):
|
|
|
150
150
|
|
|
151
151
|
|
|
152
152
|
async def remove_objects(
|
|
153
|
-
bucket_name: str, prefix: str = None, object_names: Iterable[str] = None
|
|
153
|
+
bucket_name: str, prefix: str | None = None, object_names: Iterable[str] | None = None
|
|
154
154
|
) -> Sequence[Mapping] | None:
|
|
155
155
|
storage = ObjectStorage(s3_settings)
|
|
156
156
|
|
|
@@ -24,9 +24,8 @@ async def has_api_key_permission(session: AsyncSession, api_key_uid: UUID, permi
|
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
cursor = await session.execute(query)
|
|
27
|
-
result = cursor.scalar()
|
|
28
27
|
|
|
29
|
-
return
|
|
28
|
+
return bool(cursor.scalar())
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
async def has_user_permission(session: AsyncSession, user_id: UUID, permission: str) -> bool:
|
|
@@ -43,6 +42,5 @@ async def has_user_permission(session: AsyncSession, user_id: UUID, permission:
|
|
|
43
42
|
)
|
|
44
43
|
|
|
45
44
|
cursor = await session.execute(query)
|
|
46
|
-
result = cursor.scalar()
|
|
47
45
|
|
|
48
|
-
return
|
|
46
|
+
return bool(cursor.scalar())
|
|
@@ -14,11 +14,11 @@ class CustomJSONEncoder(json.JSONEncoder):
|
|
|
14
14
|
except TypeError:
|
|
15
15
|
if isinstance(o, (datetime, date)):
|
|
16
16
|
return o.isoformat()
|
|
17
|
-
|
|
17
|
+
if isinstance(o, bytes):
|
|
18
18
|
return base64.b64encode(o).decode('ascii')
|
|
19
|
-
|
|
19
|
+
if dataclasses.is_dataclass(o):
|
|
20
20
|
return dataclasses.asdict(o)
|
|
21
|
-
|
|
21
|
+
if isinstance(o, (Decimal, socket, type, Exception)):
|
|
22
22
|
return str(o)
|
|
23
23
|
|
|
24
24
|
return type(o).__name__
|
{python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/msgpack.py
RENAMED
|
@@ -16,11 +16,11 @@ logger = logging.getLogger(__name__)
|
|
|
16
16
|
def msgpack_encoder(obj):
|
|
17
17
|
if isinstance(obj, Decimal):
|
|
18
18
|
return ExtType(ExtendedType.DECIMAL, str(obj).encode())
|
|
19
|
-
|
|
19
|
+
if isinstance(obj, datetime):
|
|
20
20
|
return ExtType(ExtendedType.DATETIME, obj.isoformat().encode())
|
|
21
|
-
|
|
21
|
+
if isinstance(obj, date):
|
|
22
22
|
return ExtType(ExtendedType.DATE, obj.isoformat().encode())
|
|
23
|
-
|
|
23
|
+
if dataclasses.is_dataclass(obj):
|
|
24
24
|
return ExtType(ExtendedType.DATACLASS, json.dumps(dataclasses.asdict(obj), cls=CustomJSONEncoder).encode())
|
|
25
25
|
|
|
26
26
|
return f'no encoder for {obj}'
|
|
@@ -41,12 +41,8 @@ def msgpack_decoder(code, data):
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
def serialize_msgpack(data) -> bytes:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return result
|
|
44
|
+
return msgpack.packb(data, default=msgpack_encoder)
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
def deserialize_msgpack(data: bytes):
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return result
|
|
48
|
+
return msgpack.unpackb(data, ext_hook=msgpack_decoder)
|
{python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/msgspec.py
RENAMED
|
@@ -20,11 +20,11 @@ T = TypeVar('T')
|
|
|
20
20
|
def enc_hook(obj: Any) -> Any:
|
|
21
21
|
if isinstance(obj, Decimal):
|
|
22
22
|
return Ext(ExtendedType.DECIMAL, struct.pack('b', str(obj).encode()))
|
|
23
|
-
|
|
23
|
+
if isinstance(obj, datetime):
|
|
24
24
|
return Ext(ExtendedType.DATETIME, struct.pack('b', obj.isoformat().encode()))
|
|
25
|
-
|
|
25
|
+
if isinstance(obj, date):
|
|
26
26
|
return Ext(ExtendedType.DATE, struct.pack('b', obj.isoformat().encode()))
|
|
27
|
-
|
|
27
|
+
if dataclasses.is_dataclass(obj):
|
|
28
28
|
return Ext(
|
|
29
29
|
ExtendedType.DATACLASS,
|
|
30
30
|
struct.pack('b', json.dumps(dataclasses.asdict(obj), cls=CustomJSONEncoder).encode()),
|
|
@@ -60,9 +60,7 @@ def serialize_msgpack_native(data: Any) -> bytes:
|
|
|
60
60
|
if isinstance(data, BaseModel):
|
|
61
61
|
data = data.model_dump()
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return result
|
|
63
|
+
return encode(data)
|
|
66
64
|
|
|
67
65
|
|
|
68
66
|
def deserialize_msgpack_native[T](data: bytes, data_type: type[T] | None = None) -> T | Any:
|
|
@@ -82,9 +80,7 @@ def serialize_msgpack(data: Any) -> bytes:
|
|
|
82
80
|
if isinstance(data, BaseModel):
|
|
83
81
|
data = data.model_dump()
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return result
|
|
83
|
+
return MSGPACK_ENCODER.encode(data)
|
|
88
84
|
|
|
89
85
|
|
|
90
86
|
def deserialize_msgpack[T](data: bytes, data_type: type[T] | None = None) -> T | Any:
|
|
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
|
{python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons/serializers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.10.0 → python3_commons-0.10.1}/src/python3_commons.egg-info/top_level.txt
RENAMED
|
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
|