python3-commons 0.8.36__tar.gz → 0.9.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.8.36/src/python3_commons.egg-info → python3_commons-0.9.1}/PKG-INFO +1 -1
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/audit.py +16 -23
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/conf.py +2 -2
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/object_storage.py +1 -1
- {python3_commons-0.8.36 → python3_commons-0.9.1/src/python3_commons.egg-info}/PKG-INFO +1 -1
- {python3_commons-0.8.36 → python3_commons-0.9.1}/.coveragerc +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/.github/workflows/release-on-tag-push.yml +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/.gitignore +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/.pre-commit-config.yaml +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/.python-version +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/AUTHORS.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/CHANGELOG.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/LICENSE +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/README.md +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/README.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/Makefile +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/_static/.gitignore +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/authors.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/changelog.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/conf.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/index.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/docs/license.rst +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/pyproject.toml +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/setup.cfg +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/api_client.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/auth.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/cache.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/db/__init__.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/db/helpers.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/db/models/__init__.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/db/models/auth.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/db/models/common.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/db/models/rbac.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/helpers.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/log/__init__.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/log/filters.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/log/formatters.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/permissions.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/serializers/json.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/serializers/msgpack.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/serializers/msgspec.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons.egg-info/SOURCES.txt +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons.egg-info/requires.txt +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/tests/conftest.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/tests/test_audit.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/tests/test_cache.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/tests/test_helpers.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/tests/test_msgpack.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/tests/test_msgspec.py +0 -0
- {python3_commons-0.8.36 → python3_commons-0.9.1}/uv.lock +0 -0
@@ -5,23 +5,21 @@ import tarfile
|
|
5
5
|
from bz2 import BZ2Compressor
|
6
6
|
from collections import deque
|
7
7
|
from datetime import UTC, datetime, timedelta
|
8
|
-
from typing import
|
8
|
+
from typing import AsyncGenerator
|
9
9
|
from uuid import uuid4
|
10
10
|
|
11
11
|
from lxml import etree
|
12
|
-
from minio import S3Error
|
13
12
|
from zeep.plugins import Plugin
|
14
13
|
from zeep.wsdl.definitions import AbstractOperation
|
15
14
|
|
16
15
|
from python3_commons import object_storage
|
17
16
|
from python3_commons.conf import S3Settings, s3_settings
|
18
|
-
from python3_commons.object_storage import ObjectStorage
|
19
17
|
|
20
18
|
logger = logging.getLogger(__name__)
|
21
19
|
|
22
20
|
|
23
21
|
class GeneratedStream(io.BytesIO):
|
24
|
-
def __init__(self, generator:
|
22
|
+
def __init__(self, generator: AsyncGenerator[bytes], *args, **kwargs):
|
25
23
|
super().__init__(*args, **kwargs)
|
26
24
|
self.generator = generator
|
27
25
|
|
@@ -29,7 +27,7 @@ class GeneratedStream(io.BytesIO):
|
|
29
27
|
if size < 0:
|
30
28
|
while True:
|
31
29
|
try:
|
32
|
-
chunk =
|
30
|
+
chunk = anext(self.generator)
|
33
31
|
except StopIteration:
|
34
32
|
break
|
35
33
|
else:
|
@@ -39,7 +37,7 @@ class GeneratedStream(io.BytesIO):
|
|
39
37
|
|
40
38
|
while total_written_size < size:
|
41
39
|
try:
|
42
|
-
chunk =
|
40
|
+
chunk = anext(self.generator)
|
43
41
|
except StopIteration:
|
44
42
|
break
|
45
43
|
else:
|
@@ -67,17 +65,17 @@ class GeneratedStream(io.BytesIO):
|
|
67
65
|
return True
|
68
66
|
|
69
67
|
|
70
|
-
def generate_archive(
|
71
|
-
objects:
|
72
|
-
) ->
|
68
|
+
async def generate_archive(
|
69
|
+
objects: AsyncGenerator[tuple[str, datetime, bytes]], chunk_size: int = 4096
|
70
|
+
) -> AsyncGenerator[bytes]:
|
73
71
|
buffer = deque()
|
74
72
|
|
75
73
|
with tarfile.open(fileobj=buffer, mode='w') as archive:
|
76
|
-
for name, last_modified, content in objects:
|
74
|
+
async for name, last_modified, content in objects:
|
77
75
|
logger.info(f'Adding {name} to archive')
|
78
76
|
info = tarfile.TarInfo(name)
|
79
77
|
info.size = len(content)
|
80
|
-
info.mtime = last_modified.timestamp()
|
78
|
+
info.mtime = int(last_modified.timestamp())
|
81
79
|
archive.addfile(info, io.BytesIO(content))
|
82
80
|
|
83
81
|
buffer_length = buffer.tell()
|
@@ -109,10 +107,10 @@ def generate_archive(
|
|
109
107
|
buffer.truncate(0)
|
110
108
|
|
111
109
|
|
112
|
-
def generate_bzip2(chunks:
|
110
|
+
async def generate_bzip2(chunks: AsyncGenerator[bytes]) -> AsyncGenerator[bytes]:
|
113
111
|
compressor = BZ2Compressor()
|
114
112
|
|
115
|
-
for chunk in chunks:
|
113
|
+
async for chunk in chunks:
|
116
114
|
if compressed_chunk := compressor.compress(chunk):
|
117
115
|
yield compressed_chunk
|
118
116
|
|
@@ -120,14 +118,13 @@ def generate_bzip2(chunks: Generator[bytes, None, None]) -> Generator[bytes, Non
|
|
120
118
|
yield compressed_chunk
|
121
119
|
|
122
120
|
|
123
|
-
def
|
121
|
+
async def write_audit_data(settings: S3Settings, key: str, data: bytes):
|
124
122
|
if settings.s3_secret_access_key:
|
125
123
|
try:
|
126
|
-
client = ObjectStorage(settings).get_client()
|
127
124
|
absolute_path = object_storage.get_absolute_path(f'audit/{key}')
|
128
125
|
|
129
|
-
|
130
|
-
except
|
126
|
+
await object_storage.put_object(settings.s3_bucket, absolute_path, io.BytesIO(data), len(data))
|
127
|
+
except Exception as e:
|
131
128
|
logger.error(f'Failed storing object in storage: {e}')
|
132
129
|
else:
|
133
130
|
logger.debug(f'Stored object in storage: {key}')
|
@@ -135,10 +132,6 @@ def write_audit_data_sync(settings: S3Settings, key: str, data: bytes):
|
|
135
132
|
logger.debug(f'S3 is not configured, not storing object in storage: {key}')
|
136
133
|
|
137
134
|
|
138
|
-
async def write_audit_data(settings: S3Settings, key: str, data: bytes):
|
139
|
-
await asyncio.to_thread(write_audit_data_sync, settings, key, data)
|
140
|
-
|
141
|
-
|
142
135
|
async def archive_audit_data(root_path: str = 'audit'):
|
143
136
|
now = datetime.now(tz=UTC) - timedelta(days=1)
|
144
137
|
year = now.year
|
@@ -155,9 +148,9 @@ async def archive_audit_data(root_path: str = 'audit'):
|
|
155
148
|
archive_stream = GeneratedStream(bzip2_generator)
|
156
149
|
|
157
150
|
archive_path = object_storage.get_absolute_path(f'audit/.archive/{year}_{month:02}_{day:02}.tar.bz2')
|
158
|
-
object_storage.put_object(bucket_name, archive_path, archive_stream, -1, part_size=5 * 1024 * 1024)
|
151
|
+
await object_storage.put_object(bucket_name, archive_path, archive_stream, -1, part_size=5 * 1024 * 1024)
|
159
152
|
|
160
|
-
if errors := object_storage.remove_objects(bucket_name, date_path):
|
153
|
+
if errors := await object_storage.remove_objects(bucket_name, date_path):
|
161
154
|
for error in errors:
|
162
155
|
logger.error(f'Failed to delete object in {bucket_name=}: {error}')
|
163
156
|
|
@@ -64,8 +64,8 @@ class DBSettings(BaseSettings):
|
|
64
64
|
class S3Settings(BaseSettings):
|
65
65
|
s3_endpoint_url: str | None = None
|
66
66
|
s3_region_name: str | None = None
|
67
|
-
s3_access_key_id: SecretStr = ''
|
68
|
-
s3_secret_access_key: SecretStr = ''
|
67
|
+
s3_access_key_id: SecretStr = SecretStr('')
|
68
|
+
s3_secret_access_key: SecretStr = SecretStr('')
|
69
69
|
s3_secure: bool = True
|
70
70
|
s3_bucket: str | None = None
|
71
71
|
s3_bucket_root: str | None = None
|
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
|
File without changes
|
File without changes
|
{python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons/serializers/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{python3_commons-0.8.36 → python3_commons-0.9.1}/src/python3_commons.egg-info/dependency_links.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
|