python3-commons 0.16.7__tar.gz → 0.17.0__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.0/PKG-INFO +42 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/pyproject.toml +31 -10
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/api_client.py +6 -2
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/audit.py +6 -2
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/auth.py +10 -5
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/cache.py +8 -4
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/__init__.py +8 -4
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/helpers.py +6 -2
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/models/auth.py +6 -2
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/models/common.py +10 -6
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/models/rbac.py +7 -3
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/models/users.py +6 -2
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/log/formatters.py +14 -13
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/object_storage.py +11 -7
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/permissions.py +6 -2
- python3_commons-0.17.0/src/python3_commons.egg-info/PKG-INFO +42 -0
- python3_commons-0.17.0/src/python3_commons.egg-info/requires.txt +29 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/uv.lock +62 -31
- python3_commons-0.16.7/PKG-INFO +0 -31
- python3_commons-0.16.7/src/python3_commons.egg-info/PKG-INFO +0 -31
- python3_commons-0.16.7/src/python3_commons.egg-info/requires.txt +0 -11
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.coveragerc +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.devcontainer/Dockerfile +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.devcontainer/devcontainer.json +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.devcontainer/docker-compose.yml +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.env_template +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.github/workflows/checks.yml +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.github/workflows/release-on-tag-push.yml +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.gitignore +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.pre-commit-config.yaml +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/.python-version +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/AUTHORS.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/CHANGELOG.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/LICENSE +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/README.md +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/README.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/Makefile +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/_static/.gitignore +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/authors.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/changelog.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/conf.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/index.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/docs/license.rst +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/setup.cfg +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/async_functools.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/conf.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/db/models/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/exceptions.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/generators.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/helpers.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/log/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/log/filters.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/common.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/json.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/msgpack.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/msgspec.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons.egg-info/SOURCES.txt +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/integration/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/integration/test_cache.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/integration/test_osc.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/conftest.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/log/__init__.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/log/test_formatters.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/test_async_functools.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/test_audit.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/test_helpers.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/test_msgpack.py +0 -0
- {python3_commons-0.16.7 → python3_commons-0.17.0}/tests/unit/test_msgspec.py +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python3-commons
|
|
3
|
+
Version: 0.17.0
|
|
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,database,object-storage,valkey]; 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
|
|
@@ -16,20 +16,41 @@ classifiers = [
|
|
|
16
16
|
"Programming Language :: Python"
|
|
17
17
|
]
|
|
18
18
|
keywords = []
|
|
19
|
-
requires-python = ">=3.14.
|
|
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,database,object-storage,valkey]"
|
|
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
|
|
@@ -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
|
|
@@ -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
|
|
@@ -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
|
|
|
@@ -71,7 +71,7 @@ class JSONFormatter(logging.Formatter):
|
|
|
71
71
|
message = str(record.msg)
|
|
72
72
|
|
|
73
73
|
timestamp = datetime.fromtimestamp(record.created, UTC).isoformat().replace('+00:00', 'Z')
|
|
74
|
-
|
|
74
|
+
log_dict: dict[str, Any] = {
|
|
75
75
|
'message': message,
|
|
76
76
|
'level': record.levelname,
|
|
77
77
|
'logger': record.name,
|
|
@@ -81,8 +81,8 @@ class JSONFormatter(logging.Formatter):
|
|
|
81
81
|
if (exc_info := record.exc_info) and exc_info[0] is not None:
|
|
82
82
|
exc_type, exc_value, exc_tb = exc_info
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
log_dict['exc_type'] = f'{exc_type.__module__}.{exc_type.__qualname__}'
|
|
85
|
+
log_dict['exc_value'] = str(exc_value)
|
|
86
86
|
|
|
87
87
|
tb = ''.join(traceback.format_exception(exc_type, exc_value, exc_tb)).rstrip()
|
|
88
88
|
cap = self._max_tb_chars
|
|
@@ -90,18 +90,19 @@ class JSONFormatter(logging.Formatter):
|
|
|
90
90
|
if cap and len(tb) > cap:
|
|
91
91
|
tb = tb[:cap] + '\n... <truncated>'
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
log_dict['exc_traceback'] = tb
|
|
94
94
|
|
|
95
95
|
record_dict = record.__dict__
|
|
96
96
|
std_log_fields = _STD_LOG_FIELDS
|
|
97
97
|
|
|
98
98
|
if len(record_dict) > len(std_log_fields):
|
|
99
99
|
normalize = _normalize
|
|
100
|
-
|
|
100
|
+
log_dict_set = log_dict.__setitem__
|
|
101
101
|
|
|
102
102
|
for k, v in record_dict.items():
|
|
103
103
|
if k[0] == '_' or k in std_log_fields:
|
|
104
104
|
continue
|
|
105
|
-
out_set(k, normalize(v))
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
log_dict_set(k, normalize(v))
|
|
107
|
+
|
|
108
|
+
return self._encoder.encode(log_dict).decode('utf-8')
|
|
@@ -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
|
|
@@ -132,7 +136,7 @@ async def list_objects(bucket_name: str, prefix: str, *, recursive: bool = True)
|
|
|
132
136
|
|
|
133
137
|
|
|
134
138
|
async def get_object_streams(
|
|
135
|
-
|
|
139
|
+
bucket_name: str, path: str, *, recursive: bool = True
|
|
136
140
|
) -> AsyncGenerator[tuple[str, datetime, StreamingBody]]:
|
|
137
141
|
async for obj in list_objects(bucket_name, path, recursive=recursive):
|
|
138
142
|
object_name = obj['Key']
|
|
@@ -143,7 +147,7 @@ async def get_object_streams(
|
|
|
143
147
|
|
|
144
148
|
|
|
145
149
|
async def get_objects(
|
|
146
|
-
|
|
150
|
+
bucket_name: str, path: str, *, recursive: bool = True
|
|
147
151
|
) -> AsyncGenerator[tuple[str, datetime, bytes]]:
|
|
148
152
|
async for object_name, last_modified, stream in get_object_streams(bucket_name, path, recursive=recursive):
|
|
149
153
|
data = await stream.read()
|
|
@@ -165,7 +169,7 @@ async def remove_object(bucket_name: str, object_name: str) -> None:
|
|
|
165
169
|
|
|
166
170
|
|
|
167
171
|
async def remove_objects(
|
|
168
|
-
|
|
172
|
+
bucket_name: str, prefix: str | None = None, object_names: Iterable[str] | None = None
|
|
169
173
|
) -> Sequence[Mapping] | None:
|
|
170
174
|
storage = ObjectStorage(s3_settings)
|
|
171
175
|
|
|
@@ -188,7 +192,7 @@ async def remove_objects(
|
|
|
188
192
|
chunk_size = 1000
|
|
189
193
|
|
|
190
194
|
for i in range(0, len(objects_to_delete), chunk_size):
|
|
191
|
-
chunk = objects_to_delete[i: i + chunk_size]
|
|
195
|
+
chunk = objects_to_delete[i : i + chunk_size]
|
|
192
196
|
|
|
193
197
|
response = await s3_client.delete_objects(Bucket=bucket_name, Delete={'Objects': chunk})
|
|
194
198
|
|
|
@@ -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.0
|
|
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,database,object-storage,valkey]; 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,database,object-storage,valkey]
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
version = 1
|
|
2
2
|
revision = 3
|
|
3
|
-
requires-python = "
|
|
3
|
+
requires-python = "==3.14.*"
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "aiobotocore"
|
|
@@ -229,25 +229,25 @@ wheels = [
|
|
|
229
229
|
|
|
230
230
|
[[package]]
|
|
231
231
|
name = "build"
|
|
232
|
-
version = "1.4.
|
|
232
|
+
version = "1.4.4"
|
|
233
233
|
source = { registry = "https://pypi.org/simple" }
|
|
234
234
|
dependencies = [
|
|
235
235
|
{ name = "colorama", marker = "os_name == 'nt'" },
|
|
236
236
|
{ name = "packaging" },
|
|
237
237
|
{ name = "pyproject-hooks" },
|
|
238
238
|
]
|
|
239
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
239
|
+
sdist = { url = "https://files.pythonhosted.org/packages/02/ec/bf5ae0a7e5ab57abe8aabdd0759c971883895d1a20c49ae99f8146840c3c/build-1.4.4.tar.gz", hash = "sha256:f832ae053061f3fb524af812dc94b8b84bac6880cd587630e3b5d91a6a9c1703", size = 89220, upload-time = "2026-04-22T20:53:44.807Z" }
|
|
240
240
|
wheels = [
|
|
241
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
241
|
+
{ url = "https://files.pythonhosted.org/packages/fa/88/6764e7a109dd84294850741501145da90d13cdeac9d4e614929464a37420/build-1.4.4-py3-none-any.whl", hash = "sha256:8c3f48a6090b39edec1a273d2d57949aaf13723b01e02f9d518396887519f64d", size = 25921, upload-time = "2026-04-22T20:53:43.251Z" },
|
|
242
242
|
]
|
|
243
243
|
|
|
244
244
|
[[package]]
|
|
245
245
|
name = "certifi"
|
|
246
|
-
version = "2026.
|
|
246
|
+
version = "2026.4.22"
|
|
247
247
|
source = { registry = "https://pypi.org/simple" }
|
|
248
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
248
|
+
sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" }
|
|
249
249
|
wheels = [
|
|
250
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
250
|
+
{ url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" },
|
|
251
251
|
]
|
|
252
252
|
|
|
253
253
|
[[package]]
|
|
@@ -478,11 +478,11 @@ wheels = [
|
|
|
478
478
|
|
|
479
479
|
[[package]]
|
|
480
480
|
name = "idna"
|
|
481
|
-
version = "3.
|
|
481
|
+
version = "3.13"
|
|
482
482
|
source = { registry = "https://pypi.org/simple" }
|
|
483
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
483
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" }
|
|
484
484
|
wheels = [
|
|
485
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
485
|
+
{ url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" },
|
|
486
486
|
]
|
|
487
487
|
|
|
488
488
|
[[package]]
|
|
@@ -992,17 +992,43 @@ 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" },
|
|
1005
|
+
{ name = "object-storage-client" },
|
|
1006
|
+
{ name = "sqlalchemy", extra = ["asyncio"] },
|
|
1007
|
+
]
|
|
1008
|
+
api-client = [
|
|
1009
|
+
{ name = "aiobotocore" },
|
|
1010
|
+
{ name = "aiohttp", extra = ["speedups"] },
|
|
998
1011
|
{ name = "lxml" },
|
|
999
|
-
{ name = "msgpack" },
|
|
1000
|
-
{ name = "msgspec" },
|
|
1001
1012
|
{ name = "object-storage-client" },
|
|
1002
|
-
{ name = "
|
|
1013
|
+
{ name = "zeep" },
|
|
1014
|
+
]
|
|
1015
|
+
authn = [
|
|
1016
|
+
{ name = "aiohttp", extra = ["speedups"] },
|
|
1017
|
+
]
|
|
1018
|
+
authz = [
|
|
1019
|
+
{ name = "asyncpg" },
|
|
1003
1020
|
{ name = "sqlalchemy", extra = ["asyncio"] },
|
|
1021
|
+
]
|
|
1022
|
+
cache = [
|
|
1004
1023
|
{ name = "valkey", extra = ["libvalkey"] },
|
|
1005
|
-
|
|
1024
|
+
]
|
|
1025
|
+
database = [
|
|
1026
|
+
{ name = "asyncpg" },
|
|
1027
|
+
{ name = "sqlalchemy", extra = ["asyncio"] },
|
|
1028
|
+
]
|
|
1029
|
+
object-storage = [
|
|
1030
|
+
{ name = "aiobotocore" },
|
|
1031
|
+
{ name = "object-storage-client" },
|
|
1006
1032
|
]
|
|
1007
1033
|
|
|
1008
1034
|
[package.dev-dependencies]
|
|
@@ -1024,18 +1050,23 @@ testing = [
|
|
|
1024
1050
|
|
|
1025
1051
|
[package.metadata]
|
|
1026
1052
|
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 = "
|
|
1053
|
+
{ name = "aiobotocore", marker = "extra == 'object-storage'", specifier = "~=3.5.0" },
|
|
1054
|
+
{ name = "aiohttp", extras = ["speedups"], marker = "extra == 'api-client'", specifier = ">=3.13.5,<3.15.0" },
|
|
1055
|
+
{ name = "aiohttp", extras = ["speedups"], marker = "extra == 'authn'", specifier = ">=3.13.5,<3.15.0" },
|
|
1056
|
+
{ name = "asyncpg", marker = "extra == 'database'", specifier = "~=0.31.0" },
|
|
1057
|
+
{ name = "lxml", marker = "extra == 'api-client'", specifier = "~=6.1.0" },
|
|
1031
1058
|
{ name = "msgpack", specifier = "~=1.1.2" },
|
|
1032
1059
|
{ name = "msgspec", specifier = "==0.21.1" },
|
|
1033
|
-
{ name = "object-storage-client", specifier = "==0.0.22" },
|
|
1060
|
+
{ name = "object-storage-client", marker = "extra == 'object-storage'", specifier = "==0.0.22" },
|
|
1034
1061
|
{ name = "pydantic-settings", specifier = "~=2.14.0" },
|
|
1035
|
-
{ name = "
|
|
1036
|
-
{ name = "
|
|
1037
|
-
{ name = "
|
|
1062
|
+
{ name = "python3-commons", extras = ["audit", "authn", "authz", "database", "object-storage", "valkey"], marker = "extra == 'all'" },
|
|
1063
|
+
{ name = "python3-commons", extras = ["database"], marker = "extra == 'authz'" },
|
|
1064
|
+
{ name = "python3-commons", extras = ["object-storage"], marker = "extra == 'api-client'" },
|
|
1065
|
+
{ name = "sqlalchemy", extras = ["asyncio"], marker = "extra == 'database'", specifier = "~=2.0.49" },
|
|
1066
|
+
{ name = "valkey", extras = ["libvalkey"], marker = "extra == 'cache'", specifier = "~=6.1.1" },
|
|
1067
|
+
{ name = "zeep", marker = "extra == 'api-client'", specifier = "~=4.3.2" },
|
|
1038
1068
|
]
|
|
1069
|
+
provides-extras = ["all", "api-client", "authn", "authz", "cache", "database", "object-storage"]
|
|
1039
1070
|
|
|
1040
1071
|
[package.metadata.requires-dev]
|
|
1041
1072
|
dev = [
|
|
@@ -1193,14 +1224,14 @@ asyncio = [
|
|
|
1193
1224
|
|
|
1194
1225
|
[[package]]
|
|
1195
1226
|
name = "types-aiobotocore"
|
|
1196
|
-
version = "3.
|
|
1227
|
+
version = "3.5.0"
|
|
1197
1228
|
source = { registry = "https://pypi.org/simple" }
|
|
1198
1229
|
dependencies = [
|
|
1199
1230
|
{ name = "botocore-stubs" },
|
|
1200
1231
|
]
|
|
1201
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1232
|
+
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
1233
|
wheels = [
|
|
1203
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1234
|
+
{ 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
1235
|
]
|
|
1205
1236
|
|
|
1206
1237
|
[package.optional-dependencies]
|
|
@@ -1210,11 +1241,11 @@ s3 = [
|
|
|
1210
1241
|
|
|
1211
1242
|
[[package]]
|
|
1212
1243
|
name = "types-aiobotocore-s3"
|
|
1213
|
-
version = "3.
|
|
1244
|
+
version = "3.5.0"
|
|
1214
1245
|
source = { registry = "https://pypi.org/simple" }
|
|
1215
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1246
|
+
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
1247
|
wheels = [
|
|
1217
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1248
|
+
{ 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
1249
|
]
|
|
1219
1250
|
|
|
1220
1251
|
[[package]]
|
|
@@ -1299,14 +1330,14 @@ wheels = [
|
|
|
1299
1330
|
|
|
1300
1331
|
[[package]]
|
|
1301
1332
|
name = "wheel"
|
|
1302
|
-
version = "0.
|
|
1333
|
+
version = "0.47.0"
|
|
1303
1334
|
source = { registry = "https://pypi.org/simple" }
|
|
1304
1335
|
dependencies = [
|
|
1305
1336
|
{ name = "packaging" },
|
|
1306
1337
|
]
|
|
1307
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1338
|
+
sdist = { url = "https://files.pythonhosted.org/packages/39/62/75f18a0f03b4219c456652c7780e4d749b929eb605c098ce3a5b6b6bc081/wheel-0.47.0.tar.gz", hash = "sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3", size = 63854, upload-time = "2026-04-22T15:51:27.727Z" }
|
|
1308
1339
|
wheels = [
|
|
1309
|
-
{ url = "https://files.pythonhosted.org/packages/87/
|
|
1340
|
+
{ url = "https://files.pythonhosted.org/packages/87/1b/9e33c09813d65e248f7f773119148a612516a4bea93e9c6f545f78455b7c/wheel-0.47.0-py3-none-any.whl", hash = "sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced", size = 32218, upload-time = "2026-04-22T15:51:26.296Z" },
|
|
1310
1341
|
]
|
|
1311
1342
|
|
|
1312
1343
|
[[package]]
|
python3_commons-0.16.7/PKG-INFO
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: python3-commons
|
|
3
|
-
Version: 0.16.7
|
|
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.4
|
|
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.7
|
|
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.4
|
|
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.7 → python3_commons-0.17.0}/src/python3_commons/serializers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/msgpack.py
RENAMED
|
File without changes
|
{python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons/serializers/msgspec.py
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.16.7 → python3_commons-0.17.0}/src/python3_commons.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{python3_commons-0.16.7 → python3_commons-0.17.0}/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
|