plexus-python-common 1.0.23__tar.gz → 1.0.25__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.
Files changed (80) hide show
  1. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/PKG-INFO +7 -3
  2. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/pyproject.toml +13 -3
  3. plexus_python_common-1.0.25/src/plexus/common/utils/apiutils.py +31 -0
  4. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/s3utils.py +27 -3
  5. plexus_python_common-1.0.25/src/plexus/common/utils/sqlutils.py +9 -0
  6. plexus_python_common-1.0.25/src/plexus/common/utils/testutils.py +49 -0
  7. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus_python_common.egg-info/PKG-INFO +7 -3
  8. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus_python_common.egg-info/SOURCES.txt +5 -1
  9. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus_python_common.egg-info/requires.txt +7 -2
  10. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/ormutils_test.py +3 -2
  11. plexus_python_common-1.0.25/test/plexus_tests/common/utils/testutils_test.py +50 -0
  12. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/.editorconfig +0 -0
  13. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/.github/workflows/pr.yml +0 -0
  14. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/.github/workflows/push.yml +0 -0
  15. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/.gitignore +0 -0
  16. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/MANIFEST.in +0 -0
  17. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/README.md +0 -0
  18. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/VERSION +0 -0
  19. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
  20. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
  21. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
  22. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
  23. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
  24. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
  25. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
  26. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
  27. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
  28. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
  29. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/file.bar +0 -0
  30. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/file.baz +0 -0
  31. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/s3utils/dir.foo/file.foo +0 -0
  32. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/0-dummy +0 -0
  33. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/1-dummy +0 -0
  34. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/2-dummy +0 -0
  35. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.0.0.jsonl +0 -0
  36. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.0.0.vol-0.jsonl +0 -0
  37. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.0.jsonl +0 -0
  38. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.1.1.jsonl +0 -0
  39. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.1.1.vol-1.jsonl +0 -0
  40. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.1.jsonl +0 -0
  41. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.2.2.jsonl +0 -0
  42. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.2.2.vol-2.jsonl +0 -0
  43. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.2.jsonl +0 -0
  44. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.csv.part0 +0 -0
  45. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.csv.part1 +0 -0
  46. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.csv.part2 +0 -0
  47. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/resources/unittest/shutils/dummy.txt +0 -0
  48. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/setup.cfg +0 -0
  49. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/setup.py +0 -0
  50. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/__init__.py +0 -0
  51. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/carto/OSMFile.py +0 -0
  52. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/carto/OSMNode.py +0 -0
  53. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/carto/OSMTags.py +0 -0
  54. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/carto/OSMWay.py +0 -0
  55. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/carto/__init__.py +0 -0
  56. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/config.py +0 -0
  57. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/pose.py +0 -0
  58. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/proj.py +0 -0
  59. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/__init__.py +0 -0
  60. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/bagutils.py +0 -0
  61. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/datautils.py +0 -0
  62. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/jsonutils.py +0 -0
  63. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/ormutils.py +0 -0
  64. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/shutils.py +0 -0
  65. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus/common/utils/strutils.py +0 -0
  66. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
  67. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
  68. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/src/plexus_python_common.egg-info/top_level.txt +0 -0
  69. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_test.py +0 -0
  70. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/__init__.py +0 -0
  71. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
  72. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
  73. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/pose_test.py +0 -0
  74. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/proj_test.py +0 -0
  75. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
  76. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/datautils_test.py +0 -0
  77. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
  78. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/s3utils_test.py +0 -0
  79. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/shutils_test.py +0 -0
  80. {plexus_python_common-1.0.23 → plexus_python_common-1.0.25}/test/plexus_tests/common/utils/strutils_test.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plexus-python-common
3
- Version: 1.0.23
3
+ Version: 1.0.25
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.12
6
6
  Classifier: Programming Language :: Python :: 3.13
7
7
  Classifier: Programming Language :: Python :: 3.14
8
8
  Requires-Python: <3.15,>=3.12
9
9
  Requires-Dist: boto3>=1.41
10
+ Requires-Dist: boto3-stubs>=1.41
10
11
  Requires-Dist: cloudpathlib>=0.21
11
12
  Requires-Dist: lxml>=6.0
12
13
  Requires-Dist: numpy>=2.3
@@ -16,12 +17,15 @@ Requires-Dist: pyparsing>=3.2
16
17
  Requires-Dist: pyproj>=3.6
17
18
  Requires-Dist: pyquaternion>=0.9
18
19
  Requires-Dist: sqlalchemy>=2.0
19
- Requires-Dist: sqlmodel
20
20
  Requires-Dist: rich>=13.9
21
+ Requires-Dist: textcase>=0.4
21
22
  Requires-Dist: ujson>=5.9
22
23
  Requires-Dist: iker-python-common[all]>=1.0
23
24
  Provides-Extra: all
24
- Requires-Dist: plexus-python-common; extra == "all"
25
+ Requires-Dist: plexus-python-common[api]; extra == "all"
26
+ Provides-Extra: api
27
+ Requires-Dist: fastapi>=0.119.0; extra == "api"
28
+ Requires-Dist: sqlmodel>=0.0.25; extra == "api"
25
29
  Provides-Extra: test
26
30
  Requires-Dist: ddt>=1.7; extra == "test"
27
31
  Requires-Dist: moto[all,ec2,s3]>=5.1; extra == "test"
@@ -9,6 +9,7 @@ build-backend = "setuptools.build_meta"
9
9
  [dependency-groups]
10
10
  dev = [
11
11
  "boto3>=1.41",
12
+ "boto3-stubs>=1.41",
12
13
  "cloudpathlib>=0.21",
13
14
  "lxml>=6.0",
14
15
  "numpy>=2.3",
@@ -18,11 +19,15 @@ dev = [
18
19
  "pyproj>=3.6",
19
20
  "pyquaternion>=0.9",
20
21
  "sqlalchemy>=2.0",
21
- "sqlmodel",
22
22
  "rich>=13.9",
23
+ "textcase>=0.4",
23
24
  "ujson>=5.9",
24
25
  "iker-python-common[all]>=1.0",
25
26
  ]
27
+ api = [
28
+ "fastapi>=0.119.0",
29
+ "sqlmodel>=0.0.25",
30
+ ]
26
31
  test = [
27
32
  "ddt>=1.7",
28
33
  "moto[ec2,s3,all]>=5.1",
@@ -44,6 +49,7 @@ classifiers = [
44
49
  ]
45
50
  dependencies = [
46
51
  "boto3>=1.41",
52
+ "boto3-stubs>=1.41",
47
53
  "cloudpathlib>=0.21",
48
54
  "lxml>=6.0",
49
55
  "numpy>=2.3",
@@ -53,15 +59,19 @@ dependencies = [
53
59
  "pyproj>=3.6",
54
60
  "pyquaternion>=0.9",
55
61
  "sqlalchemy>=2.0",
56
- "sqlmodel",
57
62
  "rich>=13.9",
63
+ "textcase>=0.4",
58
64
  "ujson>=5.9",
59
65
  "iker-python-common[all]>=1.0",
60
66
  ]
61
67
 
62
68
  [project.optional-dependencies]
63
69
  all = [
64
- "plexus-python-common",
70
+ "plexus-python-common[api]",
71
+ ]
72
+ api = [
73
+ "fastapi>=0.119.0",
74
+ "sqlmodel>=0.0.25",
65
75
  ]
66
76
  test = [
67
77
  "ddt>=1.7",
@@ -0,0 +1,31 @@
1
+ from contextlib import AbstractContextManager
2
+
3
+ import sqlalchemy.orm as sa_orm
4
+ from fastapi import HTTPException
5
+
6
+ __all__ = [
7
+ "managed_db_session",
8
+ ]
9
+
10
+
11
+ class DBSessionExceptionManager(AbstractContextManager):
12
+ def __init__(self, db: sa_orm.Session, commit_on_exit: bool):
13
+ self.db = db
14
+ self.commit_on_exit = commit_on_exit
15
+
16
+ def __enter__(self):
17
+ return self
18
+
19
+ def __exit__(self, exc_type, exc_value, traceback):
20
+ if isinstance(exc_type, HTTPException):
21
+ return False # Propagate HTTPException
22
+ if exc_type is not None:
23
+ self.db.rollback() # Raise a new HTTPException (or any other exception type)
24
+ raise HTTPException(status_code=500, detail=str(exc_value)) from exc_value
25
+ if self.commit_on_exit:
26
+ self.db.commit()
27
+ return True
28
+
29
+
30
+ def managed_db_session(db: sa_orm.Session, commit_on_exit: bool = True) -> DBSessionExceptionManager:
31
+ return DBSessionExceptionManager(db, commit_on_exit)
@@ -7,6 +7,7 @@ import mimetypes
7
7
  import os
8
8
  import os.path
9
9
  import tempfile
10
+ import typing
10
11
  from collections.abc import Callable, Generator
11
12
  from pathlib import Path
12
13
  from typing import Literal
@@ -34,20 +35,29 @@ __all__ = [
34
35
  ]
35
36
 
36
37
 
37
- @dataclasses.dataclass
38
+ @dataclasses.dataclass(frozen=True, eq=True)
38
39
  class S3ObjectMeta(object):
39
40
  key: str
40
41
  last_modified: datetime.datetime
41
42
  size: int
42
43
 
43
44
 
45
+ if typing.TYPE_CHECKING:
46
+ def s3_make_client(
47
+ access_key_id: str = None,
48
+ secret_access_key: str = None,
49
+ region_name: str = None,
50
+ endpoint_url: str = None,
51
+ ) -> contextlib.AbstractContextManager[S3Client]: ...
52
+
53
+
44
54
  @contextlib.contextmanager
45
55
  def s3_make_client(
46
56
  access_key_id: str = None,
47
57
  secret_access_key: str = None,
48
58
  region_name: str = None,
49
59
  endpoint_url: str = None,
50
- ) -> Generator[S3Client]:
60
+ ) -> Generator[S3Client, None, None]:
51
61
  """
52
62
  Creates an S3 client as a context manager for safe resource handling.
53
63
 
@@ -60,7 +70,12 @@ def s3_make_client(
60
70
  session = boto3.Session(aws_access_key_id=trim_to_none(access_key_id),
61
71
  aws_secret_access_key=trim_to_none(secret_access_key),
62
72
  region_name=trim_to_none(region_name))
63
- yield S3Client(boto3_session=session, endpoint_url=trim_to_none(endpoint_url))
73
+ client = S3Client(boto3_session=session, endpoint_url=trim_to_none(endpoint_url))
74
+ try:
75
+ yield client
76
+ finally:
77
+ if hasattr(client, "close"):
78
+ client.close()
64
79
 
65
80
 
66
81
  def s3_list_objects(client: S3Client, bucket: str, prefix: str, limit: int = None) -> Generator[S3ObjectMeta]:
@@ -386,6 +401,15 @@ def s3_make_progress_callback(
386
401
  return progress_callback
387
402
 
388
403
 
404
+ if typing.TYPE_CHECKING:
405
+ def s3_make_progressed_client(
406
+ access_key_id: str = None,
407
+ secret_access_key: str = None,
408
+ region_name: str = None,
409
+ endpoint_url: str = None,
410
+ ) -> contextlib.AbstractContextManager[S3Client]: ...
411
+
412
+
389
413
  @contextlib.contextmanager
390
414
  def s3_make_progressed_client(
391
415
  access_key_id: str = None,
@@ -0,0 +1,9 @@
1
+ __all__ = [
2
+ "escape_sql_like",
3
+ ]
4
+
5
+
6
+ def escape_sql_like(s: str | None) -> str:
7
+ if s is None:
8
+ raise ValueError("input string cannot be None")
9
+ return s.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
@@ -0,0 +1,49 @@
1
+ import uuid as py_uuid
2
+
3
+ import textcase
4
+ from iker.common.utils.jsonutils import JsonType
5
+ from iker.common.utils.jsonutils import json_difference, json_reformat
6
+
7
+ from plexus.common.utils.datautils import compute_vin_code_check_digit
8
+
9
+ __all__ = [
10
+ "generate_dummy_uuid_str",
11
+ "generate_dummy_uuid",
12
+ "generate_dummy_vin_code",
13
+ "case_insensitive_json_compare",
14
+ ]
15
+
16
+
17
+ def generate_dummy_uuid_str(*nums: int) -> str:
18
+ if len(nums) > 8:
19
+ raise ValueError("a maximum of 8 integers can be provided")
20
+ if not all(0 <= num <= 0xFFFF for num in nums):
21
+ raise ValueError("all integers must be in the range 0 to 65535 (0xFFFF)")
22
+ i0, i1, i2, i3, i4, i5, i6, i7 = list(nums) + [0] * (8 - len(nums))
23
+ return f"{i0:04x}{i1:04x}-{i2:04x}-{i3:04x}-{i4:04x}-{i5:04x}{i6:04x}{i7:04x}"
24
+
25
+
26
+ def generate_dummy_uuid(*nums: int) -> py_uuid.UUID:
27
+ return py_uuid.UUID(generate_dummy_uuid_str(*nums))
28
+
29
+
30
+ def generate_dummy_vin_code(*nums: int) -> str:
31
+ if len(nums) > 4:
32
+ raise ValueError("a maximum of 4 integers can be provided")
33
+ if not all(0 <= num <= 9999 for num in nums):
34
+ raise ValueError("all integers must be in the range 0 to 9999")
35
+ i0, i1, i2, i3 = list(nums) + [0] * (4 - len(nums))
36
+ unchecked_vin_code = f"{i0:04d}{i1:04d}0{i2:04d}{i3:04d}"
37
+ check_digit = compute_vin_code_check_digit(unchecked_vin_code)
38
+ return unchecked_vin_code[:8] + check_digit + unchecked_vin_code[-8:]
39
+
40
+
41
+ def case_insensitive_json_compare(a: JsonType, b: JsonType, *, print_diff_messages: bool = True) -> bool:
42
+ identical = True
43
+ for node_path, diff_message in json_difference(json_reformat(a, key_formatter=textcase.camel),
44
+ json_reformat(b, key_formatter=textcase.camel),
45
+ []):
46
+ if print_diff_messages:
47
+ print(node_path, diff_message)
48
+ identical = False
49
+ return identical
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plexus-python-common
3
- Version: 1.0.23
3
+ Version: 1.0.25
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.12
6
6
  Classifier: Programming Language :: Python :: 3.13
7
7
  Classifier: Programming Language :: Python :: 3.14
8
8
  Requires-Python: <3.15,>=3.12
9
9
  Requires-Dist: boto3>=1.41
10
+ Requires-Dist: boto3-stubs>=1.41
10
11
  Requires-Dist: cloudpathlib>=0.21
11
12
  Requires-Dist: lxml>=6.0
12
13
  Requires-Dist: numpy>=2.3
@@ -16,12 +17,15 @@ Requires-Dist: pyparsing>=3.2
16
17
  Requires-Dist: pyproj>=3.6
17
18
  Requires-Dist: pyquaternion>=0.9
18
19
  Requires-Dist: sqlalchemy>=2.0
19
- Requires-Dist: sqlmodel
20
20
  Requires-Dist: rich>=13.9
21
+ Requires-Dist: textcase>=0.4
21
22
  Requires-Dist: ujson>=5.9
22
23
  Requires-Dist: iker-python-common[all]>=1.0
23
24
  Provides-Extra: all
24
- Requires-Dist: plexus-python-common; extra == "all"
25
+ Requires-Dist: plexus-python-common[api]; extra == "all"
26
+ Provides-Extra: api
27
+ Requires-Dist: fastapi>=0.119.0; extra == "api"
28
+ Requires-Dist: sqlmodel>=0.0.25; extra == "api"
25
29
  Provides-Extra: test
26
30
  Requires-Dist: ddt>=1.7; extra == "test"
27
31
  Requires-Dist: moto[all,ec2,s3]>=5.1; extra == "test"
@@ -46,13 +46,16 @@ src/plexus/common/carto/OSMTags.py
46
46
  src/plexus/common/carto/OSMWay.py
47
47
  src/plexus/common/carto/__init__.py
48
48
  src/plexus/common/utils/__init__.py
49
+ src/plexus/common/utils/apiutils.py
49
50
  src/plexus/common/utils/bagutils.py
50
51
  src/plexus/common/utils/datautils.py
51
52
  src/plexus/common/utils/jsonutils.py
52
53
  src/plexus/common/utils/ormutils.py
53
54
  src/plexus/common/utils/s3utils.py
54
55
  src/plexus/common/utils/shutils.py
56
+ src/plexus/common/utils/sqlutils.py
55
57
  src/plexus/common/utils/strutils.py
58
+ src/plexus/common/utils/testutils.py
56
59
  src/plexus_python_common.egg-info/PKG-INFO
57
60
  src/plexus_python_common.egg-info/SOURCES.txt
58
61
  src/plexus_python_common.egg-info/dependency_links.txt
@@ -71,4 +74,5 @@ test/plexus_tests/common/utils/jsonutils_test.py
71
74
  test/plexus_tests/common/utils/ormutils_test.py
72
75
  test/plexus_tests/common/utils/s3utils_test.py
73
76
  test/plexus_tests/common/utils/shutils_test.py
74
- test/plexus_tests/common/utils/strutils_test.py
77
+ test/plexus_tests/common/utils/strutils_test.py
78
+ test/plexus_tests/common/utils/testutils_test.py
@@ -1,4 +1,5 @@
1
1
  boto3>=1.41
2
+ boto3-stubs>=1.41
2
3
  cloudpathlib>=0.21
3
4
  lxml>=6.0
4
5
  numpy>=2.3
@@ -8,13 +9,17 @@ pyparsing>=3.2
8
9
  pyproj>=3.6
9
10
  pyquaternion>=0.9
10
11
  sqlalchemy>=2.0
11
- sqlmodel
12
12
  rich>=13.9
13
+ textcase>=0.4
13
14
  ujson>=5.9
14
15
  iker-python-common[all]>=1.0
15
16
 
16
17
  [all]
17
- plexus-python-common
18
+ plexus-python-common[api]
19
+
20
+ [api]
21
+ fastapi>=0.119.0
22
+ sqlmodel>=0.0.25
18
23
 
19
24
  [test]
20
25
  ddt>=1.7
@@ -12,6 +12,7 @@ from iker.common.utils.jsonutils import JsonType
12
12
  from iker.common.utils.randutils import randomizer
13
13
  from sqlmodel import Field, SQLModel
14
14
 
15
+ from plexus.common.utils.apiutils import managed_db_session
15
16
  from plexus.common.utils.ormutils import (
16
17
  db_activate_revision_model,
17
18
  db_activate_snapshot_model,
@@ -954,7 +955,7 @@ def test_make_snapshot_model_trigger(fixture_postgresql_test_proc, fixture_postg
954
955
  dummy_json=rng.random_json_object(5),
955
956
  )
956
957
 
957
- with maker.make_session() as session:
958
+ with maker.make_session() as session, managed_db_session(session):
958
959
  session.execute(sa.sql.text("SET TIMEZONE TO 'UTC'"))
959
960
  session.commit()
960
961
 
@@ -1040,7 +1041,7 @@ def test_make_revision_model_trigger(fixture_postgresql_test_proc, fixture_postg
1040
1041
  dummy_json=rng.random_json_object(5),
1041
1042
  )
1042
1043
 
1043
- with maker.make_session() as session:
1044
+ with maker.make_session() as session, managed_db_session(session):
1044
1045
  session.execute(sa.sql.text("SET TIMEZONE TO 'UTC'"))
1045
1046
  session.commit()
1046
1047
 
@@ -0,0 +1,50 @@
1
+ import unittest
2
+
3
+ import ddt
4
+
5
+ from plexus.common.utils.testutils import generate_dummy_uuid_str, generate_dummy_vin_code
6
+
7
+
8
+ @ddt.ddt
9
+ class TestUtilsTest(unittest.TestCase):
10
+ data_generate_dummy_uuid_str = [
11
+ ((), "00000000-0000-0000-0000-000000000000"),
12
+ ((0,), "00000000-0000-0000-0000-000000000000"),
13
+ ((0, 0,), "00000000-0000-0000-0000-000000000000"),
14
+ ((0, 0, 0, 0, 0, 0, 0, 0,), "00000000-0000-0000-0000-000000000000"),
15
+ ((1,), "00010000-0000-0000-0000-000000000000"),
16
+ ((1, 2, 3, 4, 5, 6, 7, 8,), "00010002-0003-0004-0005-000600070008"),
17
+ ((0x1, 0x10, 0x100, 0x1000, 0xF, 0xFF, 0xFFF, 0xFFFF,), "00010010-0100-1000-000f-00ff0fffffff"),
18
+ ]
19
+
20
+ @ddt.idata(data_generate_dummy_uuid_str)
21
+ @ddt.unpack
22
+ def test_generate_dummy_uuid_str(self, nums, expect):
23
+ self.assertEqual(generate_dummy_uuid_str(*nums), expect)
24
+
25
+ data_generate_dummy_uuid_str__bad_case = [
26
+ ((0, 0, 0, 0, 0, 0, 0, 0, 0,),),
27
+ ((-1,),),
28
+ ((0x10000,),),
29
+ ]
30
+
31
+ @ddt.idata(data_generate_dummy_uuid_str__bad_case)
32
+ @ddt.unpack
33
+ def test_generate_dummy_uuid_str__bad_case(self, nums):
34
+ with self.assertRaises(ValueError):
35
+ generate_dummy_uuid_str(*nums)
36
+
37
+ data_generate_dummy_vin_code = [
38
+ ((), "00000000000000000"),
39
+ ((0,), "00000000000000000"),
40
+ ((0, 0,), "00000000000000000"),
41
+ ((0, 0, 0, 0,), "00000000000000000"),
42
+ ((1,), "00010000500000000"),
43
+ ((1, 2, 3, 4,), "00010002700030004"),
44
+ ((1, 23, 456, 7890,), "00010023504567890"),
45
+ ]
46
+
47
+ @ddt.idata(data_generate_dummy_vin_code)
48
+ @ddt.unpack
49
+ def test_generate_dummy_vin_code(self, nums, expect):
50
+ self.assertEqual(generate_dummy_vin_code(*nums), expect)