python3-commons 0.5.19__tar.gz → 0.5.21__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.19/src/python3_commons.egg-info → python3_commons-0.5.21}/PKG-INFO +2 -2
- {python3_commons-0.5.19 → python3_commons-0.5.21}/requirements.txt +1 -1
- {python3_commons-0.5.19 → python3_commons-0.5.21}/setup.cfg +1 -1
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/audit.py +14 -1
- {python3_commons-0.5.19 → python3_commons-0.5.21/src/python3_commons.egg-info}/PKG-INFO +2 -2
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/SOURCES.txt +1 -1
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/requires.txt +1 -1
- {python3_commons-0.5.19 → python3_commons-0.5.21}/tests/test_audit.py +7 -5
- python3_commons-0.5.21/tests/test_helpers.py +10 -0
- python3_commons-0.5.19/src/python3_commons/stream_tar.py +0 -105
- {python3_commons-0.5.19 → python3_commons-0.5.21}/.coveragerc +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/.gitignore +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/AUTHORS.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/CHANGELOG.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/LICENSE +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/README.md +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/README.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/Makefile +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/_static/.gitignore +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/authors.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/changelog.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/conf.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/index.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/docs/license.rst +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/pyproject.toml +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/requirements_dev.txt +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/requirements_test.txt +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/setup.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/conf.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/db.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/helpers.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/logging/__init__.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/logging/filters.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/logging/formatter.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/object_storage.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/serializers/json.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/serializers/msgpack.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/serializers/msgspec.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/not-zip-safe +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/tests/conftest.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/tests/test_msgpack.py +0 -0
- {python3_commons-0.5.19 → python3_commons-0.5.21}/tests/test_msgspec.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python3-commons
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.21
|
|
4
4
|
Summary: Re-usable Python3 code
|
|
5
5
|
Home-page: https://github.com/kamikaze/python3-commons
|
|
6
6
|
Author: Oleg Korsak
|
|
@@ -15,7 +15,7 @@ Description-Content-Type: text/x-rst; charset=UTF-8
|
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
License-File: AUTHORS.rst
|
|
17
17
|
Requires-Dist: asyncpg==0.29.0
|
|
18
|
-
Requires-Dist: lxml==5.
|
|
18
|
+
Requires-Dist: lxml==5.3.0
|
|
19
19
|
Requires-Dist: minio==7.2.7
|
|
20
20
|
Requires-Dist: msgpack==1.0.8
|
|
21
21
|
Requires-Dist: msgspec==0.18.6
|
|
@@ -2,6 +2,7 @@ import asyncio
|
|
|
2
2
|
import io
|
|
3
3
|
import logging
|
|
4
4
|
import tarfile
|
|
5
|
+
from bz2 import BZ2Compressor
|
|
5
6
|
from datetime import datetime, timedelta, UTC
|
|
6
7
|
from typing import Generator, Iterable
|
|
7
8
|
from uuid import uuid4
|
|
@@ -92,6 +93,17 @@ def generate_archive(objects: Iterable[tuple[str, datetime, bytes]],
|
|
|
92
93
|
buffer.truncate(0)
|
|
93
94
|
|
|
94
95
|
|
|
96
|
+
def generate_bzip2(chunks: Generator[bytes, None, None]) -> Generator[bytes, None, None]:
|
|
97
|
+
compressor = BZ2Compressor()
|
|
98
|
+
|
|
99
|
+
for chunk in chunks:
|
|
100
|
+
if compressed_chunk := compressor.compress(chunk):
|
|
101
|
+
yield compressed_chunk
|
|
102
|
+
|
|
103
|
+
if compressed_chunk := compressor.flush():
|
|
104
|
+
yield compressed_chunk
|
|
105
|
+
|
|
106
|
+
|
|
95
107
|
def write_audit_data_sync(settings: S3Settings, key: str, data: bytes):
|
|
96
108
|
if settings.s3_secret_access_key:
|
|
97
109
|
try:
|
|
@@ -123,7 +135,8 @@ async def archive_audit_data(root_path: str = 'audit'):
|
|
|
123
135
|
logger.info(f'Compacting files in: {date_path}')
|
|
124
136
|
|
|
125
137
|
generator = generate_archive(objects, chunk_size=5*1024*1024)
|
|
126
|
-
|
|
138
|
+
bzip2_generator = generate_bzip2(generator)
|
|
139
|
+
archive_stream = GeneratedStream(bzip2_generator)
|
|
127
140
|
|
|
128
141
|
archive_path = object_storage.get_absolute_path(f'audit/.archive/{year}_{month:02}_{day:02}.tar.bz2')
|
|
129
142
|
object_storage.put_object(bucket_name, archive_path, archive_stream, -1, part_size=5*1024*1024)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python3-commons
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.21
|
|
4
4
|
Summary: Re-usable Python3 code
|
|
5
5
|
Home-page: https://github.com/kamikaze/python3-commons
|
|
6
6
|
Author: Oleg Korsak
|
|
@@ -15,7 +15,7 @@ Description-Content-Type: text/x-rst; charset=UTF-8
|
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
License-File: AUTHORS.rst
|
|
17
17
|
Requires-Dist: asyncpg==0.29.0
|
|
18
|
-
Requires-Dist: lxml==5.
|
|
18
|
+
Requires-Dist: lxml==5.3.0
|
|
19
19
|
Requires-Dist: minio==7.2.7
|
|
20
20
|
Requires-Dist: msgpack==1.0.8
|
|
21
21
|
Requires-Dist: msgspec==0.18.6
|
|
@@ -26,7 +26,6 @@ src/python3_commons/db.py
|
|
|
26
26
|
src/python3_commons/fs.py
|
|
27
27
|
src/python3_commons/helpers.py
|
|
28
28
|
src/python3_commons/object_storage.py
|
|
29
|
-
src/python3_commons/stream_tar.py
|
|
30
29
|
src/python3_commons.egg-info/PKG-INFO
|
|
31
30
|
src/python3_commons.egg-info/SOURCES.txt
|
|
32
31
|
src/python3_commons.egg-info/dependency_links.txt
|
|
@@ -42,5 +41,6 @@ src/python3_commons/serializers/msgpack.py
|
|
|
42
41
|
src/python3_commons/serializers/msgspec.py
|
|
43
42
|
tests/conftest.py
|
|
44
43
|
tests/test_audit.py
|
|
44
|
+
tests/test_helpers.py
|
|
45
45
|
tests/test_msgpack.py
|
|
46
46
|
tests/test_msgspec.py
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from io import BytesIO
|
|
2
2
|
|
|
3
|
-
from python3_commons.audit import GeneratedStream, generate_archive
|
|
3
|
+
from python3_commons.audit import GeneratedStream, generate_archive, generate_bzip2
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def test_generated_stream(s3_file_objects):
|
|
7
7
|
expected_data = b''
|
|
8
8
|
generator = generate_archive(s3_file_objects, chunk_size=5 * 1024 * 1024)
|
|
9
|
-
|
|
9
|
+
bzip2_generator = generate_bzip2(generator)
|
|
10
|
+
archive_stream = GeneratedStream(bzip2_generator)
|
|
10
11
|
archived_data = archive_stream.read()
|
|
11
12
|
|
|
12
|
-
with open('/tmp/test.tar', 'wb') as f:
|
|
13
|
+
with open('/tmp/test.tar.bz2', 'wb') as f:
|
|
13
14
|
f.write(archived_data)
|
|
14
15
|
|
|
15
16
|
assert archived_data == expected_data
|
|
@@ -18,10 +19,11 @@ def test_generated_stream(s3_file_objects):
|
|
|
18
19
|
def test_generated_stream_by_chunks(s3_file_objects):
|
|
19
20
|
expected_data = b''
|
|
20
21
|
generator = generate_archive(s3_file_objects, chunk_size=2)
|
|
21
|
-
|
|
22
|
+
bzip2_generator = generate_bzip2(generator)
|
|
23
|
+
archive_stream = GeneratedStream(bzip2_generator)
|
|
22
24
|
archived_data = BytesIO()
|
|
23
25
|
|
|
24
|
-
with open('/tmp/test_chunked.tar', 'wb') as f:
|
|
26
|
+
with open('/tmp/test_chunked.tar.bz2', 'wb') as f:
|
|
25
27
|
while chunk := archive_stream.read(2):
|
|
26
28
|
f.write(chunk)
|
|
27
29
|
archived_data.write(chunk)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from python3_commons.helpers import date_range
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_date_range():
|
|
7
|
+
expected_dates = (date(2024, 1, 1), date(2024, 1, 2), date(2024, 1, 3), date(2024, 1, 4), date(2024, 1, 5))
|
|
8
|
+
dates = tuple(date_range(date(2024, 1, 1), date(2024, 1, 5)))
|
|
9
|
+
|
|
10
|
+
assert dates == expected_dates
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import os
|
|
3
|
-
import sys
|
|
4
|
-
import tarfile
|
|
5
|
-
from io import BytesIO
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger(__name__)
|
|
9
|
-
BLOCK_SIZE = 4096
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class FileStream(object):
|
|
13
|
-
def __init__(self):
|
|
14
|
-
self.buffer = BytesIO()
|
|
15
|
-
self.offset = 0
|
|
16
|
-
|
|
17
|
-
def write(self, chunk):
|
|
18
|
-
self.buffer.write(chunk)
|
|
19
|
-
self.offset += len(chunk)
|
|
20
|
-
|
|
21
|
-
def tell(self):
|
|
22
|
-
return self.offset
|
|
23
|
-
|
|
24
|
-
def close(self):
|
|
25
|
-
self.buffer.close()
|
|
26
|
-
|
|
27
|
-
def pop(self):
|
|
28
|
-
value = self.buffer.getvalue()
|
|
29
|
-
self.buffer.seek(0)
|
|
30
|
-
self.buffer.truncate()
|
|
31
|
-
|
|
32
|
-
return value
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def stream_build_tar(in_filename, streaming_fp):
|
|
36
|
-
tar = tarfile.TarFile.open('test.tar.gz', 'w|gz', streaming_fp)
|
|
37
|
-
|
|
38
|
-
stat = os.stat(in_filename)
|
|
39
|
-
|
|
40
|
-
tar_info = tarfile.TarInfo(in_filename)
|
|
41
|
-
|
|
42
|
-
# Note that you can get this information from the storage backend,
|
|
43
|
-
# but it's valid for either to raise a NotImplementedError, so it's
|
|
44
|
-
# important to check.
|
|
45
|
-
#
|
|
46
|
-
# Things like the mode or ownership won't be available.
|
|
47
|
-
tar_info.mtime = stat.st_mtime
|
|
48
|
-
tar_info.size = stat.st_size
|
|
49
|
-
|
|
50
|
-
# Note that we don't pass a fileobj, so we don't write any data
|
|
51
|
-
# through addfile. We'll do this ourselves.
|
|
52
|
-
tar.addfile(tar_info)
|
|
53
|
-
|
|
54
|
-
yield
|
|
55
|
-
|
|
56
|
-
with open(in_filename, 'rb') as in_fp:
|
|
57
|
-
total_size = 0
|
|
58
|
-
|
|
59
|
-
while True:
|
|
60
|
-
s = in_fp.read(BLOCK_SIZE)
|
|
61
|
-
|
|
62
|
-
if len(s) > 0:
|
|
63
|
-
tar.fileobj.write(s)
|
|
64
|
-
|
|
65
|
-
yield
|
|
66
|
-
|
|
67
|
-
if len(s) < BLOCK_SIZE:
|
|
68
|
-
blocks, remainder = divmod(tar_info.size, tarfile.BLOCKSIZE)
|
|
69
|
-
|
|
70
|
-
if remainder > 0:
|
|
71
|
-
tar.fileobj.write(tarfile.NUL *
|
|
72
|
-
(tarfile.BLOCKSIZE - remainder))
|
|
73
|
-
|
|
74
|
-
yield
|
|
75
|
-
|
|
76
|
-
blocks += 1
|
|
77
|
-
|
|
78
|
-
tar.offset += blocks * tarfile.BLOCKSIZE
|
|
79
|
-
break
|
|
80
|
-
|
|
81
|
-
tar.close()
|
|
82
|
-
|
|
83
|
-
yield
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def main():
|
|
87
|
-
if len(sys.argv) != 3:
|
|
88
|
-
print('Usage: %s in_filename out_filename' % sys.argv[0])
|
|
89
|
-
sys.exit(1)
|
|
90
|
-
|
|
91
|
-
in_filename = sys.argv[1]
|
|
92
|
-
out_filename = sys.argv[2]
|
|
93
|
-
|
|
94
|
-
streaming_fp = FileStream()
|
|
95
|
-
|
|
96
|
-
with open(out_filename, 'wb') as out_fp:
|
|
97
|
-
for i in stream_build_tar(in_filename, streaming_fp):
|
|
98
|
-
s = streaming_fp.pop()
|
|
99
|
-
|
|
100
|
-
if len(s) > 0:
|
|
101
|
-
print('Writing %d bytes...' % len(s))
|
|
102
|
-
out_fp.write(s)
|
|
103
|
-
out_fp.flush()
|
|
104
|
-
|
|
105
|
-
print('Wrote tar file to %s' % out_filename)
|
|
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.19 → python3_commons-0.5.21}/src/python3_commons/serializers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/serializers/msgpack.py
RENAMED
|
File without changes
|
{python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons/serializers/msgspec.py
RENAMED
|
File without changes
|
{python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.5.19 → python3_commons-0.5.21}/src/python3_commons.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|