python3-commons 0.5.8__tar.gz → 0.5.10__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.5.8/src/python3_commons.egg-info → python3_commons-0.5.10}/PKG-INFO +1 -1
- {python3_commons-0.5.8 → python3_commons-0.5.10}/setup.cfg +1 -1
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/audit.py +71 -20
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/object_storage.py +2 -2
- {python3_commons-0.5.8 → python3_commons-0.5.10/src/python3_commons.egg-info}/PKG-INFO +1 -1
- {python3_commons-0.5.8 → python3_commons-0.5.10}/.coveragerc +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/.gitignore +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/AUTHORS.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/CHANGELOG.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/LICENSE +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/README.md +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/README.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/Makefile +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/_static/.gitignore +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/authors.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/changelog.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/conf.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/index.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/docs/license.rst +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/pyproject.toml +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/requirements.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/requirements_dev.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/requirements_test.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/setup.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/conf.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/db.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/helpers.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/logging/__init__.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/logging/filters.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/logging/formatter.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/serializers/json.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/serializers/msgpack.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons/serializers/msgspec.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons.egg-info/SOURCES.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons.egg-info/not-zip-safe +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons.egg-info/requires.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/tests/conftest.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/tests/test_msgpack.py +0 -0
- {python3_commons-0.5.8 → python3_commons-0.5.10}/tests/test_msgspec.py +0 -0
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
import tarfile
|
|
5
5
|
from datetime import datetime, timedelta, UTC
|
|
6
6
|
from io import BytesIO
|
|
7
|
+
from typing import Generator
|
|
7
8
|
from uuid import uuid4
|
|
8
9
|
|
|
9
10
|
from lxml import etree
|
|
@@ -18,6 +19,70 @@ from python3_commons.object_storage import get_s3_client
|
|
|
18
19
|
logger = logging.getLogger(__name__)
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
class BytesIOStream(io.BytesIO):
|
|
23
|
+
def __init__(self, generator: Generator[bytes, None, None], *args, **kwargs):
|
|
24
|
+
super().__init__(*args, **kwargs)
|
|
25
|
+
self.generator = generator
|
|
26
|
+
|
|
27
|
+
def read(self, size: int = -1):
|
|
28
|
+
if size == -1:
|
|
29
|
+
size = 4096
|
|
30
|
+
|
|
31
|
+
while self.tell() < size:
|
|
32
|
+
try:
|
|
33
|
+
chunk = next(self.generator)
|
|
34
|
+
except StopIteration:
|
|
35
|
+
break
|
|
36
|
+
|
|
37
|
+
self.write(chunk)
|
|
38
|
+
|
|
39
|
+
if chunk := self.read(size):
|
|
40
|
+
pos = self.tell()
|
|
41
|
+
|
|
42
|
+
buf = self.getbuffer()
|
|
43
|
+
unread_data_size = len(buf) - pos
|
|
44
|
+
|
|
45
|
+
if unread_data_size > 0:
|
|
46
|
+
buf[:unread_data_size] = buf[pos:pos+unread_data_size]
|
|
47
|
+
|
|
48
|
+
self.seek(0)
|
|
49
|
+
self.truncate(unread_data_size)
|
|
50
|
+
|
|
51
|
+
return chunk
|
|
52
|
+
|
|
53
|
+
def readable(self):
|
|
54
|
+
return True
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def generate_archive(bucket_name: str, date_path: str, chunk_size: int = 4096) -> Generator[bytes, None, None]:
|
|
58
|
+
buffer = io.BytesIO()
|
|
59
|
+
|
|
60
|
+
with tarfile.open(fileobj=buffer, mode='w|bz2') as archive:
|
|
61
|
+
objects = object_storage.get_objects(bucket_name, date_path, recursive=True)
|
|
62
|
+
|
|
63
|
+
if objects:
|
|
64
|
+
logger.info(f'Compacting files in: {date_path}')
|
|
65
|
+
|
|
66
|
+
for name, last_modified, content in objects:
|
|
67
|
+
logger.info(f'Adding {name} to archive')
|
|
68
|
+
info = tarfile.TarInfo(name)
|
|
69
|
+
info.size = len(content)
|
|
70
|
+
info.mtime = last_modified.timestamp()
|
|
71
|
+
archive.addfile(info, io.BytesIO(content))
|
|
72
|
+
buffer.seek(0)
|
|
73
|
+
|
|
74
|
+
while True:
|
|
75
|
+
chunk = buffer.read(chunk_size)
|
|
76
|
+
|
|
77
|
+
if not chunk:
|
|
78
|
+
break
|
|
79
|
+
|
|
80
|
+
yield chunk
|
|
81
|
+
|
|
82
|
+
buffer.seek(0)
|
|
83
|
+
buffer.truncate(0)
|
|
84
|
+
|
|
85
|
+
|
|
21
86
|
def write_audit_data_sync(settings: S3Settings, key: str, data: bytes):
|
|
22
87
|
if settings.s3_secret_access_key:
|
|
23
88
|
try:
|
|
@@ -43,27 +108,15 @@ async def archive_audit_data(root_path: str = 'audit'):
|
|
|
43
108
|
month = now.month
|
|
44
109
|
day = now.day
|
|
45
110
|
bucket_name = s3_settings.s3_bucket
|
|
46
|
-
fo = BytesIO()
|
|
47
111
|
object_names = []
|
|
48
112
|
date_path = object_storage.get_absolute_path(f'{root_path}/{year}/{month:02}/{day:02}')
|
|
49
113
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
logger.info(f'Compacting files in: {date_path}')
|
|
53
|
-
|
|
54
|
-
for name, last_modified, content in objects:
|
|
55
|
-
info = tarfile.TarInfo(name)
|
|
56
|
-
info.size = len(content)
|
|
57
|
-
info.mtime = last_modified.timestamp()
|
|
58
|
-
archive.addfile(info, BytesIO(content))
|
|
59
|
-
object_names.append(name)
|
|
60
|
-
|
|
61
|
-
fo.seek(0)
|
|
114
|
+
generator = generate_archive(bucket_name, date_path, chunk_size=4096)
|
|
115
|
+
archive_stream = BytesIOStream(generator)
|
|
62
116
|
|
|
63
117
|
if object_names:
|
|
64
|
-
archive_path = object_storage.get_absolute_path(
|
|
65
|
-
|
|
66
|
-
object_storage.put_object(bucket_name, archive_path, fo, fo.getbuffer().nbytes)
|
|
118
|
+
archive_path = object_storage.get_absolute_path(f'audit/.archive/{year}_{month:02}_{day:02}.tar.bz2')
|
|
119
|
+
object_storage.put_object(bucket_name, archive_path, archive_stream, -1, part_size=4096)
|
|
67
120
|
|
|
68
121
|
if errors := object_storage.remove_objects(bucket_name, object_names=object_names):
|
|
69
122
|
for error in errors:
|
|
@@ -82,10 +135,8 @@ class ZeepAuditPlugin(Plugin):
|
|
|
82
135
|
now = datetime.now(tz=UTC)
|
|
83
136
|
date_path = now.strftime('%Y/%m/%d')
|
|
84
137
|
timestamp = now.strftime('%H%M%S')
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
f'{date_path}/{self.audit_name}/{operation.name}/{timestamp}_{str(uuid4())[-12:]}_{direction}.xml', xml
|
|
88
|
-
)
|
|
138
|
+
path = f'{date_path}/{self.audit_name}/{operation.name}/{timestamp}_{str(uuid4())[-12:]}_{direction}.xml'
|
|
139
|
+
coro = write_audit_data(s3_settings, path, xml)
|
|
89
140
|
|
|
90
141
|
try:
|
|
91
142
|
loop = asyncio.get_running_loop()
|
|
@@ -39,11 +39,11 @@ def get_absolute_path(path: str) -> str:
|
|
|
39
39
|
return path
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def put_object(bucket_name: str, path: str, data: io.BytesIO, length: int) -> str:
|
|
42
|
+
def put_object(bucket_name: str, path: str, data: io.BytesIO, length: int, part_size: int = 0) -> str:
|
|
43
43
|
s3_client = get_s3_client(s3_settings)
|
|
44
44
|
|
|
45
45
|
if s3_client:
|
|
46
|
-
result = s3_client.put_object(bucket_name, path, data, length)
|
|
46
|
+
result = s3_client.put_object(bucket_name, path, data, length, part_size=part_size)
|
|
47
47
|
|
|
48
48
|
logger.debug(f'Stored object into object storage: {bucket_name}:{path}')
|
|
49
49
|
|
|
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.5.8 → python3_commons-0.5.10}/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.5.8 → python3_commons-0.5.10}/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
|