ipulse-shared-core-ftredge 2.54__tar.gz → 2.55__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.

Potentially problematic release.


This version of ipulse-shared-core-ftredge might be problematic. Click here for more details.

Files changed (31) hide show
  1. {ipulse_shared_core_ftredge-2.54/src/ipulse_shared_core_ftredge.egg-info → ipulse_shared_core_ftredge-2.55}/PKG-INFO +1 -1
  2. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/setup.py +1 -1
  3. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/__init__.py +1 -1
  4. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/utils_common.py +111 -25
  5. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55/src/ipulse_shared_core_ftredge.egg-info}/PKG-INFO +1 -1
  6. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/LICENCE +0 -0
  7. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/README.md +0 -0
  8. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/pyproject.toml +0 -0
  9. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/setup.cfg +0 -0
  10. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/enums/__init__.py +0 -0
  11. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/enums/enums_common_utils.py +0 -0
  12. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/enums/enums_data_eng.py +0 -0
  13. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/enums/enums_module_fincore.py +0 -0
  14. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/enums/enums_modules.py +0 -0
  15. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/__init__.py +0 -0
  16. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/audit_log_firestore.py +0 -0
  17. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/organisation.py +0 -0
  18. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/pulse_enums.py +0 -0
  19. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/resource_catalog_item.py +0 -0
  20. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/user_auth.py +0 -0
  21. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/user_profile.py +0 -0
  22. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/user_profile_update.py +0 -0
  23. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/models/user_status.py +0 -0
  24. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/tests/__init__.py +0 -0
  25. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/tests/test.py +0 -0
  26. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/utils_gcp.py +0 -0
  27. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge/utils_templates_and_schemas.py +0 -0
  28. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge.egg-info/SOURCES.txt +0 -0
  29. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge.egg-info/dependency_links.txt +0 -0
  30. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge.egg-info/requires.txt +0 -0
  31. {ipulse_shared_core_ftredge-2.54 → ipulse_shared_core_ftredge-2.55}/src/ipulse_shared_core_ftredge.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipulse_shared_core_ftredge
3
- Version: 2.54
3
+ Version: 2.55
4
4
  Summary: Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.
5
5
  Home-page: https://github.com/TheFutureEdge/ipulse_shared_core
6
6
  Author: Russlan Ramdowar
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
3
3
 
4
4
  setup(
5
5
  name='ipulse_shared_core_ftredge',
6
- version='2.54',
6
+ version='2.55',
7
7
  package_dir={'': 'src'}, # Specify the source directory
8
8
  packages=find_packages(where='src'), # Look for packages in 'src'
9
9
  install_requires=[
@@ -5,7 +5,7 @@ from .utils_gcp import (setup_gcp_logger_and_error_report,
5
5
  write_csv_to_gcs, write_json_to_gcs)
6
6
  from .utils_templates_and_schemas import (create_bigquery_schema_from_json,
7
7
  check_format_against_schema_template)
8
- from .utils_common import (ContextLog, PipelineWatcher)
8
+ from .utils_common import (ContextLog, Pipelinemon)
9
9
 
10
10
  from .enums import (TargetLogs, LogLevel, Unit, Frequency,
11
11
  Module, SubModule, BaseDataCategory,
@@ -17,11 +17,12 @@ from ipulse_shared_core_ftredge.utils_gcp import write_json_to_gcs
17
17
  # ["data_import","data_quality", "data_processing","data_general","data_persistance","metadata_quality", "metadata_processing", "metadata_persistance","metadata_general"]
18
18
 
19
19
  class ContextLog:
20
- MAX_TRACEBACK_LINES = 14 # Define the maximum number of traceback lines to include
20
+ MAX_TRACEBACK_LINES = 24 # Define the maximum number of traceback lines to include
21
21
  def __init__(self, level: LogLevel, base_context: str = None, collector_id: str = None,
22
- e: Exception = None, e_type: str = None, e_message: str = None, e_traceback: str = None,
23
- subject: str = None, description: str = None, context: str = None,
24
- log_status: LogStatus = LogStatus.OPEN):
22
+ context: str = None, description: str = None,
23
+ e: Exception = None, e_type: str = None, e_message: str = None, e_traceback: str = None,
24
+ log_status: LogStatus = LogStatus.OPEN, subject: str = None
25
+ ):
25
26
  if e is not None:
26
27
  e_type = type(e).__name__ if e_type is None else e_type
27
28
  e_message = str(e) if e_message is None else e_message
@@ -46,7 +47,7 @@ class ContextLog:
46
47
  return None
47
48
 
48
49
  traceback_lines = e_traceback.splitlines()
49
-
50
+
50
51
  # Remove lines that are part of the exception message if they are present in traceback
51
52
  message_lines = e_message.splitlines() if e_message else []
52
53
  if message_lines:
@@ -56,7 +57,7 @@ class ContextLog:
56
57
 
57
58
  # Filter out lines from third-party libraries (like site-packages)
58
59
  filtered_lines = [line for line in traceback_lines if "site-packages" not in line]
59
-
60
+
60
61
  # If filtering results in too few lines, revert to original traceback
61
62
  if len(filtered_lines) < 2:
62
63
  filtered_lines = traceback_lines
@@ -101,23 +102,108 @@ class ContextLog:
101
102
  def context(self, value):
102
103
  self._context = value
103
104
 
104
- def to_dict(self):
105
- return {
106
- "base_context": self.base_context,
107
- "context": self.context,
108
- "level_code": self.level.value,
109
- "level_name": self.level.name,
110
- "subject": self.subject,
111
- "description": self.description,
112
- "exception_type": self.exception_type,
113
- "exception_message": self.exception_message,
114
- "exception_traceback": self.exception_traceback,
115
- "log_status": self.log_status.value,
116
- "collector_id": self.collector_id,
117
- "timestamp": self.timestamp
118
- }
119
-
120
- class PipelineWatcher:
105
+
106
+ def to_dict(self, size_limit=256 * 1024 * 0.80):
107
+ size_limit = int(size_limit) # Ensure size_limit is an integer
108
+
109
+ # Define the priority order of the fields
110
+ priority_fields = [
111
+ ("base_context", self.base_context),
112
+ ("level_code", self.level.value),
113
+ ("level_name", self.level.name),
114
+ ("log_status", self.log_status.value),
115
+ ("collector_id", self.collector_id),
116
+ ("timestamp", self.timestamp),
117
+ ]
118
+
119
+ # Additional fields to be truncated if necessary. Shorter fields are truncated first so that remaining size can increase for longer fields.
120
+ additional_fields = [
121
+ ("subject", self.subject),
122
+ ("description", self.description),
123
+ ("exception_type", self.exception_type),
124
+ ("exception_message", self.exception_message),
125
+ ("context", self.context), # special sizing rules apply to it
126
+ ("exception_traceback", self.exception_traceback)
127
+ ]
128
+
129
+ all_fields = priority_fields + additional_fields
130
+ non_zero_fields = [(key, value) for key, value in all_fields if value is not None]
131
+
132
+ total_size = 0
133
+ truncated = False # Flag to indicate if truncation happened
134
+
135
+ # Function to calculate the byte size of a JSON-encoded field
136
+ def field_size(key, value):
137
+ return len(json.dumps({key: value}).encode('utf-8'))
138
+
139
+ # Function to truncate a value based on its type
140
+ def truncate_value(value, max_size):
141
+ if isinstance(value, str):
142
+ half_size = max_size // 2
143
+ return value[:half_size] + '...' + value[-(max_size - half_size - 3):]
144
+ elif isinstance(value, (list, tuple)):
145
+ half_size = max_size // 2
146
+ return list(value[:half_size]) + ['...'] + list(value[-(max_size - half_size - 1):])
147
+ elif isinstance(value, set):
148
+ truncated_set = set(list(value)[:max_size // 2]) | set(list(value)[-(max_size // 2):])
149
+ return truncated_set
150
+ elif isinstance(value, dict):
151
+ truncated_dict = {k: truncate_value(v, max_size // len(value)) for k, v in list(value.items())}
152
+ return truncated_dict
153
+ else:
154
+ return value
155
+
156
+ # Calculate the initial total size
157
+ for key, value in non_zero_fields:
158
+ total_size += field_size(key, value)
159
+
160
+ log_dict = {}
161
+ # Check if total size exceeds the size limit
162
+ if total_size > size_limit:
163
+ truncated = True # Set the truncation flag
164
+ # Calculate max size per field based on all non-zero fields
165
+ max_size_per_field = size_limit // len(non_zero_fields)
166
+
167
+ # Reset total_size to recompute with truncation
168
+ total_size = 0
169
+
170
+ # Add priority fields first with possible truncation
171
+ for key, value in priority_fields:
172
+ if value is not None:
173
+ truncated_value = value
174
+ if isinstance(value, (str, list, tuple, set, dict)) and field_size(key, value) > max_size_per_field:
175
+ truncated_value = truncate_value(value, max_size_per_field)
176
+ log_dict[key] = truncated_value
177
+ total_size += field_size(key, truncated_value)
178
+ else:
179
+ log_dict[key] = value
180
+
181
+ # Calculate remaining size for additional fields
182
+ remaining_size = size_limit - total_size
183
+
184
+ # Handle remaining additional fields
185
+ non_zero_additional_fields = [field for field in additional_fields[1:] if field[1]]
186
+ remaining_field_size = remaining_size // len(non_zero_additional_fields) if non_zero_additional_fields else 0
187
+
188
+ for key, value in additional_fields[1:]:
189
+ if value is not None:
190
+ if field_size(key, value) > remaining_field_size:
191
+ truncated_value = truncate_value(value, remaining_field_size)
192
+ else:
193
+ truncated_value = value
194
+ log_dict[key] = truncated_value
195
+ remaining_size -= field_size(key, truncated_value)
196
+ else:
197
+ log_dict[key] = value
198
+ else:
199
+ log_dict = dict(all_fields)
200
+
201
+ # Add trunc flag to the log dictionary
202
+ log_dict['trunc'] = truncated
203
+
204
+ return log_dict
205
+
206
+ class Pipelinemon:
121
207
  ERROR_START_CODE = LogLevel.ERROR.value
122
208
  WARNING_START_CODE = LogLevel.WARNING.value
123
209
  NOTICE_START_CODE = LogLevel.NOTICE.value
@@ -192,7 +278,7 @@ class PipelineWatcher:
192
278
  def add_log(self, log: ContextLog):
193
279
  if (self._target_logs == TargetLogs.SUCCESSES and log.level >=self.NOTICE_START_CODE) or \
194
280
  (self._target_logs == TargetLogs.WARNINGS_AND_ERRORS and log.level.value < self.WARNING_START_CODE):
195
- raise ValueError(f"Invalid log level {log.level.name} for Pipeline Watcher target logs setup: {self._target_logs}")
281
+ raise ValueError(f"Invalid log level {log.level.name} for Pipelinemon target logs setup: {self._target_logs}")
196
282
  log.base_context = self.base_context
197
283
  log.context = self.current_context
198
284
  log.collector_id = self.id
@@ -201,7 +287,7 @@ class PipelineWatcher:
201
287
  self._update_counts(log_dict)
202
288
 
203
289
  if self._logger:
204
- # We specifically want to avoid having an ERROR log level for this structured Pipeline Watcher reporting, to ensure Errors are alerting on Critical Application Services.
290
+ # We specifically want to avoid having an ERROR log level for this structured Pipelinemon reporting, to ensure Errors are alerting on Critical Application Services.
205
291
  # A single ERROR log level can be used for the entire pipeline, which shall be used at the end of the pipeline
206
292
  if log.level.value >= self.WARNING_START_CODE:
207
293
  self._logger.log_struct(log_dict, severity="WARNING")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipulse_shared_core_ftredge
3
- Version: 2.54
3
+ Version: 2.55
4
4
  Summary: Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.
5
5
  Home-page: https://github.com/TheFutureEdge/ipulse_shared_core
6
6
  Author: Russlan Ramdowar