csu 2.6.6__tar.gz → 2.6.7__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.
- {csu-2.6.6 → csu-2.6.7}/.bumpversion.cfg +1 -1
- {csu-2.6.6 → csu-2.6.7}/.cookiecutterrc +1 -1
- {csu-2.6.6 → csu-2.6.7}/PKG-INFO +3 -3
- {csu-2.6.6 → csu-2.6.7}/README.rst +2 -2
- {csu-2.6.6 → csu-2.6.7}/pyproject.toml +1 -1
- {csu-2.6.6 → csu-2.6.7}/src/csu/__init__.py +1 -1
- {csu-2.6.6 → csu-2.6.7}/src/csu/exceptions.py +37 -3
- {csu-2.6.6 → csu-2.6.7}/src/csu/service.py +3 -6
- {csu-2.6.6 → csu-2.6.7}/src/csu.egg-info/PKG-INFO +3 -3
- {csu-2.6.6 → csu-2.6.7}/tests/test_exceptions.py +14 -3
- {csu-2.6.6 → csu-2.6.7}/tests/test_service.py +64 -52
- {csu-2.6.6 → csu-2.6.7}/tests/test_service_auth.py +12 -12
- {csu-2.6.6 → csu-2.6.7}/tests/test_views.py +8 -8
- {csu-2.6.6 → csu-2.6.7}/.coveragerc +0 -0
- {csu-2.6.6 → csu-2.6.7}/.editorconfig +0 -0
- {csu-2.6.6 → csu-2.6.7}/.github/workflows/github-actions.yml +0 -0
- {csu-2.6.6 → csu-2.6.7}/.pre-commit-config.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/.tombi.toml +0 -0
- {csu-2.6.6 → csu-2.6.7}/AUTHORS.rst +0 -0
- {csu-2.6.6 → csu-2.6.7}/CHANGELOG.rst +0 -0
- {csu-2.6.6 → csu-2.6.7}/CONTRIBUTING.rst +0 -0
- {csu-2.6.6 → csu-2.6.7}/LICENSE +0 -0
- {csu-2.6.6 → csu-2.6.7}/MANIFEST.in +0 -0
- {csu-2.6.6 → csu-2.6.7}/ci/bootstrap.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/ci/requirements.txt +0 -0
- {csu-2.6.6 → csu-2.6.7}/ci/templates/.github/workflows/github-actions.yml +0 -0
- {csu-2.6.6 → csu-2.6.7}/pytest.ini +0 -0
- {csu-2.6.6 → csu-2.6.7}/setup.cfg +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/admin.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/conf.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/consts.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/__init__.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/auth.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/fields.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/forms.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/perms.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/phonenumber.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/serializers.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/test_auth.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/test_fields.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/test_forms.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/test_phonenumber.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/test_serializers.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/drf/views.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/enums.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/env.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/export.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/fixups.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/forms/__init__.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/forms/crispy.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/forms/fields.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/gettext.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/gettext_lazy.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/locale/ro/LC_MESSAGES/django.mo +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/locale/ro/LC_MESSAGES/django.po +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/logging.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/management.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/models.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/query.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/routers.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/templates/api_exception.html +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/templates/forms/widgets/opaquewidget.html +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_consts.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_env.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_management.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_service.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_timezones.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_utils.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/test_xml.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/timezones.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/utils.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/views.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/__init__.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/admin.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/asgi.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/engine.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/enums.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/job.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/models.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/worker/registry.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/wsgi.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu/xml.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu.egg-info/SOURCES.txt +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu.egg-info/dependency_links.txt +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu.egg-info/requires.txt +0 -0
- {csu-2.6.6 → csu-2.6.7}/src/csu.egg-info/top_level.txt +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service/test_custom_context.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service/test_custom_context_0_retries.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service/test_decoding.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service/test_error.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service/test_logging.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service/test_redirects.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service_auth/test_async.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service_auth/test_async_auth.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service_auth/test_sync.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/cassettes/test_service_auth/test_sync_auth.yaml +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/conftest.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/exampleworker.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/test_exampleworker.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/test_logging.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/test_models.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/test_worker.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/testproject/__init__.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/testproject/fixtures/testuser.json +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/testproject/models.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/testproject/settings.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tests/testproject/urls.py +0 -0
- {csu-2.6.6 → csu-2.6.7}/tox.ini +0 -0
{csu-2.6.6 → csu-2.6.7}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csu
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.7
|
|
4
4
|
Summary: Clean Slate Utils - bunch of utility code, mostly Django/DRF specific.
|
|
5
5
|
Author-email: Ionel Cristian Mărieș <contact@ionelmc.ro>
|
|
6
6
|
License-Expression: BSD-2-Clause
|
|
@@ -69,9 +69,9 @@ Overview
|
|
|
69
69
|
.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/csu.svg
|
|
70
70
|
:alt: Supported implementations
|
|
71
71
|
:target: https://pypi.org/project/csu
|
|
72
|
-
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.6.
|
|
72
|
+
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.6.7.svg
|
|
73
73
|
:alt: Commits since latest release
|
|
74
|
-
:target: https://github.com/ionelmc/python-csu/compare/v2.6.
|
|
74
|
+
:target: https://github.com/ionelmc/python-csu/compare/v2.6.7...main
|
|
75
75
|
.. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/python-csu/main.svg
|
|
76
76
|
:alt: Scrutinizer Status
|
|
77
77
|
:target: https://scrutinizer-ci.com/g/ionelmc/python-csu/
|
|
@@ -34,9 +34,9 @@ Overview
|
|
|
34
34
|
.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/csu.svg
|
|
35
35
|
:alt: Supported implementations
|
|
36
36
|
:target: https://pypi.org/project/csu
|
|
37
|
-
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.6.
|
|
37
|
+
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.6.7.svg
|
|
38
38
|
:alt: Commits since latest release
|
|
39
|
-
:target: https://github.com/ionelmc/python-csu/compare/v2.6.
|
|
39
|
+
:target: https://github.com/ionelmc/python-csu/compare/v2.6.7...main
|
|
40
40
|
.. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/python-csu/main.svg
|
|
41
41
|
:alt: Scrutinizer Status
|
|
42
42
|
:target: https://scrutinizer-ci.com/g/ionelmc/python-csu/
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import math
|
|
2
2
|
from collections import Counter
|
|
3
3
|
from collections.abc import Iterable
|
|
4
|
+
from datetime import datetime
|
|
4
5
|
from importlib.util import find_spec
|
|
6
|
+
from math import ceil
|
|
5
7
|
from os import urandom
|
|
6
8
|
from typing import TYPE_CHECKING
|
|
7
9
|
|
|
@@ -21,10 +23,42 @@ else:
|
|
|
21
23
|
|
|
22
24
|
HTTP_503_SERVICE_UNAVAILABLE = 503
|
|
23
25
|
|
|
26
|
+
event_id_number_table = dict(enumerate("0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"))
|
|
27
|
+
event_id_number_table_reversed = {v: k for k, v in event_id_number_table.items()}
|
|
28
|
+
event_id_number_table_len = len(event_id_number_table)
|
|
29
|
+
event_id_number_table_digit_ratio = 8 * math.log(2) / math.log(event_id_number_table_len)
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
|
|
32
|
+
def get_event_id_datetime(event_id: str) -> datetime:
|
|
33
|
+
"""
|
|
34
|
+
Returns naive datetime.
|
|
35
|
+
"""
|
|
36
|
+
return datetime( # noqa: DTZ001
|
|
37
|
+
year=event_id_number_table_reversed[event_id[0]],
|
|
38
|
+
month=event_id_number_table_reversed[event_id[1]],
|
|
39
|
+
day=event_id_number_table_reversed[event_id[2]],
|
|
40
|
+
hour=event_id_number_table_reversed[event_id[-3]],
|
|
41
|
+
minute=event_id_number_table_reversed[event_id[-2]],
|
|
42
|
+
second=event_id_number_table_reversed[event_id[-1]],
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_event_id(bytes=3):
|
|
26
47
|
dt = now()
|
|
27
|
-
|
|
48
|
+
year = event_id_number_table[dt.year % 100]
|
|
49
|
+
month = event_id_number_table[dt.month]
|
|
50
|
+
day = event_id_number_table[dt.day]
|
|
51
|
+
hour = event_id_number_table[dt.hour]
|
|
52
|
+
minute = event_id_number_table[dt.minute]
|
|
53
|
+
second = event_id_number_table[dt.second]
|
|
54
|
+
tag_num = int.from_bytes(urandom(bytes))
|
|
55
|
+
tag_parts = []
|
|
56
|
+
while tag_num > 0:
|
|
57
|
+
tag_num, rem = divmod(tag_num, event_id_number_table_len)
|
|
58
|
+
tag_parts.append(event_id_number_table[rem])
|
|
59
|
+
tag = "".join(reversed(tag_parts))
|
|
60
|
+
tag_pad = ceil(bytes * event_id_number_table_digit_ratio)
|
|
61
|
+
return dt.strftime(f"{year}{month}{day}{tag:0>{tag_pad}}{hour}{minute}{second}")
|
|
28
62
|
|
|
29
63
|
|
|
30
64
|
class TaggedError(Exception):
|
|
@@ -113,13 +113,10 @@ class HTTPServiceContext[RTYPE = HTTPServiceResponse]:
|
|
|
113
113
|
self.proxy = proxy
|
|
114
114
|
self.logger = service.logger
|
|
115
115
|
self.retries = service.retries
|
|
116
|
-
if event_id:
|
|
117
|
-
if ":" not in event_id:
|
|
118
|
-
raise ValueError("Expected a 'date:random:time' structured event id.")
|
|
119
|
-
else:
|
|
116
|
+
if event_id is None:
|
|
120
117
|
event_id = get_event_id()
|
|
121
|
-
|
|
122
|
-
self.
|
|
118
|
+
self.event_id = event_id
|
|
119
|
+
self.short_id = event_id[3:-3]
|
|
123
120
|
|
|
124
121
|
def __enter__(self) -> Self:
|
|
125
122
|
self.client.__enter__()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csu
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.7
|
|
4
4
|
Summary: Clean Slate Utils - bunch of utility code, mostly Django/DRF specific.
|
|
5
5
|
Author-email: Ionel Cristian Mărieș <contact@ionelmc.ro>
|
|
6
6
|
License-Expression: BSD-2-Clause
|
|
@@ -69,9 +69,9 @@ Overview
|
|
|
69
69
|
.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/csu.svg
|
|
70
70
|
:alt: Supported implementations
|
|
71
71
|
:target: https://pypi.org/project/csu
|
|
72
|
-
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.6.
|
|
72
|
+
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-csu/v2.6.7.svg
|
|
73
73
|
:alt: Commits since latest release
|
|
74
|
-
:target: https://github.com/ionelmc/python-csu/compare/v2.6.
|
|
74
|
+
:target: https://github.com/ionelmc/python-csu/compare/v2.6.7...main
|
|
75
75
|
.. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/python-csu/main.svg
|
|
76
76
|
:alt: Scrutinizer Status
|
|
77
77
|
:target: https://scrutinizer-ci.com/g/ionelmc/python-csu/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# ruff: noqa: DTZ001
|
|
1
2
|
import traceback
|
|
2
3
|
from datetime import datetime
|
|
3
4
|
from zoneinfo import ZoneInfo
|
|
@@ -10,6 +11,7 @@ from csu.exceptions import APIServiceError
|
|
|
10
11
|
from csu.exceptions import ExhaustedRetriesError
|
|
11
12
|
from csu.exceptions import OpenServiceError
|
|
12
13
|
from csu.exceptions import get_event_id
|
|
14
|
+
from csu.exceptions import get_event_id_datetime
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class OpenFooError(OpenServiceError):
|
|
@@ -90,11 +92,20 @@ def test_exhausted_retries_error():
|
|
|
90
92
|
|
|
91
93
|
def test_get_event_id(monkeypatch):
|
|
92
94
|
monkeypatch.setattr(exceptions, "urandom", lambda _: b"ZZZ")
|
|
93
|
-
with time_machine.travel(datetime(2024, 12,
|
|
94
|
-
assert get_event_id() == snapshot("
|
|
95
|
+
with time_machine.travel(datetime(2024, 12, 31, 12, 59, 59, microsecond=999999, tzinfo=ZoneInfo("Europe/Bucharest"))):
|
|
96
|
+
assert get_event_id() == snapshot("PCW0SPpVCzz")
|
|
95
97
|
|
|
96
98
|
|
|
97
99
|
def test_get_accident_id(monkeypatch):
|
|
98
100
|
monkeypatch.setattr(exceptions, "urandom", lambda len: bytes(range(len)))
|
|
99
101
|
with time_machine.travel(1674777700.5816755):
|
|
100
|
-
assert get_event_id() == snapshot("
|
|
102
|
+
assert get_event_id() == snapshot("N1S0004I21f")
|
|
103
|
+
|
|
104
|
+
assert get_event_id_datetime("N1R0007620140") == snapshot(datetime(23, 1, 26, hour=1, minute=4))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def test_get_event_id_datetime(monkeypatch):
|
|
108
|
+
|
|
109
|
+
assert get_event_id_datetime("N1R0007620140") == snapshot(datetime(23, 1, 26, hour=1, minute=4))
|
|
110
|
+
assert get_event_id_datetime("ZAT0007620AZZ") == snapshot(datetime(34, 10, 28, hour=10, minute=34, second=34))
|
|
111
|
+
assert get_event_id_datetime("TAT0007620Czz") == snapshot(datetime(28, 10, 28, hour=12, minute=59, second=59))
|