python3-commons 0.16.8__tar.gz → 0.17.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.
- python3_commons-0.17.1/PKG-INFO +42 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/pyproject.toml +30 -9
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/api_client.py +17 -13
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/audit.py +6 -2
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/auth.py +10 -5
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/cache.py +13 -9
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/__init__.py +8 -4
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/helpers.py +7 -3
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/models/auth.py +6 -2
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/models/common.py +10 -6
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/models/rbac.py +7 -3
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/models/users.py +6 -2
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/log/formatters.py +6 -6
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/object_storage.py +7 -3
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/permissions.py +6 -2
- python3_commons-0.17.1/src/python3_commons.egg-info/PKG-INFO +42 -0
- python3_commons-0.17.1/src/python3_commons.egg-info/requires.txt +29 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/uv.lock +50 -18
- python3_commons-0.16.8/PKG-INFO +0 -31
- python3_commons-0.16.8/src/python3_commons.egg-info/PKG-INFO +0 -31
- python3_commons-0.16.8/src/python3_commons.egg-info/requires.txt +0 -11
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.coveragerc +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.devcontainer/Dockerfile +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.devcontainer/devcontainer.json +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.devcontainer/docker-compose.yml +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.env_template +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.github/workflows/checks.yml +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.github/workflows/release-on-tag-push.yml +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.gitignore +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.pre-commit-config.yaml +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/.python-version +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/AUTHORS.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/CHANGELOG.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/LICENSE +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/README.md +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/README.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/Makefile +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/_static/.gitignore +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/authors.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/changelog.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/conf.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/index.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/docs/license.rst +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/setup.cfg +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/async_functools.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/conf.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/db/models/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/exceptions.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/generators.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/helpers.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/log/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/log/filters.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/common.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/json.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/msgpack.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/msgspec.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons.egg-info/SOURCES.txt +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/integration/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/integration/test_cache.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/integration/test_osc.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/conftest.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/log/__init__.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/log/test_formatters.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/test_async_functools.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/test_audit.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/test_helpers.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/test_msgpack.py +0 -0
- {python3_commons-0.16.8 → python3_commons-0.17.1}/tests/unit/test_msgspec.py +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python3-commons
|
|
3
|
+
Version: 0.17.1
|
|
4
|
+
Summary: Re-usable Python3 code
|
|
5
|
+
Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/kamikaze/python3-commons
|
|
8
|
+
Project-URL: Documentation, https://github.com/kamikaze/python3-commons/wiki
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Programming Language :: Python
|
|
11
|
+
Requires-Python: <3.15.0,>=3.14.0
|
|
12
|
+
Description-Content-Type: text/x-rst
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
License-File: AUTHORS.rst
|
|
15
|
+
Requires-Dist: msgpack~=1.1.2
|
|
16
|
+
Requires-Dist: msgspec==0.21.1
|
|
17
|
+
Requires-Dist: pydantic-settings~=2.14.0
|
|
18
|
+
Provides-Extra: all
|
|
19
|
+
Requires-Dist: python3_commons[audit,authn,authz,cache,database,object-storage]; extra == "all"
|
|
20
|
+
Provides-Extra: api-client
|
|
21
|
+
Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "api-client"
|
|
22
|
+
Requires-Dist: lxml~=6.1.0; extra == "api-client"
|
|
23
|
+
Requires-Dist: zeep~=4.3.2; extra == "api-client"
|
|
24
|
+
Requires-Dist: python3_commons[object-storage]; extra == "api-client"
|
|
25
|
+
Provides-Extra: authn
|
|
26
|
+
Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "authn"
|
|
27
|
+
Provides-Extra: authz
|
|
28
|
+
Requires-Dist: python3_commons[database]; extra == "authz"
|
|
29
|
+
Provides-Extra: cache
|
|
30
|
+
Requires-Dist: valkey[libvalkey]~=6.1.1; extra == "cache"
|
|
31
|
+
Provides-Extra: database
|
|
32
|
+
Requires-Dist: asyncpg~=0.31.0; extra == "database"
|
|
33
|
+
Requires-Dist: SQLAlchemy[asyncio]~=2.0.49; extra == "database"
|
|
34
|
+
Provides-Extra: object-storage
|
|
35
|
+
Requires-Dist: aiobotocore~=3.5.0; extra == "object-storage"
|
|
36
|
+
Requires-Dist: object-storage-client==0.0.22; extra == "object-storage"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
Re-usable Python3 code
|
|
40
|
+
======================
|
|
41
|
+
|
|
42
|
+
Some description here
|
|
@@ -18,18 +18,39 @@ classifiers = [
|
|
|
18
18
|
keywords = []
|
|
19
19
|
requires-python = ">=3.14.0,<3.15.0"
|
|
20
20
|
dependencies = [
|
|
21
|
-
"aiobotocore~=3.5.0",
|
|
22
|
-
"aiohttp[speedups]>=3.13.5,<3.15.0",
|
|
23
|
-
"asyncpg~=0.31.0",
|
|
24
|
-
"lxml~=6.1.0",
|
|
25
21
|
"msgpack~=1.1.2",
|
|
26
22
|
"msgspec==0.21.1",
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
"pydantic-settings~=2.14.0"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
all = [
|
|
28
|
+
"python3_commons[audit,authn,authz,cache,database,object-storage]"
|
|
29
|
+
]
|
|
30
|
+
api-client = [
|
|
31
|
+
"aiohttp[speedups]>=3.13.5,<3.15.0",
|
|
32
|
+
"lxml~=6.1.0",
|
|
33
|
+
"zeep~=4.3.2",
|
|
34
|
+
"python3_commons[object-storage]"
|
|
32
35
|
]
|
|
36
|
+
authn = [
|
|
37
|
+
"aiohttp[speedups]>=3.13.5,<3.15.0",
|
|
38
|
+
]
|
|
39
|
+
authz = [
|
|
40
|
+
"python3_commons[database]"
|
|
41
|
+
]
|
|
42
|
+
cache = [
|
|
43
|
+
"valkey[libvalkey]~=6.1.1"
|
|
44
|
+
]
|
|
45
|
+
database = [
|
|
46
|
+
"asyncpg~=0.31.0",
|
|
47
|
+
"SQLAlchemy[asyncio]~=2.0.49"
|
|
48
|
+
]
|
|
49
|
+
object-storage = [
|
|
50
|
+
"aiobotocore~=3.5.0",
|
|
51
|
+
"object-storage-client==0.0.22"
|
|
52
|
+
]
|
|
53
|
+
|
|
33
54
|
|
|
34
55
|
[dependency-groups]
|
|
35
56
|
dev = [
|
|
@@ -9,8 +9,12 @@ from json import dumps
|
|
|
9
9
|
from typing import Literal
|
|
10
10
|
from uuid import uuid4
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
from aiohttp
|
|
12
|
+
try:
|
|
13
|
+
from aiohttp import ClientResponse, ClientSession, ClientTimeout, client_exceptions
|
|
14
|
+
from aiohttp.abc import URL
|
|
15
|
+
except ImportError as e:
|
|
16
|
+
msg = 'Install python3-commons[api-client] to use this feature'
|
|
17
|
+
raise RuntimeError(msg) from e
|
|
14
18
|
|
|
15
19
|
from python3_commons import audit
|
|
16
20
|
from python3_commons.conf import s3_settings
|
|
@@ -21,7 +25,7 @@ logger = logging.getLogger(__name__)
|
|
|
21
25
|
|
|
22
26
|
|
|
23
27
|
async def _store_response_for_audit(
|
|
24
|
-
|
|
28
|
+
response: ClientResponse, audit_name: str, uri_path: str, method: str, request_id: str
|
|
25
29
|
) -> None:
|
|
26
30
|
response_text = await response.text()
|
|
27
31
|
|
|
@@ -39,16 +43,16 @@ async def _store_response_for_audit(
|
|
|
39
43
|
|
|
40
44
|
@asynccontextmanager
|
|
41
45
|
async def request(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
client: ClientSession,
|
|
47
|
+
base_url: str,
|
|
48
|
+
uri: str,
|
|
49
|
+
query: Mapping | None = None,
|
|
50
|
+
method: Literal['get', 'post', 'put', 'patch', 'options', 'head', 'delete'] = 'get',
|
|
51
|
+
headers: Mapping | None = None,
|
|
52
|
+
json: Mapping | Sequence | str | None = None,
|
|
53
|
+
data: bytes | None = None,
|
|
54
|
+
timeout: ClientTimeout | Enum | None = None,
|
|
55
|
+
audit_name: str | None = None,
|
|
52
56
|
) -> AsyncGenerator[ClientResponse]:
|
|
53
57
|
now = datetime.now(tz=UTC)
|
|
54
58
|
date_path = now.strftime('%Y/%m/%d')
|
|
@@ -5,8 +5,12 @@ from datetime import UTC, datetime
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
from uuid import uuid4
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
from
|
|
8
|
+
try:
|
|
9
|
+
from lxml import etree
|
|
10
|
+
from zeep.plugins import Plugin
|
|
11
|
+
except ImportError as e:
|
|
12
|
+
msg = 'Install python3-commons[api-client] to use this feature'
|
|
13
|
+
raise RuntimeError(msg) from e
|
|
10
14
|
|
|
11
15
|
from python3_commons import object_storage
|
|
12
16
|
from python3_commons.conf import S3Settings, s3_settings
|
|
@@ -5,7 +5,12 @@ from collections.abc import Sequence
|
|
|
5
5
|
from http import HTTPStatus
|
|
6
6
|
from typing import TypeVar
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
try:
|
|
9
|
+
import aiohttp
|
|
10
|
+
except ImportError as e:
|
|
11
|
+
msg = 'Install python3-commons[authn] to use this feature'
|
|
12
|
+
raise RuntimeError(msg) from e
|
|
13
|
+
|
|
9
14
|
import msgspec
|
|
10
15
|
|
|
11
16
|
from python3_commons.conf import oidc_settings
|
|
@@ -51,9 +56,9 @@ async def fetch_openid_config() -> dict:
|
|
|
51
56
|
"""
|
|
52
57
|
async with aiohttp.ClientSession() as session, session.get(OIDC_CONFIG_URL) as response:
|
|
53
58
|
if response.status != HTTPStatus.OK:
|
|
54
|
-
|
|
59
|
+
_msg = 'Failed to fetch OpenID configuration'
|
|
55
60
|
|
|
56
|
-
raise RuntimeError(
|
|
61
|
+
raise RuntimeError(_msg)
|
|
57
62
|
|
|
58
63
|
return await response.json()
|
|
59
64
|
|
|
@@ -67,8 +72,8 @@ async def fetch_jwks(jwks_uri: str) -> dict:
|
|
|
67
72
|
|
|
68
73
|
async with aiohttp.ClientSession() as session, session.get(jwks_uri) as response:
|
|
69
74
|
if response.status != HTTPStatus.OK:
|
|
70
|
-
|
|
75
|
+
_msg = 'Failed to fetch JWKS'
|
|
71
76
|
|
|
72
|
-
raise RuntimeError(
|
|
77
|
+
raise RuntimeError(_msg)
|
|
73
78
|
|
|
74
79
|
return await response.json()
|
|
@@ -4,10 +4,14 @@ from collections.abc import Mapping, Sequence
|
|
|
4
4
|
from platform import platform
|
|
5
5
|
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from valkey.asyncio
|
|
10
|
-
from valkey.
|
|
7
|
+
try:
|
|
8
|
+
import valkey
|
|
9
|
+
from valkey.asyncio import ConnectionPool, Sentinel, StrictValkey, Valkey
|
|
10
|
+
from valkey.asyncio.retry import Retry
|
|
11
|
+
from valkey.backoff import FullJitterBackoff
|
|
12
|
+
except ImportError as e:
|
|
13
|
+
msg = 'Install python3-commons[cache] to use this feature'
|
|
14
|
+
raise RuntimeError(msg) from e
|
|
11
15
|
|
|
12
16
|
from python3_commons.conf import valkey_settings
|
|
13
17
|
from python3_commons.helpers import SingletonMeta
|
|
@@ -77,11 +81,11 @@ def get_valkey_client() -> Valkey:
|
|
|
77
81
|
|
|
78
82
|
|
|
79
83
|
async def scan(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
cursor: int = 0,
|
|
85
|
+
match: bytes | str | memoryview | None = None,
|
|
86
|
+
count: int | None = None,
|
|
87
|
+
_type: str | None = None,
|
|
88
|
+
**kwargs,
|
|
85
89
|
) -> ResponseT:
|
|
86
90
|
return await get_valkey_client().scan(cursor, match, count, _type, **kwargs)
|
|
87
91
|
|
|
@@ -3,10 +3,14 @@ import logging
|
|
|
3
3
|
from collections.abc import AsyncGenerator, Callable, Mapping
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
from sqlalchemy
|
|
8
|
-
from sqlalchemy.ext.asyncio
|
|
9
|
-
from sqlalchemy.
|
|
6
|
+
try:
|
|
7
|
+
from sqlalchemy import MetaData
|
|
8
|
+
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_engine_from_config
|
|
9
|
+
from sqlalchemy.ext.asyncio.session import async_sessionmaker
|
|
10
|
+
from sqlalchemy.orm import declarative_base
|
|
11
|
+
except ImportError as e:
|
|
12
|
+
msg = 'Install python3-commons[database] to use this feature'
|
|
13
|
+
raise RuntimeError(msg) from e
|
|
10
14
|
|
|
11
15
|
if TYPE_CHECKING:
|
|
12
16
|
from python3_commons.conf import DBSettings
|
|
@@ -2,8 +2,12 @@ import logging
|
|
|
2
2
|
from collections.abc import Mapping
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
try:
|
|
6
|
+
import sqlalchemy as sa
|
|
7
|
+
from sqlalchemy import asc, desc, func
|
|
8
|
+
except ImportError as e:
|
|
9
|
+
msg = 'Install python3-commons[database] to use this feature'
|
|
10
|
+
raise RuntimeError(msg) from e
|
|
7
11
|
|
|
8
12
|
if TYPE_CHECKING:
|
|
9
13
|
from sqlalchemy.sql.elements import ColumnElement
|
|
@@ -12,7 +16,7 @@ logger = logging.getLogger(__name__)
|
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
def get_query(
|
|
15
|
-
|
|
19
|
+
search: Mapping[str, str] | None = None, order_by: str | None = None, columns: Mapping | None = None
|
|
16
20
|
) -> tuple[ColumnElement[bool] | None, tuple[ColumnElement[bool]] | None]:
|
|
17
21
|
"""
|
|
18
22
|
:columns:
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from sqlalchemy
|
|
4
|
+
try:
|
|
5
|
+
from sqlalchemy import UUID, DateTime, ForeignKey, String
|
|
6
|
+
from sqlalchemy.orm import Mapped, mapped_column
|
|
7
|
+
except ImportError as e:
|
|
8
|
+
msg = 'Install python3-commons[database] to use this feature'
|
|
9
|
+
raise RuntimeError(msg) from e
|
|
6
10
|
|
|
7
11
|
from python3_commons.db import Base
|
|
8
12
|
from python3_commons.db.models.common import BaseDBUUIDModel
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from sqlalchemy
|
|
6
|
-
from sqlalchemy.
|
|
7
|
-
from sqlalchemy.
|
|
8
|
-
from sqlalchemy.
|
|
9
|
-
from sqlalchemy.sql
|
|
4
|
+
try:
|
|
5
|
+
from sqlalchemy import BIGINT, DateTime
|
|
6
|
+
from sqlalchemy.dialects.postgresql import UUID
|
|
7
|
+
from sqlalchemy.ext.compiler import compiles
|
|
8
|
+
from sqlalchemy.orm import Mapped, mapped_column
|
|
9
|
+
from sqlalchemy.sql import expression
|
|
10
|
+
from sqlalchemy.sql.ddl import CreateColumn
|
|
11
|
+
except ImportError as e:
|
|
12
|
+
msg = 'Install python3-commons[database] to use this feature'
|
|
13
|
+
raise RuntimeError(msg) from e
|
|
10
14
|
|
|
11
15
|
|
|
12
16
|
class UTCNow(expression.FunctionElement):
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from sqlalchemy
|
|
6
|
-
from sqlalchemy.
|
|
4
|
+
try:
|
|
5
|
+
from sqlalchemy import CheckConstraint, DateTime, ForeignKey, PrimaryKeyConstraint, String
|
|
6
|
+
from sqlalchemy.dialects.postgresql import UUID
|
|
7
|
+
from sqlalchemy.orm import Mapped, mapped_column
|
|
8
|
+
except ImportError as e:
|
|
9
|
+
msg = 'Install python3-commons[database] to use this feature'
|
|
10
|
+
raise RuntimeError(msg) from e
|
|
7
11
|
|
|
8
12
|
from python3_commons.db import Base
|
|
9
13
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
from sqlalchemy
|
|
3
|
+
try:
|
|
4
|
+
from sqlalchemy import UUID, ForeignKey, String
|
|
5
|
+
from sqlalchemy.orm import Mapped, mapped_column
|
|
6
|
+
except ImportError as e:
|
|
7
|
+
msg = 'Install python3-commons[database] to use this feature'
|
|
8
|
+
raise RuntimeError(msg) from e
|
|
5
9
|
|
|
6
10
|
from python3_commons.db import Base
|
|
7
11
|
from python3_commons.db.models.common import BaseDBUUIDModel
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import traceback
|
|
3
|
-
from datetime import UTC,
|
|
3
|
+
from datetime import UTC, date, datetime
|
|
4
4
|
from decimal import Decimal
|
|
5
5
|
from typing import Any, Final
|
|
6
6
|
|
|
@@ -51,13 +51,13 @@ def _normalize(v: Any) -> Any:
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
class JSONFormatter(logging.Formatter):
|
|
54
|
-
__slots__ = ('
|
|
54
|
+
__slots__ = ('_encoder', '_max_tb_chars')
|
|
55
55
|
|
|
56
56
|
def __init__(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
self,
|
|
58
|
+
*,
|
|
59
|
+
max_exc_tb_chars: int = _DEFAULT_MAX_TB_CHARS,
|
|
60
|
+
**kwargs: Any,
|
|
61
61
|
) -> None:
|
|
62
62
|
super().__init__(**kwargs)
|
|
63
63
|
|
|
@@ -5,9 +5,13 @@ import threading
|
|
|
5
5
|
from contextlib import asynccontextmanager
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from
|
|
8
|
+
try:
|
|
9
|
+
import aiobotocore.session
|
|
10
|
+
from botocore.config import Config
|
|
11
|
+
from object_storage_client import ObjectStorageClient
|
|
12
|
+
except ImportError as e:
|
|
13
|
+
msg = 'Install python3-commons[object-storage] to use this feature'
|
|
14
|
+
raise RuntimeError(msg) from e
|
|
11
15
|
|
|
12
16
|
if TYPE_CHECKING:
|
|
13
17
|
import io
|
|
@@ -2,8 +2,12 @@ import logging
|
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
try:
|
|
6
|
+
import sqlalchemy as sa
|
|
7
|
+
from sqlalchemy import and_, exists, func
|
|
8
|
+
except ImportError as e:
|
|
9
|
+
msg = 'Install python3-commons[authz] to use this feature'
|
|
10
|
+
raise RuntimeError(msg) from e
|
|
7
11
|
|
|
8
12
|
from python3_commons.db.models.rbac import RBACApiKeyRole, RBACPermission, RBACRolePermission, RBACUserRole
|
|
9
13
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python3-commons
|
|
3
|
+
Version: 0.17.1
|
|
4
|
+
Summary: Re-usable Python3 code
|
|
5
|
+
Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/kamikaze/python3-commons
|
|
8
|
+
Project-URL: Documentation, https://github.com/kamikaze/python3-commons/wiki
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Programming Language :: Python
|
|
11
|
+
Requires-Python: <3.15.0,>=3.14.0
|
|
12
|
+
Description-Content-Type: text/x-rst
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
License-File: AUTHORS.rst
|
|
15
|
+
Requires-Dist: msgpack~=1.1.2
|
|
16
|
+
Requires-Dist: msgspec==0.21.1
|
|
17
|
+
Requires-Dist: pydantic-settings~=2.14.0
|
|
18
|
+
Provides-Extra: all
|
|
19
|
+
Requires-Dist: python3_commons[audit,authn,authz,cache,database,object-storage]; extra == "all"
|
|
20
|
+
Provides-Extra: api-client
|
|
21
|
+
Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "api-client"
|
|
22
|
+
Requires-Dist: lxml~=6.1.0; extra == "api-client"
|
|
23
|
+
Requires-Dist: zeep~=4.3.2; extra == "api-client"
|
|
24
|
+
Requires-Dist: python3_commons[object-storage]; extra == "api-client"
|
|
25
|
+
Provides-Extra: authn
|
|
26
|
+
Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "authn"
|
|
27
|
+
Provides-Extra: authz
|
|
28
|
+
Requires-Dist: python3_commons[database]; extra == "authz"
|
|
29
|
+
Provides-Extra: cache
|
|
30
|
+
Requires-Dist: valkey[libvalkey]~=6.1.1; extra == "cache"
|
|
31
|
+
Provides-Extra: database
|
|
32
|
+
Requires-Dist: asyncpg~=0.31.0; extra == "database"
|
|
33
|
+
Requires-Dist: SQLAlchemy[asyncio]~=2.0.49; extra == "database"
|
|
34
|
+
Provides-Extra: object-storage
|
|
35
|
+
Requires-Dist: aiobotocore~=3.5.0; extra == "object-storage"
|
|
36
|
+
Requires-Dist: object-storage-client==0.0.22; extra == "object-storage"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
Re-usable Python3 code
|
|
40
|
+
======================
|
|
41
|
+
|
|
42
|
+
Some description here
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
msgpack~=1.1.2
|
|
2
|
+
msgspec==0.21.1
|
|
3
|
+
pydantic-settings~=2.14.0
|
|
4
|
+
|
|
5
|
+
[all]
|
|
6
|
+
python3_commons[audit,authn,authz,cache,database,object-storage]
|
|
7
|
+
|
|
8
|
+
[api-client]
|
|
9
|
+
aiohttp[speedups]<3.15.0,>=3.13.5
|
|
10
|
+
lxml~=6.1.0
|
|
11
|
+
zeep~=4.3.2
|
|
12
|
+
python3_commons[object-storage]
|
|
13
|
+
|
|
14
|
+
[authn]
|
|
15
|
+
aiohttp[speedups]<3.15.0,>=3.13.5
|
|
16
|
+
|
|
17
|
+
[authz]
|
|
18
|
+
python3_commons[database]
|
|
19
|
+
|
|
20
|
+
[cache]
|
|
21
|
+
valkey[libvalkey]~=6.1.1
|
|
22
|
+
|
|
23
|
+
[database]
|
|
24
|
+
asyncpg~=0.31.0
|
|
25
|
+
SQLAlchemy[asyncio]~=2.0.49
|
|
26
|
+
|
|
27
|
+
[object-storage]
|
|
28
|
+
aiobotocore~=3.5.0
|
|
29
|
+
object-storage-client==0.0.22
|
|
@@ -992,18 +992,45 @@ wheels = [
|
|
|
992
992
|
name = "python3-commons"
|
|
993
993
|
source = { editable = "." }
|
|
994
994
|
dependencies = [
|
|
995
|
+
{ name = "msgpack" },
|
|
996
|
+
{ name = "msgspec" },
|
|
997
|
+
{ name = "pydantic-settings" },
|
|
998
|
+
]
|
|
999
|
+
|
|
1000
|
+
[package.optional-dependencies]
|
|
1001
|
+
all = [
|
|
995
1002
|
{ name = "aiobotocore" },
|
|
996
1003
|
{ name = "aiohttp", extra = ["speedups"] },
|
|
997
1004
|
{ name = "asyncpg" },
|
|
998
|
-
{ name = "lxml" },
|
|
999
|
-
{ name = "msgpack" },
|
|
1000
|
-
{ name = "msgspec" },
|
|
1001
1005
|
{ name = "object-storage-client" },
|
|
1002
|
-
{ name = "pydantic-settings" },
|
|
1003
1006
|
{ name = "sqlalchemy", extra = ["asyncio"] },
|
|
1004
1007
|
{ name = "valkey", extra = ["libvalkey"] },
|
|
1008
|
+
]
|
|
1009
|
+
api-client = [
|
|
1010
|
+
{ name = "aiobotocore" },
|
|
1011
|
+
{ name = "aiohttp", extra = ["speedups"] },
|
|
1012
|
+
{ name = "lxml" },
|
|
1013
|
+
{ name = "object-storage-client" },
|
|
1005
1014
|
{ name = "zeep" },
|
|
1006
1015
|
]
|
|
1016
|
+
authn = [
|
|
1017
|
+
{ name = "aiohttp", extra = ["speedups"] },
|
|
1018
|
+
]
|
|
1019
|
+
authz = [
|
|
1020
|
+
{ name = "asyncpg" },
|
|
1021
|
+
{ name = "sqlalchemy", extra = ["asyncio"] },
|
|
1022
|
+
]
|
|
1023
|
+
cache = [
|
|
1024
|
+
{ name = "valkey", extra = ["libvalkey"] },
|
|
1025
|
+
]
|
|
1026
|
+
database = [
|
|
1027
|
+
{ name = "asyncpg" },
|
|
1028
|
+
{ name = "sqlalchemy", extra = ["asyncio"] },
|
|
1029
|
+
]
|
|
1030
|
+
object-storage = [
|
|
1031
|
+
{ name = "aiobotocore" },
|
|
1032
|
+
{ name = "object-storage-client" },
|
|
1033
|
+
]
|
|
1007
1034
|
|
|
1008
1035
|
[package.dev-dependencies]
|
|
1009
1036
|
dev = [
|
|
@@ -1024,18 +1051,23 @@ testing = [
|
|
|
1024
1051
|
|
|
1025
1052
|
[package.metadata]
|
|
1026
1053
|
requires-dist = [
|
|
1027
|
-
{ name = "aiobotocore", specifier = "~=3.5.0" },
|
|
1028
|
-
{ name = "aiohttp", extras = ["speedups"], specifier = ">=3.13.5,<3.15.0" },
|
|
1029
|
-
{ name = "
|
|
1030
|
-
{ name = "
|
|
1054
|
+
{ name = "aiobotocore", marker = "extra == 'object-storage'", specifier = "~=3.5.0" },
|
|
1055
|
+
{ name = "aiohttp", extras = ["speedups"], marker = "extra == 'api-client'", specifier = ">=3.13.5,<3.15.0" },
|
|
1056
|
+
{ name = "aiohttp", extras = ["speedups"], marker = "extra == 'authn'", specifier = ">=3.13.5,<3.15.0" },
|
|
1057
|
+
{ name = "asyncpg", marker = "extra == 'database'", specifier = "~=0.31.0" },
|
|
1058
|
+
{ name = "lxml", marker = "extra == 'api-client'", specifier = "~=6.1.0" },
|
|
1031
1059
|
{ name = "msgpack", specifier = "~=1.1.2" },
|
|
1032
1060
|
{ name = "msgspec", specifier = "==0.21.1" },
|
|
1033
|
-
{ name = "object-storage-client", specifier = "==0.0.22" },
|
|
1061
|
+
{ name = "object-storage-client", marker = "extra == 'object-storage'", specifier = "==0.0.22" },
|
|
1034
1062
|
{ name = "pydantic-settings", specifier = "~=2.14.0" },
|
|
1035
|
-
{ name = "
|
|
1036
|
-
{ name = "
|
|
1037
|
-
{ name = "
|
|
1063
|
+
{ name = "python3-commons", extras = ["audit", "authn", "authz", "cache", "database", "object-storage"], marker = "extra == 'all'" },
|
|
1064
|
+
{ name = "python3-commons", extras = ["database"], marker = "extra == 'authz'" },
|
|
1065
|
+
{ name = "python3-commons", extras = ["object-storage"], marker = "extra == 'api-client'" },
|
|
1066
|
+
{ name = "sqlalchemy", extras = ["asyncio"], marker = "extra == 'database'", specifier = "~=2.0.49" },
|
|
1067
|
+
{ name = "valkey", extras = ["libvalkey"], marker = "extra == 'cache'", specifier = "~=6.1.1" },
|
|
1068
|
+
{ name = "zeep", marker = "extra == 'api-client'", specifier = "~=4.3.2" },
|
|
1038
1069
|
]
|
|
1070
|
+
provides-extras = ["all", "api-client", "authn", "authz", "cache", "database", "object-storage"]
|
|
1039
1071
|
|
|
1040
1072
|
[package.metadata.requires-dev]
|
|
1041
1073
|
dev = [
|
|
@@ -1193,14 +1225,14 @@ asyncio = [
|
|
|
1193
1225
|
|
|
1194
1226
|
[[package]]
|
|
1195
1227
|
name = "types-aiobotocore"
|
|
1196
|
-
version = "3.
|
|
1228
|
+
version = "3.5.0"
|
|
1197
1229
|
source = { registry = "https://pypi.org/simple" }
|
|
1198
1230
|
dependencies = [
|
|
1199
1231
|
{ name = "botocore-stubs" },
|
|
1200
1232
|
]
|
|
1201
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1233
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d5/99/3863acdc373aa621cf56634bb08145fb54f2213e647d893c1ac7b2636c11/types_aiobotocore-3.5.0.tar.gz", hash = "sha256:8636c9e5a9837d41e45264570349d98c0cdad51fe7961ee19664a11094bb2262", size = 87983, upload-time = "2026-04-23T02:57:02.576Z" }
|
|
1202
1234
|
wheels = [
|
|
1203
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1235
|
+
{ url = "https://files.pythonhosted.org/packages/ed/d7/2b2d4d5b64b81149b08cc3fde6e826788c703c012b687cd4cc4d83742afd/types_aiobotocore-3.5.0-py3-none-any.whl", hash = "sha256:7c75ff73c10098d1d885e5b061f05945afdc4e9d0d5b573274292c329abe8a62", size = 54805, upload-time = "2026-04-23T02:56:59.721Z" },
|
|
1204
1236
|
]
|
|
1205
1237
|
|
|
1206
1238
|
[package.optional-dependencies]
|
|
@@ -1210,11 +1242,11 @@ s3 = [
|
|
|
1210
1242
|
|
|
1211
1243
|
[[package]]
|
|
1212
1244
|
name = "types-aiobotocore-s3"
|
|
1213
|
-
version = "3.
|
|
1245
|
+
version = "3.5.0"
|
|
1214
1246
|
source = { registry = "https://pypi.org/simple" }
|
|
1215
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1247
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2d/6b/0d9fd45a69afbd2007480a35e8612121f6e27b988741b3a6d0b05c964229/types_aiobotocore_s3-3.5.0.tar.gz", hash = "sha256:147e2128be67de8c8a33b8a9bcca5fa8e963c6c54e52c58c17fa5c6013195a5a", size = 77175, upload-time = "2026-04-23T02:54:40.652Z" }
|
|
1216
1248
|
wheels = [
|
|
1217
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1249
|
+
{ url = "https://files.pythonhosted.org/packages/3b/c4/ce16af65a9227fe0ff3e737c0b4317e138fffbd06f7d631fe3a1b5a7f0f3/types_aiobotocore_s3-3.5.0-py3-none-any.whl", hash = "sha256:6fc53a6da5ec5cfb5478197fca74e1d11c389e0e20df7c0e0006a84c56224ada", size = 84930, upload-time = "2026-04-23T02:54:36.283Z" },
|
|
1218
1250
|
]
|
|
1219
1251
|
|
|
1220
1252
|
[[package]]
|
python3_commons-0.16.8/PKG-INFO
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: python3-commons
|
|
3
|
-
Version: 0.16.8
|
|
4
|
-
Summary: Re-usable Python3 code
|
|
5
|
-
Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
|
|
6
|
-
License-Expression: GPL-3.0
|
|
7
|
-
Project-URL: Homepage, https://github.com/kamikaze/python3-commons
|
|
8
|
-
Project-URL: Documentation, https://github.com/kamikaze/python3-commons/wiki
|
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
|
10
|
-
Classifier: Programming Language :: Python
|
|
11
|
-
Requires-Python: <3.15.0,>=3.14.0
|
|
12
|
-
Description-Content-Type: text/x-rst
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
License-File: AUTHORS.rst
|
|
15
|
-
Requires-Dist: aiobotocore~=3.5.0
|
|
16
|
-
Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5
|
|
17
|
-
Requires-Dist: asyncpg~=0.31.0
|
|
18
|
-
Requires-Dist: lxml~=6.1.0
|
|
19
|
-
Requires-Dist: msgpack~=1.1.2
|
|
20
|
-
Requires-Dist: msgspec==0.21.1
|
|
21
|
-
Requires-Dist: object-storage-client==0.0.22
|
|
22
|
-
Requires-Dist: pydantic-settings~=2.14.0
|
|
23
|
-
Requires-Dist: SQLAlchemy[asyncio]~=2.0.49
|
|
24
|
-
Requires-Dist: valkey[libvalkey]~=6.1.1
|
|
25
|
-
Requires-Dist: zeep~=4.3.2
|
|
26
|
-
Dynamic: license-file
|
|
27
|
-
|
|
28
|
-
Re-usable Python3 code
|
|
29
|
-
======================
|
|
30
|
-
|
|
31
|
-
Some description here
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: python3-commons
|
|
3
|
-
Version: 0.16.8
|
|
4
|
-
Summary: Re-usable Python3 code
|
|
5
|
-
Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
|
|
6
|
-
License-Expression: GPL-3.0
|
|
7
|
-
Project-URL: Homepage, https://github.com/kamikaze/python3-commons
|
|
8
|
-
Project-URL: Documentation, https://github.com/kamikaze/python3-commons/wiki
|
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
|
10
|
-
Classifier: Programming Language :: Python
|
|
11
|
-
Requires-Python: <3.15.0,>=3.14.0
|
|
12
|
-
Description-Content-Type: text/x-rst
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
License-File: AUTHORS.rst
|
|
15
|
-
Requires-Dist: aiobotocore~=3.5.0
|
|
16
|
-
Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5
|
|
17
|
-
Requires-Dist: asyncpg~=0.31.0
|
|
18
|
-
Requires-Dist: lxml~=6.1.0
|
|
19
|
-
Requires-Dist: msgpack~=1.1.2
|
|
20
|
-
Requires-Dist: msgspec==0.21.1
|
|
21
|
-
Requires-Dist: object-storage-client==0.0.22
|
|
22
|
-
Requires-Dist: pydantic-settings~=2.14.0
|
|
23
|
-
Requires-Dist: SQLAlchemy[asyncio]~=2.0.49
|
|
24
|
-
Requires-Dist: valkey[libvalkey]~=6.1.1
|
|
25
|
-
Requires-Dist: zeep~=4.3.2
|
|
26
|
-
Dynamic: license-file
|
|
27
|
-
|
|
28
|
-
Re-usable Python3 code
|
|
29
|
-
======================
|
|
30
|
-
|
|
31
|
-
Some description here
|
|
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
|
{python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/msgpack.py
RENAMED
|
File without changes
|
{python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons/serializers/msgspec.py
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.16.8 → python3_commons-0.17.1}/src/python3_commons.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{python3_commons-0.16.8 → python3_commons-0.17.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|