Encryptors 2.1__tar.gz → 2.6__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 (150) hide show
  1. {encryptors-2.1 → encryptors-2.6}/PKG-INFO +9 -3
  2. {encryptors-2.1 → encryptors-2.6}/setup.py +12 -6
  3. {encryptors-2.1 → encryptors-2.6}/src/Encryptors.egg-info/PKG-INFO +9 -3
  4. encryptors-2.6/src/Encryptors.egg-info/SOURCES.txt +85 -0
  5. {encryptors-2.1 → encryptors-2.6}/src/Encryptors.egg-info/requires.txt +8 -2
  6. encryptors-2.6/src/Osdental/Cache/Redis.py +316 -0
  7. encryptors-2.6/src/Osdental/Cache/__init__.py +53 -0
  8. encryptors-2.6/src/Osdental/Cli/__init__.py +137 -0
  9. encryptors-2.6/src/Osdental/Constants/Constant.py +10 -0
  10. encryptors-2.6/src/Osdental/Constants/Message.py +37 -0
  11. encryptors-2.6/src/Osdental/Context/__init__.py +5 -0
  12. encryptors-2.6/src/Osdental/Database/BaseRepository.py +192 -0
  13. encryptors-2.6/src/Osdental/Database/Connection.py +199 -0
  14. encryptors-2.6/src/Osdental/Decorators/Grpc.py +34 -0
  15. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Decorators/Retry.py +4 -1
  16. encryptors-2.6/src/Osdental/Decorators/SecureResolver.py +147 -0
  17. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Encryptor/Aes.py +35 -31
  18. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Encryptor/Argon2.py +2 -11
  19. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Encryptor/Bcrypt.py +1 -1
  20. encryptors-2.6/src/Osdental/Encryptor/Jwt.py +35 -0
  21. encryptors-2.6/src/Osdental/Encryptor/Rsa.py +54 -0
  22. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Encryptor/Sha512.py +3 -3
  23. encryptors-2.6/src/Osdental/Enums/AuditType.py +5 -0
  24. encryptors-2.6/src/Osdental/Enums/CipherType.py +6 -0
  25. encryptors-2.6/src/Osdental/Enums/FileType.py +9 -0
  26. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Enums/GrahpqlOperation.py +2 -2
  27. encryptors-2.6/src/Osdental/Enums/Profile.py +11 -0
  28. encryptors-2.6/src/Osdental/Enums/ResultType.py +5 -0
  29. encryptors-2.6/src/Osdental/Enums/StatusCode.py +40 -0
  30. encryptors-2.6/src/Osdental/Exception/ControlledException.py +132 -0
  31. encryptors-2.6/src/Osdental/Helpers/AuditHelper.py +175 -0
  32. encryptors-2.6/src/Osdental/Helpers/AuditQueue.py +45 -0
  33. encryptors-2.6/src/Osdental/Helpers/AuthTokenProcessor.py +98 -0
  34. encryptors-2.6/src/Osdental/Helpers/AzureClassifier.py +74 -0
  35. encryptors-2.6/src/Osdental/Helpers/CipherHelper.py +40 -0
  36. {encryptors-2.1/src/Osdental/Grpc/Client → encryptors-2.6/src/Osdental/Helpers}/GrpcConnection.py +1 -1
  37. encryptors-2.6/src/Osdental/Helpers/JwtTokenHelper.py +179 -0
  38. encryptors-2.6/src/Osdental/Helpers/Resilience.py +232 -0
  39. encryptors-2.6/src/Osdental/Http/APIClient.py +163 -0
  40. encryptors-2.6/src/Osdental/Messaging/AzureServiceBus.py +146 -0
  41. encryptors-2.6/src/Osdental/Messaging/Kafka.py +11 -0
  42. encryptors-2.6/src/Osdental/Messaging/RabbitMQ.py +11 -0
  43. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Messaging/__init__.py +2 -2
  44. encryptors-2.6/src/Osdental/Models/ApiResponse.py +17 -0
  45. encryptors-2.6/src/Osdental/Models/AuditContext.py +61 -0
  46. encryptors-2.6/src/Osdental/Models/Graphql.py +12 -0
  47. encryptors-2.6/src/Osdental/Models/Notification.py +10 -0
  48. encryptors-2.6/src/Osdental/Models/Response.py +28 -0
  49. encryptors-2.6/src/Osdental/Models/Token.py +18 -0
  50. encryptors-2.6/src/Osdental/Models/TokenClaims.py +47 -0
  51. encryptors-2.6/src/Osdental/Secrets/AzureKeyVaultProvider.py +79 -0
  52. encryptors-2.6/src/Osdental/Secrets/__init__.py +7 -0
  53. encryptors-2.6/src/Osdental/Services/JwtAuthTokenService.py +170 -0
  54. encryptors-2.6/src/Osdental/Services/ServiceBusAuditEmitter.py +21 -0
  55. encryptors-2.6/src/Osdental/Services/WebsocketClient.py +45 -0
  56. encryptors-2.6/src/Osdental/Services/__init__.py +60 -0
  57. encryptors-2.6/src/Osdental/Storage/AzureBlobStorage.py +134 -0
  58. encryptors-2.6/src/Osdental/Storage/__init__.py +48 -0
  59. encryptors-2.6/src/Osdental/Utils/DataNormalizer.py +58 -0
  60. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/FileMetaData.py +14 -14
  61. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/Mapper.py +1 -1
  62. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/PasswordGenerator.py +1 -1
  63. encryptors-2.6/src/Osdental/Utils/RsaUtils.py +56 -0
  64. encryptors-2.1/src/Encryptors.egg-info/SOURCES.txt +0 -100
  65. encryptors-2.1/src/Osdental/BlobStorage/Storage.py +0 -52
  66. encryptors-2.1/src/Osdental/Cli/__init__.py +0 -505
  67. encryptors-2.1/src/Osdental/Database/__init__.py +0 -52
  68. encryptors-2.1/src/Osdental/Decorators/AuditLog.py +0 -123
  69. encryptors-2.1/src/Osdental/Decorators/DecryptedData.py +0 -101
  70. encryptors-2.1/src/Osdental/Decorators/Deprecated.py +0 -16
  71. encryptors-2.1/src/Osdental/Decorators/Grpc.py +0 -55
  72. encryptors-2.1/src/Osdental/Decorators/SqlDataNormalizer.py +0 -86
  73. encryptors-2.1/src/Osdental/Encryptor/Jwt.py +0 -26
  74. encryptors-2.1/src/Osdental/Encryptor/Rsa.py +0 -52
  75. encryptors-2.1/src/Osdental/Exception/ControlledException.py +0 -174
  76. encryptors-2.1/src/Osdental/ExternalHttp/Client.py +0 -177
  77. encryptors-2.1/src/Osdental/Grpc/Adapter/AuthGrpcAdapter.py +0 -15
  78. encryptors-2.1/src/Osdental/Grpc/Adapter/SharedGrpcAdapter.py +0 -28
  79. encryptors-2.1/src/Osdental/Grpc/Base/GrpcClientBase.py +0 -61
  80. encryptors-2.1/src/Osdental/Grpc/Client/AuthGrpcClient.py +0 -28
  81. encryptors-2.1/src/Osdental/Grpc/Client/SharedGrpcClient.py +0 -37
  82. encryptors-2.1/src/Osdental/Grpc/Dtos/GrpcResponse.py +0 -8
  83. encryptors-2.1/src/Osdental/Grpc/Generated/Auth_pb2.py +0 -40
  84. encryptors-2.1/src/Osdental/Grpc/Generated/Auth_pb2_grpc.py +0 -97
  85. encryptors-2.1/src/Osdental/Grpc/Generated/Common_pb2.py +0 -40
  86. encryptors-2.1/src/Osdental/Grpc/Generated/Common_pb2_grpc.py +0 -24
  87. encryptors-2.1/src/Osdental/Grpc/Generated/Shared_pb2.py +0 -46
  88. encryptors-2.1/src/Osdental/Grpc/Generated/Shared_pb2_grpc.py +0 -269
  89. encryptors-2.1/src/Osdental/Helpers/AuditLogHelper.py +0 -75
  90. encryptors-2.1/src/Osdental/Helpers/AuditQueueHelper.py +0 -9
  91. encryptors-2.1/src/Osdental/Helpers/DecryptedHelper.py +0 -147
  92. encryptors-2.1/src/Osdental/Helpers/EncryptorHelper.py +0 -24
  93. encryptors-2.1/src/Osdental/Helpers/RequestHelper.py +0 -131
  94. encryptors-2.1/src/Osdental/Helpers/__init__.py +0 -0
  95. encryptors-2.1/src/Osdental/InternalHttp/Request.py +0 -62
  96. encryptors-2.1/src/Osdental/InternalHttp/Response.py +0 -42
  97. encryptors-2.1/src/Osdental/InternalHttp/__init__.py +0 -0
  98. encryptors-2.1/src/Osdental/Messaging/AuditServiceBus.py +0 -31
  99. encryptors-2.1/src/Osdental/Messaging/AzureServiceBus.py +0 -57
  100. encryptors-2.1/src/Osdental/Messaging/Kafka.py +0 -12
  101. encryptors-2.1/src/Osdental/Messaging/RabbitMQ.py +0 -12
  102. encryptors-2.1/src/Osdental/Models/Encryptor.py +0 -12
  103. encryptors-2.1/src/Osdental/Models/Legacy.py +0 -16
  104. encryptors-2.1/src/Osdental/Models/Response.py +0 -13
  105. encryptors-2.1/src/Osdental/Models/ShardResource.py +0 -31
  106. encryptors-2.1/src/Osdental/Models/Token.py +0 -25
  107. encryptors-2.1/src/Osdental/Models/__init__.py +0 -0
  108. encryptors-2.1/src/Osdental/RedisCache/Redis.py +0 -97
  109. encryptors-2.1/src/Osdental/RedisCache/__init__.py +0 -0
  110. encryptors-2.1/src/Osdental/ServicesBus/ServicesBus.py +0 -21
  111. encryptors-2.1/src/Osdental/ServicesBus/__init__.py +0 -0
  112. encryptors-2.1/src/Osdental/Shared/Config/__init__.py +0 -16
  113. encryptors-2.1/src/Osdental/Shared/Enums/App.py +0 -11
  114. encryptors-2.1/src/Osdental/Shared/Enums/Code.py +0 -25
  115. encryptors-2.1/src/Osdental/Shared/Enums/Constant.py +0 -16
  116. encryptors-2.1/src/Osdental/Shared/Enums/FileType.py +0 -9
  117. encryptors-2.1/src/Osdental/Shared/Enums/Message.py +0 -39
  118. encryptors-2.1/src/Osdental/Shared/Enums/Profile.py +0 -10
  119. encryptors-2.1/src/Osdental/Shared/Enums/__init__.py +0 -0
  120. encryptors-2.1/src/Osdental/Shared/Instance.py +0 -36
  121. encryptors-2.1/src/Osdental/Shared/Logger.py +0 -3
  122. encryptors-2.1/src/Osdental/Shared/Utils/__init__.py +0 -0
  123. encryptors-2.1/src/Osdental/Shared/__init__.py +0 -0
  124. encryptors-2.1/src/Osdental/Storage/AzureBlobStorage.py +0 -50
  125. encryptors-2.1/src/Osdental/Storage/__init__.py +0 -20
  126. encryptors-2.1/src/Osdental/__init__.py +0 -0
  127. {encryptors-2.1 → encryptors-2.6}/README.md +0 -0
  128. {encryptors-2.1 → encryptors-2.6}/setup.cfg +0 -0
  129. {encryptors-2.1 → encryptors-2.6}/src/Encryptors.egg-info/dependency_links.txt +0 -0
  130. {encryptors-2.1 → encryptors-2.6}/src/Encryptors.egg-info/entry_points.txt +0 -0
  131. {encryptors-2.1 → encryptors-2.6}/src/Encryptors.egg-info/top_level.txt +0 -0
  132. {encryptors-2.1/src/Osdental/BlobStorage → encryptors-2.6/src/Osdental/Constants}/__init__.py +0 -0
  133. {encryptors-2.1/src/Osdental/Decorators → encryptors-2.6/src/Osdental/Database}/__init__.py +0 -0
  134. {encryptors-2.1/src/Osdental/Encryptor → encryptors-2.6/src/Osdental/Decorators}/__init__.py +0 -0
  135. {encryptors-2.1/src/Osdental/Exception → encryptors-2.6/src/Osdental/Encryptor}/__init__.py +0 -0
  136. {encryptors-2.1/src/Osdental/ExternalHttp → encryptors-2.6/src/Osdental/Enums}/__init__.py +0 -0
  137. {encryptors-2.1/src/Osdental/Grpc/Adapter → encryptors-2.6/src/Osdental/Exception}/__init__.py +0 -0
  138. {encryptors-2.1/src/Osdental/Grpc/Base → encryptors-2.6/src/Osdental/Helpers}/__init__.py +0 -0
  139. {encryptors-2.1/src/Osdental/Grpc/Client → encryptors-2.6/src/Osdental/Http}/__init__.py +0 -0
  140. {encryptors-2.1/src/Osdental/Grpc/Dtos → encryptors-2.6/src/Osdental/Models}/__init__.py +0 -0
  141. {encryptors-2.1 → encryptors-2.6}/src/Osdental/Storage/S3Storage.py +0 -0
  142. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/CaseConverter.py +0 -0
  143. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/CodeGenerator.py +0 -0
  144. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/DataUtils.py +0 -0
  145. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/DateUtils.py +0 -0
  146. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/HashValidator.py +0 -0
  147. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/QueryGenerator.py +0 -0
  148. {encryptors-2.1/src/Osdental/Shared → encryptors-2.6/src/Osdental}/Utils/TextProcessor.py +0 -0
  149. {encryptors-2.1/src/Osdental/Grpc/Generated → encryptors-2.6/src/Osdental/Utils}/__init__.py +0 -0
  150. {encryptors-2.1/src/Osdental/Grpc → encryptors-2.6/src/Osdental}/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.1
3
+ Version: 2.6
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -16,6 +16,8 @@ Requires-Dist: ariadne==0.26.2
16
16
  Requires-Dist: azure-core==1.32.0
17
17
  Requires-Dist: azure-servicebus==7.13.0
18
18
  Requires-Dist: azure-storage-blob==12.24.0
19
+ Requires-Dist: azure-identity<2,>=1.24
20
+ Requires-Dist: azure-keyvault-secrets==4.10.0
19
21
  Requires-Dist: certifi==2024.12.14
20
22
  Requires-Dist: cffi==1.17.1
21
23
  Requires-Dist: charset-normalizer==3.4.1
@@ -30,9 +32,10 @@ Requires-Dist: isodate==0.7.2
30
32
  Requires-Dist: pycparser==2.22
31
33
  Requires-Dist: pydantic==2.12.2
32
34
  Requires-Dist: pydantic_core==2.41.4
33
- Requires-Dist: PyJWT==2.10.1
35
+ Requires-Dist: PyJWT~=2.12.0
34
36
  Requires-Dist: aioodbc==0.5.0
35
37
  Requires-Dist: python-dotenv==1.0.1
38
+ Requires-Dist: pydantic_settings==2.13.1
36
39
  Requires-Dist: requests==2.32.3
37
40
  Requires-Dist: six==1.17.0
38
41
  Requires-Dist: sniffio==1.3.1
@@ -40,8 +43,10 @@ Requires-Dist: SQLAlchemy==2.0.36
40
43
  Requires-Dist: starlette==0.41.3
41
44
  Requires-Dist: tenacity==9.1.2
42
45
  Requires-Dist: typing_extensions==4.15.0
46
+ Requires-Dist: tzlocal==5.2
43
47
  Requires-Dist: urllib3==2.3.0
44
- Requires-Dist: redis==5.2.1
48
+ Requires-Dist: redis<8,>=5
49
+ Requires-Dist: redis-entraid==1.1.2
45
50
  Requires-Dist: colorlog==6.9.0
46
51
  Requires-Dist: click==8.2.0
47
52
  Requires-Dist: grpcio==1.75.0
@@ -52,6 +57,7 @@ Requires-Dist: bcrypt==4.3.0
52
57
  Requires-Dist: azure-monitor-opentelemetry==1.8.1
53
58
  Requires-Dist: uvicorn==0.37.0
54
59
  Requires-Dist: gunicorn==23.0.0
60
+ Requires-Dist: joserfc==1.5.0
55
61
  Dynamic: author
56
62
  Dynamic: author-email
57
63
  Dynamic: classifier
@@ -1,8 +1,8 @@
1
1
  from setuptools import setup, find_packages
2
-
2
+ # ANDERSON REVISAR EL CACHE LOCAL DEL KEYVAULT PARA VALIDAR SI FUNCIONA
3
3
  setup(
4
4
  name="Encryptors",
5
- version="2.1",
5
+ version="2.6",
6
6
  author="OSDental LLC",
7
7
  author_email="support@osdental.ai",
8
8
  description="End-to-end algorithm library",
@@ -19,11 +19,13 @@ setup(
19
19
  install_requires=[
20
20
  "aiohttp==3.11.12",
21
21
  "annotated-types==0.7.0",
22
- "anyio==4.7.0",
22
+ "anyio==4.7.0",
23
23
  "ariadne==0.26.2",
24
24
  "azure-core==1.32.0",
25
25
  "azure-servicebus==7.13.0",
26
26
  "azure-storage-blob==12.24.0",
27
+ "azure-identity>=1.24,<2",
28
+ "azure-keyvault-secrets==4.10.0",
27
29
  "certifi==2024.12.14",
28
30
  "cffi==1.17.1",
29
31
  "charset-normalizer==3.4.1",
@@ -38,9 +40,10 @@ setup(
38
40
  "pycparser==2.22",
39
41
  "pydantic==2.12.2",
40
42
  "pydantic_core==2.41.4",
41
- "PyJWT==2.10.1",
43
+ "PyJWT~=2.12.0",
42
44
  "aioodbc==0.5.0",
43
45
  "python-dotenv==1.0.1",
46
+ "pydantic_settings==2.13.1",
44
47
  "requests==2.32.3",
45
48
  "six==1.17.0",
46
49
  "sniffio==1.3.1",
@@ -48,8 +51,10 @@ setup(
48
51
  "starlette==0.41.3",
49
52
  "tenacity==9.1.2",
50
53
  "typing_extensions==4.15.0",
54
+ "tzlocal==5.2",
51
55
  "urllib3==2.3.0",
52
- "redis==5.2.1",
56
+ "redis>=5,<8",
57
+ "redis-entraid==1.1.2",
53
58
  "colorlog==6.9.0",
54
59
  "click==8.2.0",
55
60
  "grpcio==1.75.0",
@@ -59,7 +64,8 @@ setup(
59
64
  "bcrypt==4.3.0",
60
65
  "azure-monitor-opentelemetry==1.8.1",
61
66
  "uvicorn==0.37.0",
62
- "gunicorn==23.0.0"
67
+ "gunicorn==23.0.0",
68
+ "joserfc==1.5.0",
63
69
  ],
64
70
  entry_points={
65
71
  'console_scripts': [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.1
3
+ Version: 2.6
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -16,6 +16,8 @@ Requires-Dist: ariadne==0.26.2
16
16
  Requires-Dist: azure-core==1.32.0
17
17
  Requires-Dist: azure-servicebus==7.13.0
18
18
  Requires-Dist: azure-storage-blob==12.24.0
19
+ Requires-Dist: azure-identity<2,>=1.24
20
+ Requires-Dist: azure-keyvault-secrets==4.10.0
19
21
  Requires-Dist: certifi==2024.12.14
20
22
  Requires-Dist: cffi==1.17.1
21
23
  Requires-Dist: charset-normalizer==3.4.1
@@ -30,9 +32,10 @@ Requires-Dist: isodate==0.7.2
30
32
  Requires-Dist: pycparser==2.22
31
33
  Requires-Dist: pydantic==2.12.2
32
34
  Requires-Dist: pydantic_core==2.41.4
33
- Requires-Dist: PyJWT==2.10.1
35
+ Requires-Dist: PyJWT~=2.12.0
34
36
  Requires-Dist: aioodbc==0.5.0
35
37
  Requires-Dist: python-dotenv==1.0.1
38
+ Requires-Dist: pydantic_settings==2.13.1
36
39
  Requires-Dist: requests==2.32.3
37
40
  Requires-Dist: six==1.17.0
38
41
  Requires-Dist: sniffio==1.3.1
@@ -40,8 +43,10 @@ Requires-Dist: SQLAlchemy==2.0.36
40
43
  Requires-Dist: starlette==0.41.3
41
44
  Requires-Dist: tenacity==9.1.2
42
45
  Requires-Dist: typing_extensions==4.15.0
46
+ Requires-Dist: tzlocal==5.2
43
47
  Requires-Dist: urllib3==2.3.0
44
- Requires-Dist: redis==5.2.1
48
+ Requires-Dist: redis<8,>=5
49
+ Requires-Dist: redis-entraid==1.1.2
45
50
  Requires-Dist: colorlog==6.9.0
46
51
  Requires-Dist: click==8.2.0
47
52
  Requires-Dist: grpcio==1.75.0
@@ -52,6 +57,7 @@ Requires-Dist: bcrypt==4.3.0
52
57
  Requires-Dist: azure-monitor-opentelemetry==1.8.1
53
58
  Requires-Dist: uvicorn==0.37.0
54
59
  Requires-Dist: gunicorn==23.0.0
60
+ Requires-Dist: joserfc==1.5.0
55
61
  Dynamic: author
56
62
  Dynamic: author-email
57
63
  Dynamic: classifier
@@ -0,0 +1,85 @@
1
+ README.md
2
+ setup.py
3
+ src/Encryptors.egg-info/PKG-INFO
4
+ src/Encryptors.egg-info/SOURCES.txt
5
+ src/Encryptors.egg-info/dependency_links.txt
6
+ src/Encryptors.egg-info/entry_points.txt
7
+ src/Encryptors.egg-info/requires.txt
8
+ src/Encryptors.egg-info/top_level.txt
9
+ src/Osdental/__init__.py
10
+ src/Osdental/Cache/Redis.py
11
+ src/Osdental/Cache/__init__.py
12
+ src/Osdental/Cli/__init__.py
13
+ src/Osdental/Constants/Constant.py
14
+ src/Osdental/Constants/Message.py
15
+ src/Osdental/Constants/__init__.py
16
+ src/Osdental/Context/__init__.py
17
+ src/Osdental/Database/BaseRepository.py
18
+ src/Osdental/Database/Connection.py
19
+ src/Osdental/Database/__init__.py
20
+ src/Osdental/Decorators/Grpc.py
21
+ src/Osdental/Decorators/Retry.py
22
+ src/Osdental/Decorators/SecureResolver.py
23
+ src/Osdental/Decorators/__init__.py
24
+ src/Osdental/Encryptor/Aes.py
25
+ src/Osdental/Encryptor/Argon2.py
26
+ src/Osdental/Encryptor/Bcrypt.py
27
+ src/Osdental/Encryptor/Jwt.py
28
+ src/Osdental/Encryptor/Rsa.py
29
+ src/Osdental/Encryptor/Sha512.py
30
+ src/Osdental/Encryptor/__init__.py
31
+ src/Osdental/Enums/AuditType.py
32
+ src/Osdental/Enums/CipherType.py
33
+ src/Osdental/Enums/FileType.py
34
+ src/Osdental/Enums/GrahpqlOperation.py
35
+ src/Osdental/Enums/Profile.py
36
+ src/Osdental/Enums/ResultType.py
37
+ src/Osdental/Enums/StatusCode.py
38
+ src/Osdental/Enums/__init__.py
39
+ src/Osdental/Exception/ControlledException.py
40
+ src/Osdental/Exception/__init__.py
41
+ src/Osdental/Helpers/AuditHelper.py
42
+ src/Osdental/Helpers/AuditQueue.py
43
+ src/Osdental/Helpers/AuthTokenProcessor.py
44
+ src/Osdental/Helpers/AzureClassifier.py
45
+ src/Osdental/Helpers/CipherHelper.py
46
+ src/Osdental/Helpers/GrpcConnection.py
47
+ src/Osdental/Helpers/JwtTokenHelper.py
48
+ src/Osdental/Helpers/Resilience.py
49
+ src/Osdental/Helpers/__init__.py
50
+ src/Osdental/Http/APIClient.py
51
+ src/Osdental/Http/__init__.py
52
+ src/Osdental/Messaging/AzureServiceBus.py
53
+ src/Osdental/Messaging/Kafka.py
54
+ src/Osdental/Messaging/RabbitMQ.py
55
+ src/Osdental/Messaging/__init__.py
56
+ src/Osdental/Models/ApiResponse.py
57
+ src/Osdental/Models/AuditContext.py
58
+ src/Osdental/Models/Graphql.py
59
+ src/Osdental/Models/Notification.py
60
+ src/Osdental/Models/Response.py
61
+ src/Osdental/Models/Token.py
62
+ src/Osdental/Models/TokenClaims.py
63
+ src/Osdental/Models/__init__.py
64
+ src/Osdental/Secrets/AzureKeyVaultProvider.py
65
+ src/Osdental/Secrets/__init__.py
66
+ src/Osdental/Services/JwtAuthTokenService.py
67
+ src/Osdental/Services/ServiceBusAuditEmitter.py
68
+ src/Osdental/Services/WebsocketClient.py
69
+ src/Osdental/Services/__init__.py
70
+ src/Osdental/Storage/AzureBlobStorage.py
71
+ src/Osdental/Storage/S3Storage.py
72
+ src/Osdental/Storage/__init__.py
73
+ src/Osdental/Utils/CaseConverter.py
74
+ src/Osdental/Utils/CodeGenerator.py
75
+ src/Osdental/Utils/DataNormalizer.py
76
+ src/Osdental/Utils/DataUtils.py
77
+ src/Osdental/Utils/DateUtils.py
78
+ src/Osdental/Utils/FileMetaData.py
79
+ src/Osdental/Utils/HashValidator.py
80
+ src/Osdental/Utils/Mapper.py
81
+ src/Osdental/Utils/PasswordGenerator.py
82
+ src/Osdental/Utils/QueryGenerator.py
83
+ src/Osdental/Utils/RsaUtils.py
84
+ src/Osdental/Utils/TextProcessor.py
85
+ src/Osdental/Utils/__init__.py
@@ -5,6 +5,8 @@ ariadne==0.26.2
5
5
  azure-core==1.32.0
6
6
  azure-servicebus==7.13.0
7
7
  azure-storage-blob==12.24.0
8
+ azure-identity<2,>=1.24
9
+ azure-keyvault-secrets==4.10.0
8
10
  certifi==2024.12.14
9
11
  cffi==1.17.1
10
12
  charset-normalizer==3.4.1
@@ -19,9 +21,10 @@ isodate==0.7.2
19
21
  pycparser==2.22
20
22
  pydantic==2.12.2
21
23
  pydantic_core==2.41.4
22
- PyJWT==2.10.1
24
+ PyJWT~=2.12.0
23
25
  aioodbc==0.5.0
24
26
  python-dotenv==1.0.1
27
+ pydantic_settings==2.13.1
25
28
  requests==2.32.3
26
29
  six==1.17.0
27
30
  sniffio==1.3.1
@@ -29,8 +32,10 @@ SQLAlchemy==2.0.36
29
32
  starlette==0.41.3
30
33
  tenacity==9.1.2
31
34
  typing_extensions==4.15.0
35
+ tzlocal==5.2
32
36
  urllib3==2.3.0
33
- redis==5.2.1
37
+ redis<8,>=5
38
+ redis-entraid==1.1.2
34
39
  colorlog==6.9.0
35
40
  click==8.2.0
36
41
  grpcio==1.75.0
@@ -41,3 +46,4 @@ bcrypt==4.3.0
41
46
  azure-monitor-opentelemetry==1.8.1
42
47
  uvicorn==0.37.0
43
48
  gunicorn==23.0.0
49
+ joserfc==1.5.0
@@ -0,0 +1,316 @@
1
+ import logging
2
+ import asyncio
3
+ import json
4
+ from typing import Dict, List, Optional, Any
5
+ import redis.asyncio as redis
6
+ from redis_entraid.cred_provider import (
7
+ create_from_default_azure_credential
8
+ )
9
+ from Osdental.Cache import ICacheService
10
+ from Osdental.Helpers.Resilience import AzureResiliencePolicy, AzureTransientError
11
+ from Osdental.Helpers.AzureClassifier import classify_redis
12
+
13
+
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ class RedisCacheAsync(ICacheService):
18
+
19
+ _instances: Dict[str, "RedisCacheAsync"] = {}
20
+ _lock = asyncio.Lock()
21
+
22
+
23
+ def __new__(cls, redis_host: str, redis_port: int = 6380):
24
+
25
+ key = f"{redis_host}:{redis_port}"
26
+
27
+ if key not in cls._instances:
28
+ cls._instances[key] = super().__new__(cls)
29
+
30
+ return cls._instances[key]
31
+
32
+ def __init__(
33
+ self,
34
+ redis_host: str,
35
+ redis_port: int = 6380
36
+ ):
37
+
38
+ if hasattr(self, "_initialized"):
39
+ return
40
+
41
+ self.redis_host = redis_host
42
+ self.redis_port = redis_port
43
+
44
+ self.client = None
45
+
46
+ self._policy = AzureResiliencePolicy(
47
+ "redis-cache",
48
+ max_attempts=3,
49
+ base_delay=0.5,
50
+ failure_threshold=5,
51
+ )
52
+
53
+ self._initialized = True
54
+ self._reconnect_lock = asyncio.Lock()
55
+
56
+
57
+ async def _call(self, func, *args, **kwargs):
58
+ """
59
+ Ejecuta una operación de Redis a través de la policy.
60
+ Clasifica el error y deja que la policy decida si reintenta.
61
+ """
62
+ await self._ensure_connection()
63
+
64
+ async def _inner():
65
+ try:
66
+ return await func(*args, **kwargs)
67
+ except Exception as exc:
68
+ raise classify_redis(exc)
69
+
70
+ try:
71
+ return await self._policy.execute(_inner)
72
+ except AzureTransientError as exc:
73
+ try:
74
+ await self._reconnect()
75
+
76
+ except Exception as reconnect_exc:
77
+ logger.exception(
78
+ "redis.reconnect.failed error=%s",
79
+ reconnect_exc
80
+ )
81
+
82
+ logger.exception(
83
+ "redis.exhausted error=%s",
84
+ exc
85
+ )
86
+
87
+
88
+
89
+ async def connect(self):
90
+ if self.client:
91
+ return
92
+
93
+ async with self._lock:
94
+
95
+ if self.client:
96
+ return
97
+
98
+ try:
99
+ credential_provider = (
100
+ create_from_default_azure_credential(
101
+ ("https://redis.azure.com/.default",)
102
+ )
103
+ )
104
+
105
+ self.client = redis.Redis(
106
+ host=self.redis_host,
107
+ port=self.redis_port,
108
+ ssl=True,
109
+ credential_provider=credential_provider,
110
+ decode_responses=True,
111
+ health_check_interval=30,
112
+ retry_on_timeout=True,
113
+ socket_connect_timeout=5,
114
+ socket_timeout=5,
115
+ max_connections=100,
116
+ socket_keepalive=True
117
+ )
118
+
119
+ await self.client.ping()
120
+
121
+ logger.info(
122
+ "Redis connected with Managed Identity"
123
+ )
124
+
125
+ except Exception as e:
126
+ self.client = None
127
+
128
+ logger.exception(
129
+ f"Redis connection error: {str(e)}"
130
+ )
131
+
132
+ raise e
133
+
134
+ async def _ensure_connection(self):
135
+
136
+ if not self.client:
137
+ await self.connect()
138
+
139
+ async def set_dict(
140
+ self,
141
+ key: str,
142
+ value: Dict[str, Any],
143
+ ttl: Optional[int] = None
144
+ ):
145
+
146
+ await self._call(
147
+ self.client.set,
148
+ key,
149
+ json.dumps(value),
150
+ ex=ttl
151
+ )
152
+
153
+
154
+ async def set_str(
155
+ self,
156
+ key: str,
157
+ value: str,
158
+ ttl: Optional[int] = None
159
+ ):
160
+
161
+ await self._call(
162
+ self.client.set,
163
+ key,
164
+ value,
165
+ ex=ttl
166
+ )
167
+
168
+ async def get_dict(
169
+ self,
170
+ key: str
171
+ ) -> Optional[Dict[str, Any]]:
172
+
173
+ value = await self._call(
174
+ self.client.get,
175
+ key
176
+ )
177
+
178
+ try:
179
+ return json.loads(value) if value else None
180
+
181
+ except json.JSONDecodeError:
182
+ logger.error(
183
+ "redis.invalid_json key=%s",
184
+ key
185
+ )
186
+ return None
187
+
188
+
189
+ async def get_str(
190
+ self,
191
+ key: str
192
+ ) -> Optional[str]:
193
+
194
+ return await self._call(
195
+ self.client.get,
196
+ key
197
+ )
198
+
199
+
200
+ async def delete(self, key: str) -> bool:
201
+
202
+ result = await self._call(
203
+ self.client.delete,
204
+ key
205
+ )
206
+
207
+ return result > 0
208
+
209
+
210
+ async def exists(self, key: str) -> bool:
211
+
212
+ result = await self._call(
213
+ self.client.exists,
214
+ key
215
+ )
216
+
217
+ return result > 0
218
+
219
+
220
+ async def flush(self):
221
+
222
+ await self._call(
223
+ self.client.flushdb
224
+ )
225
+
226
+
227
+ async def flush_all(self):
228
+
229
+ await self._call(
230
+ self.client.flushall
231
+ )
232
+
233
+
234
+ async def mget(
235
+ self,
236
+ keys: List[str]
237
+ ) -> List[Optional[Any]]:
238
+
239
+ values = await self._call(
240
+ self.client.mget,
241
+ keys
242
+ )
243
+
244
+ return [
245
+ json.loads(value)
246
+ if value else None
247
+ for value in values
248
+ ]
249
+
250
+
251
+ async def clear_cache(self, prefix: str):
252
+
253
+ await self._ensure_connection()
254
+
255
+ async for key in self._scan_keys(
256
+ match=f"{prefix}*"
257
+ ):
258
+
259
+ await self._call(
260
+ self.client.delete,
261
+ key
262
+ )
263
+
264
+
265
+ async def _scan_keys(self, match: str = "*"):
266
+
267
+ async for key in self.client.scan_iter(
268
+ match=match
269
+ ):
270
+ yield key
271
+
272
+
273
+ async def _reconnect(self):
274
+
275
+ async with self._reconnect_lock:
276
+
277
+ try:
278
+
279
+ if self.client:
280
+ await self.client.ping()
281
+ return
282
+
283
+ except Exception:
284
+ pass
285
+
286
+ try:
287
+
288
+ if self.client:
289
+ await self.client.aclose()
290
+
291
+ except Exception:
292
+ pass
293
+
294
+ self.client = None
295
+
296
+ await self.connect()
297
+
298
+ async def close(self):
299
+
300
+ try:
301
+
302
+ if self.client:
303
+
304
+ await self.client.aclose()
305
+
306
+ self.client = None
307
+
308
+ logger.info(
309
+ "Redis connection closed"
310
+ )
311
+
312
+ except Exception as e:
313
+
314
+ logger.exception(
315
+ f"Redis close error: {str(e)}"
316
+ )
@@ -0,0 +1,53 @@
1
+ from typing import Protocol, Optional, Dict, List, Any
2
+
3
+
4
+ class ICacheService(Protocol):
5
+
6
+ async def set_dict(self, key: str, value: Dict[str, Any], ttl: Optional[int] = None):
7
+ """Set a JSON value in the cache."""
8
+ pass
9
+
10
+ async def set_str(self, key: str, value: str, ttl: Optional[int] = None):
11
+ """Set a string value in the cache."""
12
+ pass
13
+
14
+ async def get_dict(self, key: str) -> Optional[Dict[str, Any]]:
15
+ """Get a JSON value from the cache and convert it back to a Python object."""
16
+ pass
17
+
18
+
19
+ async def get_str(self, key: str) -> Optional[str]:
20
+ """Get a string value from the cache."""
21
+ pass
22
+
23
+ async def delete(self, key: str) -> bool:
24
+ """Delete a value from the cache."""
25
+ pass
26
+
27
+ async def exists(self, key: str) -> bool:
28
+ """Check if a key exists in the cache."""
29
+ pass
30
+
31
+ async def flush(self):
32
+ """Flush all keys in the cache."""
33
+ pass
34
+
35
+ async def flush_all(self):
36
+ """Flush all keys in all Redis databases."""
37
+ pass
38
+
39
+ async def mget(self, keys:List[str]) -> List[Optional[str]]:
40
+ """Get multiple values from the cache."""
41
+ pass
42
+
43
+ async def clear_cache(self, prefix: str):
44
+ """Delete all keys matching the given prefix."""
45
+ pass
46
+
47
+ async def _scan_keys(self, match: str = "*"):
48
+ """Asynchronous generator to scan keys matching a pattern."""
49
+ pass
50
+
51
+ async def close(self):
52
+ """Close the connection pool and Redis client."""
53
+ pass