finalsa-common-models 1.0.1__py3-none-any.whl → 2.0.1__py3-none-any.whl

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.
@@ -1,15 +1,18 @@
1
1
  from finalsa.common.models.models import (
2
- SqsMessage,
2
+ Meta,
3
3
  SqsReponse,
4
- parse_message_attributes,
5
- to_message_attributes
4
+ parse_sns_message_attributes,
5
+ parse_sqs_message_attributes,
6
+ to_sqs_message_attributes,
7
+ to_sns_message_attributes,
6
8
  )
7
9
 
8
- __version__ = "1.0.1"
9
10
 
10
11
  __all__ = [
11
- "SqsMessage",
12
+ "Meta",
12
13
  "SqsReponse",
13
- "parse_message_attributes",
14
- "to_message_attributes",
14
+ "parse_sns_message_attributes",
15
+ "parse_sqs_message_attributes",
16
+ "to_sqs_message_attributes",
17
+ "to_sns_message_attributes",
15
18
  ]
@@ -1,3 +1,12 @@
1
- from .functions import parse_message_attributes, to_message_attributes
2
- from .sqs_message import SqsMessage
1
+ from .functions import parse_sns_message_attributes, parse_sqs_message_attributes, to_sqs_message_attributes, to_sns_message_attributes
3
2
  from .sqs_response import SqsReponse
3
+ from .meta import Meta
4
+
5
+ __all__ = [
6
+ "Meta",
7
+ "SqsReponse",
8
+ "parse_sns_message_attributes",
9
+ "parse_sqs_message_attributes",
10
+ "to_sqs_message_attributes",
11
+ "to_sns_message_attributes"
12
+ ]
@@ -4,7 +4,7 @@ from decimal import Decimal
4
4
  from uuid import UUID
5
5
 
6
6
 
7
- def parse_message_attributes(attributes: Dict) -> Dict:
7
+ def parse_sns_message_attributes(attributes: Dict) -> Dict:
8
8
  message_attributes = {}
9
9
  if not attributes:
10
10
  return message_attributes
@@ -17,8 +17,20 @@ def parse_message_attributes(attributes: Dict) -> Dict:
17
17
  message_attributes[key] = bytes(value['Value'], 'utf-8')
18
18
  return message_attributes
19
19
 
20
+ def parse_sqs_message_attributes(attributes: Dict) -> Dict:
21
+ message_attributes = {}
22
+ if not attributes:
23
+ return message_attributes
24
+ for key, value in attributes.items():
25
+ if value['DataType'] == 'String':
26
+ message_attributes[key] = value['StringValue']
27
+ elif value['DataType'] == 'Number':
28
+ message_attributes[key] = int(value['StringValue'])
29
+ elif value['DataType'] == 'Binary':
30
+ message_attributes[key] = bytes(value['StringValue'], 'utf-8')
31
+ return message_attributes
20
32
 
21
- def to_message_attributes(attributes: Dict) -> Dict:
33
+ def to_sqs_message_attributes(attributes: Dict) -> Dict:
22
34
  att_dict = {}
23
35
  for key, value in attributes.items():
24
36
  if isinstance(value, str):
@@ -40,3 +52,28 @@ def to_message_attributes(attributes: Dict) -> Dict:
40
52
  att_dict[key] = {
41
53
  'DataType': 'Binary', 'BinaryValue': value}
42
54
  return att_dict
55
+
56
+
57
+
58
+ def to_sns_message_attributes(attributes: Dict) -> Dict:
59
+ att_dict = {}
60
+ for key, value in attributes.items():
61
+ if isinstance(value, str):
62
+ att_dict[key] = {
63
+ 'Type': 'String', 'Value': value}
64
+ elif isinstance(value, Decimal):
65
+ att_dict[key] = {
66
+ 'Type': 'Number', 'Value': str(value)}
67
+ elif isinstance(value, UUID):
68
+ att_dict[key] = {
69
+ 'Type': 'String', 'Value': str(value)}
70
+ elif isinstance(value, datetime):
71
+ att_dict[key] = {
72
+ 'Type': 'String', 'Value': value.isoformat()}
73
+ elif isinstance(value, int):
74
+ att_dict[key] = {
75
+ 'Type': 'Number', 'Value': str(value)}
76
+ elif isinstance(value, bytes):
77
+ att_dict[key] = {
78
+ 'Type': 'Binary', 'Value': value}
79
+ return att_dict
@@ -0,0 +1,10 @@
1
+ from pydantic import BaseModel
2
+ from datetime import datetime
3
+ from typing import Optional
4
+
5
+
6
+ class Meta(BaseModel):
7
+ authorization: Optional[dict] = {}
8
+ timestamp: datetime
9
+ correlation_id: str
10
+ ip: str
@@ -1,10 +1,7 @@
1
- from datetime import datetime, timezone
2
1
  from typing import Dict, Optional, Union
3
- from uuid import UUID, uuid4
4
2
  from pydantic import BaseModel
5
- from json import loads
6
- from .sqs_message import SqsMessage
7
- from .functions import parse_message_attributes
3
+ from orjson import loads
4
+ from .functions import parse_sqs_message_attributes, parse_sns_message_attributes
8
5
 
9
6
 
10
7
  class SqsReponse(BaseModel):
@@ -17,38 +14,10 @@ class SqsReponse(BaseModel):
17
14
  md5_of_message_attributes: Optional[str] = ""
18
15
  message_attributes: Optional[Dict] = {}
19
16
 
20
- @staticmethod
21
- def correlation_id_from_attributes(attributes: Dict) -> Optional[str]:
22
- correlation_id = attributes.get('correlation_id', None)
23
- if not correlation_id:
24
- return None
25
- if isinstance(correlation_id, str):
26
- return correlation_id
27
- if isinstance(correlation_id, dict) and 'Type' in correlation_id and 'Value' in correlation_id:
28
- return correlation_id["Value"]
29
- return None
30
-
31
- def get_correlation_id(self, payload: Optional[Dict] = {}) -> Union[str, UUID]:
32
- correlation_id = self.correlation_id_from_attributes(self.message_attributes)
33
- if correlation_id:
34
- return correlation_id
35
- correlation_id = self.correlation_id_from_attributes(self.attributes)
36
- if correlation_id:
37
- return correlation_id
38
- if 'correlation_id' in payload:
39
- return payload['correlation_id']
40
- return str(uuid4())
41
-
42
17
  @staticmethod
43
18
  def __is_sns_message__(content: Dict) -> bool:
44
19
  return 'Type' in content and content['Type'] == 'Notification'
45
20
 
46
- @staticmethod
47
- def __is_sqs_message__(content: Dict) -> bool:
48
- return ('id' in content and
49
- 'topic' in content and
50
- 'payload' in content)
51
-
52
21
  def parse_from_sns(self) -> Dict:
53
22
  payload = loads(self.body)
54
23
  if self.__is_sns_message__(payload):
@@ -57,7 +26,7 @@ class SqsReponse(BaseModel):
57
26
 
58
27
  def __parse_from_sns__(self, payload: Dict) -> Union[str, Dict]:
59
28
  self.topic = str(payload['TopicArn'].split(':')[-1]).lower()
60
- self.message_attributes = parse_message_attributes(
29
+ self.message_attributes = parse_sns_message_attributes(
61
30
  payload.get('MessageAttributes', {}))
62
31
  try:
63
32
  return loads(payload['Message'])
@@ -70,34 +39,15 @@ class SqsReponse(BaseModel):
70
39
  content = self.__parse_from_sns__(content)
71
40
  return content
72
41
 
73
- def __get_sqs_message__(self, content: Union[str, Dict]) -> SqsMessage:
74
-
75
- if isinstance(content, dict) and self.__is_sqs_message__(content):
76
- if 'correlation_id' not in content:
77
- content['correlation_id'] = str(self.get_correlation_id(content))
78
- return SqsMessage(
79
- id=UUID(content['id']),
80
- topic=content['topic'],
81
- payload=content['payload'],
82
- correlation_id=content['correlation_id'],
83
- timestamp=content.get('timestamp', datetime.now(timezone.utc).isoformat())
84
- )
85
- return SqsMessage(
86
- id=uuid4(),
87
- topic=self.topic,
88
- payload=content,
89
- correlation_id=self.get_correlation_id(content),
90
- timestamp=datetime.now(timezone.utc).isoformat()
91
- )
92
-
93
- def get_sqs_message(self) -> SqsMessage:
42
+ def get_payload(self) -> Union[str, Dict]:
94
43
  try:
95
44
  content = loads(self.body)
96
45
  except Exception:
97
- return self.__get_sqs_message__(self.body)
46
+ return self.body
98
47
  if self.__is_sns_message__(content):
99
48
  content = self.__parse_from_sns__(content)
100
- return self.__get_sqs_message__(content)
49
+ return content
50
+ return loads(self.body)
101
51
 
102
52
  @classmethod
103
53
  def from_boto_response(cls, response: Dict):
@@ -109,6 +59,6 @@ class SqsReponse(BaseModel):
109
59
  attributes=response['Attributes'],
110
60
  md5_of_message_attributes=response.get(
111
61
  'MD5OfMessageAttributes', ''),
112
- message_attributes=parse_message_attributes(
62
+ message_attributes=parse_sqs_message_attributes(
113
63
  response.get('MessageAttributes', {}))
114
64
  )
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.4
2
+ Name: finalsa-common-models
3
+ Version: 2.0.1
4
+ Summary: Common models for Finalsa
5
+ Project-URL: Homepage, https://github.com/finalsa/finalsa-common-models
6
+ Author-email: Luis Jimenez <luis@finalsa.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2025 Luis Diego Jiménez Delgado
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ License-File: LICENSE.md
29
+ Keywords: common,finalsa,models
30
+ Requires-Python: >=3.10
31
+ Requires-Dist: orjson>=3.10.16
32
+ Requires-Dist: pydantic>=2.11.1
33
+ Requires-Dist: python-dateutil>=2.9.0.post0
34
+ Description-Content-Type: text/markdown
35
+
36
+ # Finalsa Async Models
37
+
38
+ Finalsa Async Models is a Python library designed to simplify the implementation of asynchronous data models. It provides tools to handle asynchronous operations, making it easier to work with modern Python applications that rely on async/await patterns.
39
+
40
+ ## Features
41
+
42
+ - **Asynchronous Data Models**: Define and manage data models with full async support.
43
+ - **Ease of Use**: Simplified API for seamless integration into your projects.
44
+ - **Extensibility**: Easily extend and customize models to fit your needs.
45
+ - **Performance**: Optimized for high-performance asynchronous workflows.
46
+
47
+ ## Installation
48
+
49
+ Install the library using pip:
50
+
51
+ ```bash
52
+ pip install finalsa-async-models
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ Here's a quick example of how to use Finalsa Async Models:
58
+
59
+ ```python
60
+ from finalsa_async_models import AsyncModel
61
+
62
+ class User(AsyncModel):
63
+ async def save(self):
64
+ # Custom save logic
65
+ pass
66
+
67
+ # Example usage
68
+ async def main():
69
+ user = User()
70
+ await user.save()
71
+ ```
72
+
73
+ ## Documentation
74
+
75
+ For detailed documentation, visit the [official documentation](#).
76
+
77
+ ## Contributing
78
+
79
+ Contributions are welcome! Please follow the [contribution guidelines](CONTRIBUTING.md).
80
+
81
+ ## License
82
+
83
+ This project is licensed under the [MIT License](LICENSE).
84
+
85
+ ## Contact
86
+
87
+ For questions or support, please open an issue on the [GitHub repository](#).
@@ -0,0 +1,9 @@
1
+ finalsa/common/models/__init__.py,sha256=FgaW3-ykBoS6QVLLvTdje5zz85Ei0Pe8M7LtB2QOMiU,385
2
+ finalsa/common/models/models/__init__.py,sha256=75LSf90upIL2qlxyHQ_7QFUhKGHM6b3n1RE7-qEWDpk,378
3
+ finalsa/common/models/models/functions.py,sha256=vKUrhl3AVfnYBqqKYpZbZevrBpUx7ywqhtU3KKPqWUE,2983
4
+ finalsa/common/models/models/meta.py,sha256=YX62zKeu_3McVJUhGDrub897XfuGxDDKGw5AejEL48g,213
5
+ finalsa/common/models/models/sqs_response.py,sha256=GKkDyWYeYEUCRHp2H8MjxvzFuwWL1ngzpf5zILhVUNg,2258
6
+ finalsa_common_models-2.0.1.dist-info/METADATA,sha256=6ttMktELBnzxnQoT_SH9_Qf4rMl4G2hND65Qw4cOxq4,3054
7
+ finalsa_common_models-2.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
8
+ finalsa_common_models-2.0.1.dist-info/licenses/LICENSE.md,sha256=yqzhfnTBr2S4lUBx-yibVPOIXRUDPrSUN9-_7AsC6OU,1084
9
+ finalsa_common_models-2.0.1.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Luis Diego Jiménez Delgado
3
+ Copyright (c) 2025 Luis Diego Jiménez Delgado
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,27 +0,0 @@
1
- from datetime import datetime, timezone
2
- from typing import Optional, Union, Dict
3
- from uuid import UUID
4
- from pydantic import BaseModel
5
- from json import loads
6
-
7
-
8
- class SqsMessage(BaseModel):
9
- id: UUID
10
- topic: str
11
- payload: Union[str, Dict]
12
- correlation_id: str
13
- timestamp: Optional[datetime] = datetime.now(timezone.utc)
14
-
15
- def get_payload(self) -> Dict:
16
- if isinstance(self.payload, str):
17
- self.payload = loads(self.payload)
18
- return self.payload
19
-
20
- def to_dict(self):
21
- return {
22
- 'id': str(self.id),
23
- 'topic': self.topic,
24
- 'payload': self.payload,
25
- 'correlation_id': self.correlation_id,
26
- 'timestamp': self.timestamp.isoformat()
27
- }
File without changes
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2021 Luis Diego Jiménez Delgado
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,24 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: finalsa-common-models
3
- Version: 1.0.1
4
- Summary: An utils package for using finalsa common models.
5
- Home-page: https://github.com/finalsa/finalsa-common-models
6
- Author: Luis Jimenez
7
- Author-email: luis@finalsa.com
8
- License: MIT
9
- Keywords: dynamodb
10
- Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: BSD License
12
- Classifier: Operating System :: OS Independent
13
- Classifier: Topic :: Internet :: WWW/HTTP
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Requires-Python: >=3.10
20
- Description-Content-Type: text/markdown
21
- License-File: LICENSE.md
22
- Requires-Dist: boto3 >=1.20.3
23
- Requires-Dist: pydantic >=2.5.2
24
-
@@ -1,13 +0,0 @@
1
- finalsa/common/models/__init__.py,sha256=t7xlW2QlpKdaTLjg_LzBkDODCyJzBUXonyD9B-hZ80g,268
2
- finalsa/common/models/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- finalsa/common/models/models/__init__.py,sha256=Bm0KxSyueMwLkiN4W3sX5oXgLbfyQ8ZhKPD0WLhZepA,144
4
- finalsa/common/models/models/functions.py,sha256=4bA57p5ar0btRlygzzLIlImQxOTypH3EQUyzys-ryE8,1551
5
- finalsa/common/models/models/sqs_message.py,sha256=0E2dx_Ml55rNn6dG7jMQH9jL28bLECiZDAgNprBGSpM,742
6
- finalsa/common/models/models/sqs_response.py,sha256=k5yK6Q2g2mx_nwam4ma1w2SN4VrNnRYWA73aCcoulrc,4301
7
- finalsa_common_models-1.0.1.data/data/LICENSE.md,sha256=_lu-V-f2tGID1BS2V_W6D2XWppBsylFF1J2KEpfIXN0,1084
8
- finalsa_common_models-1.0.1.dist-info/LICENSE.md,sha256=_lu-V-f2tGID1BS2V_W6D2XWppBsylFF1J2KEpfIXN0,1084
9
- finalsa_common_models-1.0.1.dist-info/METADATA,sha256=bQS7iUthb32aQxkOkjm6FZYT0NIhyiFtnRDY0DFbXhE,853
10
- finalsa_common_models-1.0.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
11
- finalsa_common_models-1.0.1.dist-info/top_level.txt,sha256=P7YD1HSd4CVujGFG9Vl9hJlg5OVCGN2J_ZsSQezWZAs,51
12
- finalsa_common_models-1.0.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
13
- finalsa_common_models-1.0.1.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- finalsa/common/models
2
- finalsa/common/models/models