python3-commons 0.5.18__tar.gz → 0.5.20__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.

Files changed (48) hide show
  1. {python3_commons-0.5.18/src/python3_commons.egg-info → python3_commons-0.5.20}/PKG-INFO +2 -2
  2. {python3_commons-0.5.18 → python3_commons-0.5.20}/requirements.txt +1 -1
  3. {python3_commons-0.5.18 → python3_commons-0.5.20}/setup.cfg +2 -2
  4. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/audit.py +14 -1
  5. {python3_commons-0.5.18 → python3_commons-0.5.20/src/python3_commons.egg-info}/PKG-INFO +2 -2
  6. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons.egg-info/SOURCES.txt +1 -1
  7. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons.egg-info/requires.txt +1 -1
  8. {python3_commons-0.5.18 → python3_commons-0.5.20}/tests/test_audit.py +7 -5
  9. python3_commons-0.5.20/tests/test_helpers.py +10 -0
  10. python3_commons-0.5.18/src/python3_commons/stream_tar.py +0 -105
  11. {python3_commons-0.5.18 → python3_commons-0.5.20}/.coveragerc +0 -0
  12. {python3_commons-0.5.18 → python3_commons-0.5.20}/.github/workflows/python-publish.yaml +0 -0
  13. {python3_commons-0.5.18 → python3_commons-0.5.20}/.gitignore +0 -0
  14. {python3_commons-0.5.18 → python3_commons-0.5.20}/AUTHORS.rst +0 -0
  15. {python3_commons-0.5.18 → python3_commons-0.5.20}/CHANGELOG.rst +0 -0
  16. {python3_commons-0.5.18 → python3_commons-0.5.20}/LICENSE +0 -0
  17. {python3_commons-0.5.18 → python3_commons-0.5.20}/README.md +0 -0
  18. {python3_commons-0.5.18 → python3_commons-0.5.20}/README.rst +0 -0
  19. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/Makefile +0 -0
  20. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/_static/.gitignore +0 -0
  21. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/authors.rst +0 -0
  22. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/changelog.rst +0 -0
  23. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/conf.py +0 -0
  24. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/index.rst +0 -0
  25. {python3_commons-0.5.18 → python3_commons-0.5.20}/docs/license.rst +0 -0
  26. {python3_commons-0.5.18 → python3_commons-0.5.20}/pyproject.toml +0 -0
  27. {python3_commons-0.5.18 → python3_commons-0.5.20}/requirements_dev.txt +0 -0
  28. {python3_commons-0.5.18 → python3_commons-0.5.20}/requirements_test.txt +0 -0
  29. {python3_commons-0.5.18 → python3_commons-0.5.20}/setup.py +0 -0
  30. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/__init__.py +0 -0
  31. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/conf.py +0 -0
  32. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/db.py +0 -0
  33. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/fs.py +0 -0
  34. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/helpers.py +0 -0
  35. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/logging/__init__.py +0 -0
  36. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/logging/filters.py +0 -0
  37. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/logging/formatter.py +0 -0
  38. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/object_storage.py +0 -0
  39. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/serializers/__init__.py +0 -0
  40. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/serializers/json.py +0 -0
  41. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/serializers/msgpack.py +0 -0
  42. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons/serializers/msgspec.py +0 -0
  43. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons.egg-info/dependency_links.txt +0 -0
  44. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons.egg-info/not-zip-safe +0 -0
  45. {python3_commons-0.5.18 → python3_commons-0.5.20}/src/python3_commons.egg-info/top_level.txt +0 -0
  46. {python3_commons-0.5.18 → python3_commons-0.5.20}/tests/conftest.py +0 -0
  47. {python3_commons-0.5.18 → python3_commons-0.5.20}/tests/test_msgpack.py +0 -0
  48. {python3_commons-0.5.18 → python3_commons-0.5.20}/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.18
3
+ Version: 0.5.20
4
4
  Summary: Re-usable Python3 code
5
5
  Home-page: https://github.com/kamikaze/python3-commons
6
6
  Author: Oleg Korsak
@@ -20,7 +20,7 @@ Requires-Dist: minio==7.2.7
20
20
  Requires-Dist: msgpack==1.0.8
21
21
  Requires-Dist: msgspec==0.18.6
22
22
  Requires-Dist: pydantic[email]==2.8.2
23
- Requires-Dist: pydantic-settings==2.3.4
23
+ Requires-Dist: pydantic-settings==2.4.0
24
24
  Requires-Dist: zeep==4.2.1
25
25
  Provides-Extra: testing
26
26
  Requires-Dist: pytest; extra == "testing"
@@ -4,5 +4,5 @@ minio==7.2.7
4
4
  msgpack==1.0.8
5
5
  msgspec==0.18.6
6
6
  pydantic[email]==2.8.2
7
- pydantic-settings==2.3.4
7
+ pydantic-settings==2.4.0
8
8
  zeep==4.2.1
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = python3-commons
3
- version = 0.5.16
3
+ version = 0.5.19
4
4
  description = Re-usable Python3 code
5
5
  author = Oleg Korsak
6
6
  author_email = kamikaze.is.waiting.you@gmail.com
@@ -29,7 +29,7 @@ install_requires =
29
29
  msgpack==1.0.8
30
30
  msgspec==0.18.6
31
31
  pydantic[email]==2.8.2
32
- pydantic-settings==2.3.4
32
+ pydantic-settings==2.4.0
33
33
  zeep==4.2.1
34
34
  python_requires = >=3.12
35
35
 
@@ -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
- archive_stream = GeneratedStream(generator)
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.18
3
+ Version: 0.5.20
4
4
  Summary: Re-usable Python3 code
5
5
  Home-page: https://github.com/kamikaze/python3-commons
6
6
  Author: Oleg Korsak
@@ -20,7 +20,7 @@ Requires-Dist: minio==7.2.7
20
20
  Requires-Dist: msgpack==1.0.8
21
21
  Requires-Dist: msgspec==0.18.6
22
22
  Requires-Dist: pydantic[email]==2.8.2
23
- Requires-Dist: pydantic-settings==2.3.4
23
+ Requires-Dist: pydantic-settings==2.4.0
24
24
  Requires-Dist: zeep==4.2.1
25
25
  Provides-Extra: testing
26
26
  Requires-Dist: pytest; extra == "testing"
@@ -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
@@ -4,7 +4,7 @@ minio==7.2.7
4
4
  msgpack==1.0.8
5
5
  msgspec==0.18.6
6
6
  pydantic[email]==2.8.2
7
- pydantic-settings==2.3.4
7
+ pydantic-settings==2.4.0
8
8
  zeep==4.2.1
9
9
 
10
10
  [testing]
@@ -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
- archive_stream = GeneratedStream(generator)
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
- archive_stream = GeneratedStream(generator)
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)