Encryptors 2.26__tar.gz → 2.28__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 (91) hide show
  1. {encryptors-2.26 → encryptors-2.28}/PKG-INFO +1 -1
  2. {encryptors-2.26 → encryptors-2.28}/setup.py +1 -1
  3. {encryptors-2.26 → encryptors-2.28}/src/Encryptors.egg-info/PKG-INFO +1 -1
  4. {encryptors-2.26 → encryptors-2.28}/src/Encryptors.egg-info/SOURCES.txt +2 -0
  5. encryptors-2.28/src/Osdental/Database/BaseRepository.py +98 -0
  6. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Messaging/AzureServiceBus.py +1 -1
  7. encryptors-2.28/src/Osdental/Shared/Utils/DataNormalizer.py +58 -0
  8. {encryptors-2.26 → encryptors-2.28}/README.md +0 -0
  9. {encryptors-2.26 → encryptors-2.28}/setup.cfg +0 -0
  10. {encryptors-2.26 → encryptors-2.28}/src/Encryptors.egg-info/dependency_links.txt +0 -0
  11. {encryptors-2.26 → encryptors-2.28}/src/Encryptors.egg-info/entry_points.txt +0 -0
  12. {encryptors-2.26 → encryptors-2.28}/src/Encryptors.egg-info/requires.txt +0 -0
  13. {encryptors-2.26 → encryptors-2.28}/src/Encryptors.egg-info/top_level.txt +0 -0
  14. {encryptors-2.26 → encryptors-2.28}/src/Osdental/BlobStorage/Storage.py +0 -0
  15. {encryptors-2.26 → encryptors-2.28}/src/Osdental/BlobStorage/__init__.py +0 -0
  16. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Cli/__init__.py +0 -0
  17. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Database/Connection.py +0 -0
  18. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Database/UnitOfWork.py +0 -0
  19. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Database/UowFactory.py +0 -0
  20. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Database/__init__.py +0 -0
  21. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Decorators/AuditLog.py +0 -0
  22. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Decorators/DecryptedData.py +0 -0
  23. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Decorators/Grpc.py +0 -0
  24. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Decorators/Retry.py +0 -0
  25. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Decorators/SqlDataNormalizer.py +0 -0
  26. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Decorators/__init__.py +0 -0
  27. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/Aes.py +0 -0
  28. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/Argon2.py +0 -0
  29. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/Bcrypt.py +0 -0
  30. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/Jwt.py +0 -0
  31. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/Rsa.py +0 -0
  32. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/Sha512.py +0 -0
  33. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Encryptor/__init__.py +0 -0
  34. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Exception/ControlledException.py +0 -0
  35. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Exception/__init__.py +0 -0
  36. {encryptors-2.26 → encryptors-2.28}/src/Osdental/ExternalHttp/Client.py +0 -0
  37. {encryptors-2.26 → encryptors-2.28}/src/Osdental/ExternalHttp/__init__.py +0 -0
  38. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Base/GrpcClientBase.py +0 -0
  39. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Base/__init__.py +0 -0
  40. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Client/PortalClient.py +0 -0
  41. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Client/__init__.py +0 -0
  42. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Generated/Common_pb2.py +0 -0
  43. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Generated/Common_pb2_grpc.py +0 -0
  44. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Generated/Portal_pb2.py +0 -0
  45. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Generated/Portal_pb2_grpc.py +0 -0
  46. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/Generated/__init__.py +0 -0
  47. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Grpc/__init__.py +0 -0
  48. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Helpers/KeyVaultService.py +0 -0
  49. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Helpers/__init__.py +0 -0
  50. {encryptors-2.26 → encryptors-2.28}/src/Osdental/InternalHttp/Request.py +0 -0
  51. {encryptors-2.26 → encryptors-2.28}/src/Osdental/InternalHttp/Response.py +0 -0
  52. {encryptors-2.26 → encryptors-2.28}/src/Osdental/InternalHttp/__init__.py +0 -0
  53. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Messaging/Kafka.py +0 -0
  54. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Messaging/RabbitMQ.py +0 -0
  55. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Messaging/__init__.py +0 -0
  56. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Models/CDataIntegration.py +0 -0
  57. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Models/Catalog.py +0 -0
  58. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Models/Legacy.py +0 -0
  59. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Models/Response.py +0 -0
  60. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Models/Token.py +0 -0
  61. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Models/__init__.py +0 -0
  62. {encryptors-2.26 → encryptors-2.28}/src/Osdental/RedisCache/Redis.py +0 -0
  63. {encryptors-2.26 → encryptors-2.28}/src/Osdental/RedisCache/__init__.py +0 -0
  64. {encryptors-2.26 → encryptors-2.28}/src/Osdental/ServicesBus/ServicesBus.py +0 -0
  65. {encryptors-2.26 → encryptors-2.28}/src/Osdental/ServicesBus/TaskQueue.py +0 -0
  66. {encryptors-2.26 → encryptors-2.28}/src/Osdental/ServicesBus/__init__.py +0 -0
  67. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Config/__init__.py +0 -0
  68. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/Code.py +0 -0
  69. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/Constant.py +0 -0
  70. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/FileType.py +0 -0
  71. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/GrahpqlOperation.py +0 -0
  72. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/Message.py +0 -0
  73. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/Profile.py +0 -0
  74. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Enums/__init__.py +0 -0
  75. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Logger.py +0 -0
  76. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/CaseConverter.py +0 -0
  77. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/CodeGenerator.py +0 -0
  78. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/DataUtils.py +0 -0
  79. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/DateUtils.py +0 -0
  80. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/FileMetaData.py +0 -0
  81. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/HashValidator.py +0 -0
  82. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/Mapper.py +0 -0
  83. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/PasswordGenerator.py +0 -0
  84. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/QueryGenerator.py +0 -0
  85. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/TextProcessor.py +0 -0
  86. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/Utils/__init__.py +0 -0
  87. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Shared/__init__.py +0 -0
  88. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Storage/AzureBlobStorage.py +0 -0
  89. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Storage/S3Storage.py +0 -0
  90. {encryptors-2.26 → encryptors-2.28}/src/Osdental/Storage/__init__.py +0 -0
  91. {encryptors-2.26 → encryptors-2.28}/src/Osdental/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.26
3
+ Version: 2.28
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="Encryptors",
5
- version="2.26",
5
+ version="2.28",
6
6
  author="OSDental LLC",
7
7
  author_email="support@osdental.ai",
8
8
  description="End-to-end algorithm library",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.26
3
+ Version: 2.28
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -10,6 +10,7 @@ src/Osdental/__init__.py
10
10
  src/Osdental/BlobStorage/Storage.py
11
11
  src/Osdental/BlobStorage/__init__.py
12
12
  src/Osdental/Cli/__init__.py
13
+ src/Osdental/Database/BaseRepository.py
13
14
  src/Osdental/Database/Connection.py
14
15
  src/Osdental/Database/UnitOfWork.py
15
16
  src/Osdental/Database/UowFactory.py
@@ -73,6 +74,7 @@ src/Osdental/Shared/Enums/Profile.py
73
74
  src/Osdental/Shared/Enums/__init__.py
74
75
  src/Osdental/Shared/Utils/CaseConverter.py
75
76
  src/Osdental/Shared/Utils/CodeGenerator.py
77
+ src/Osdental/Shared/Utils/DataNormalizer.py
76
78
  src/Osdental/Shared/Utils/DataUtils.py
77
79
  src/Osdental/Shared/Utils/DateUtils.py
78
80
  src/Osdental/Shared/Utils/FileMetaData.py
@@ -0,0 +1,98 @@
1
+ from typing import Any
2
+ from sqlalchemy import text
3
+ from sqlalchemy.ext.asyncio import AsyncSession
4
+ from Osdental.Exception.ControlledException import DatabaseException
5
+ from Osdental.Shared.Utils.DataNormalizer import normalize
6
+
7
+ class BaseRepository:
8
+
9
+ def __init__(self, async_session: AsyncSession):
10
+ self.async_session = async_session
11
+
12
+ def _get_status_value(self, rows: dict, *possible_keys: str):
13
+ for key in possible_keys:
14
+ if key in rows:
15
+ return rows[key]
16
+ return None
17
+
18
+ async def _execute_query(
19
+ self,
20
+ query: str,
21
+ params: dict | None = None,
22
+ *,
23
+ many: bool = False,
24
+ as_dict: bool = False
25
+ ) -> Any:
26
+ result = await self.async_session.execute(
27
+ text(query),
28
+ params or {}
29
+ )
30
+
31
+ data = (
32
+ result.mappings().all()
33
+ if many
34
+ else result.mappings().first()
35
+ )
36
+
37
+ if not as_dict or data is None:
38
+ return data
39
+
40
+ if many:
41
+ return normalize(data)
42
+
43
+ return normalize(data)
44
+
45
+ async def _execute_command(
46
+ self,
47
+ query: str,
48
+ params: dict | None = None,
49
+ *,
50
+ validate: bool = True,
51
+ success_codes: str | int | tuple[str | int, ...] | None = None
52
+ ):
53
+ result = await self.async_session.execute(
54
+ text(query),
55
+ params or {}
56
+ )
57
+
58
+ row = result.mappings().first()
59
+
60
+ if not validate or not row:
61
+ return row
62
+
63
+ status_code = self._get_status_value(
64
+ row,
65
+ "statusCode",
66
+ "STATUS_CODE",
67
+ "status_code"
68
+ )
69
+
70
+ status_message = self._get_status_value(
71
+ row,
72
+ "statusMessage",
73
+ "STATUS_MESSAGE",
74
+ "status_message"
75
+ )
76
+
77
+ # Si no se define success_codes, solo valida que no sea None
78
+ if success_codes is None:
79
+ if status_code is None:
80
+ raise DatabaseException(
81
+ message="Status code missing",
82
+ error="Status code missing",
83
+ status_code=500
84
+ )
85
+ return row
86
+
87
+ # Normalizamos a tupla
88
+ if not isinstance(success_codes, tuple):
89
+ success_codes = (success_codes,)
90
+
91
+ if status_code not in success_codes:
92
+ raise DatabaseException(
93
+ message=status_message,
94
+ error=status_message,
95
+ status_code=status_code
96
+ )
97
+
98
+ return row
@@ -4,7 +4,7 @@ from azure.servicebus import ServiceBusMessage
4
4
  from azure.servicebus.aio import ServiceBusClient
5
5
  from azure.identity.aio import DefaultAzureCredential
6
6
 
7
- class ServiceBusService:
7
+ class AzureServiceBusQueue:
8
8
 
9
9
  def __init__(self, namespace: str, queue_name: str):
10
10
 
@@ -0,0 +1,58 @@
1
+ from datetime import datetime, date
2
+ from decimal import Decimal
3
+ from uuid import UUID
4
+ from typing import Any
5
+ from sqlalchemy import RowMapping
6
+
7
+ def is_uuid_string(value: str) -> bool:
8
+ try:
9
+ UUID(value)
10
+ return True
11
+ except (ValueError, TypeError):
12
+ return False
13
+
14
+ def normalize_odbc_value(value: Any) -> Any:
15
+ """
16
+ Convierte valores problemáticos de ODBC a tipos JSON serializables.
17
+ """
18
+
19
+ if value is None:
20
+ return None
21
+
22
+ if isinstance(value, Decimal):
23
+ return float(value)
24
+
25
+ if isinstance(value, (datetime, date)):
26
+ return value.isoformat()
27
+
28
+ if isinstance(value, UUID):
29
+ return str(value).lower()
30
+
31
+ if isinstance(value, str) and is_uuid_string(value):
32
+ return value.lower()
33
+
34
+ return value
35
+
36
+ def normalize(data: Any) -> Any:
37
+ """
38
+ Normaliza cualquier estructura:
39
+ - RowMapping
40
+ - dict
41
+ - list
42
+ - valores simples
43
+ """
44
+
45
+ # SQLAlchemy RowMapping
46
+ if isinstance(data, RowMapping):
47
+ data = dict(data)
48
+
49
+ # dict
50
+ if isinstance(data, dict):
51
+ return {k: normalize(v) for k, v in data.items()}
52
+
53
+ # list / tuple
54
+ if isinstance(data, (list, tuple)):
55
+ return [normalize(item) for item in data]
56
+
57
+ # valor simple
58
+ return normalize_odbc_value(data)
File without changes
File without changes