velocity-python 0.0.138__py3-none-any.whl → 0.0.140__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.

Potentially problematic release.


This version of velocity-python might be problematic. Click here for more details.

velocity/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.0.138"
1
+ __version__ = version = "0.0.140"
2
2
 
3
3
  from . import aws
4
4
  from . import db
@@ -9,33 +9,34 @@ import copy
9
9
  import json
10
10
  import os
11
11
  import time
12
- from abc import ABC, abstractmethod
13
- from typing import Dict, Any, Optional
12
+ from abc import ABC
13
+ from datetime import date, datetime
14
+ from typing import Dict, Any
14
15
 
15
16
 
16
17
  class ActivityTracker(ABC):
17
18
  """
18
19
  Mixin class providing standardized activity tracking for Lambda handlers.
19
-
20
+
20
21
  Tracks API calls to the aws_api_activity table with consistent data structure
21
22
  and automatic duration calculation.
22
23
  """
23
-
24
+
24
25
  def __init__(self, *args, **kwargs):
25
26
  super().__init__(*args, **kwargs)
26
27
  self.activity_log_key = None
27
28
  self.start_time = None
28
29
  self.end_time = None
29
30
  self.activity_data = {}
30
-
31
+
31
32
  def track_activity_start(self, tx, context):
32
33
  """Start tracking activity for the current request"""
33
34
  self.start_time = time.time()
34
-
35
+
35
36
  # Gather common activity data
36
37
  postdata = context.postdata()
37
38
  payload = context.payload()
38
-
39
+
39
40
  self.activity_data = {
40
41
  "action": context.action(),
41
42
  "args": json.dumps(context.args()),
@@ -45,21 +46,34 @@ class ActivityTracker(ABC):
45
46
  "user_branch": os.environ.get("USER_BRANCH", "Unknown"),
46
47
  "start_timestamp": self.start_time,
47
48
  }
48
-
49
+
49
50
  # Add user information if available
50
51
  user_info = self._extract_user_info(payload)
51
52
  if user_info:
52
53
  self.activity_data.update(user_info)
53
-
54
+
54
55
  # Add session information
55
56
  session_data = context.session()
56
57
  if session_data:
57
- self.activity_data.update({k: v for k, v in session_data.items()
58
- if k not in ['cognito_user']})
59
-
58
+ self.activity_data.update(self._sanitize_session_data(session_data))
59
+
60
+ # Ensure all values are serializable before persisting
61
+ self.activity_data = {
62
+ key: self._normalize_activity_value(value)
63
+ for key, value in self.activity_data.items()
64
+ if value is not None
65
+ }
66
+
60
67
  # Create the activity record
61
- self.activity_log_key = tx.table("aws_api_activity").new(self.activity_data).pk
62
-
68
+ try:
69
+ self.activity_log_key = tx.table("aws_api_activity").new(self.activity_data).pk
70
+ except Exception as exc:
71
+ context.log(
72
+ f"ActivityTracker.track_activity_start failed: {exc}; keys={list(self.activity_data.keys())}",
73
+ "ActivityTracker.track_activity_start",
74
+ )
75
+ raise
76
+
63
77
  return self.activity_log_key
64
78
 
65
79
  def track_activity_success(self, tx, context):
@@ -140,3 +154,28 @@ class ActivityTracker(ABC):
140
154
  pass
141
155
 
142
156
  return user_info
157
+
158
+ def _sanitize_session_data(self, session: Dict[str, Any]) -> Dict[str, Any]:
159
+ """Remove sensitive session keys and normalize value types"""
160
+ sanitized = {}
161
+
162
+ for key, value in session.items():
163
+ if key == "cognito_user":
164
+ continue
165
+
166
+ sanitized[key] = self._normalize_activity_value(value)
167
+
168
+ return sanitized
169
+
170
+ def _normalize_activity_value(self, value: Any) -> Any:
171
+ """Convert activity data values into types acceptable by psycopg2"""
172
+ if isinstance(value, (dict, list, tuple, set)):
173
+ try:
174
+ return json.dumps(value)
175
+ except (TypeError, ValueError):
176
+ return str(value)
177
+ if isinstance(value, (datetime, date)):
178
+ return value.isoformat()
179
+ if isinstance(value, (bytes, bytearray)):
180
+ return value.decode("utf-8", errors="ignore")
181
+ return value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.138
3
+ Version: 0.0.140
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -1,4 +1,4 @@
1
- velocity/__init__.py,sha256=4cK9msUzcPYo3tFiZ2-Ww6__hxYNmQ_B876ClZvAKwY,147
1
+ velocity/__init__.py,sha256=4tuIcCyAF_BNn2pB2swolVQBfQPmUTvsDhNr9YkR7zM,147
2
2
  velocity/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  velocity/app/invoices.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  velocity/app/orders.py,sha256=fr1oTBjSFfyeMBUXRG06LV4jgwrlwYNL5mbEBleFwf0,6328
@@ -18,7 +18,7 @@ velocity/aws/handlers/lambda_handler.py,sha256=0wa_CHyJOaI5RsHqB0Ae83-B-SwlKR0qk
18
18
  velocity/aws/handlers/response.py,sha256=s2Kw7yv5zAir1mEmfv6yBVIvRcRQ__xyryf1SrvtiRc,9317
19
19
  velocity/aws/handlers/sqs_handler.py,sha256=azuV8DrFOh0hM13EnPzyYVBS-3fLe2fn9OPc4ho7sGc,3375
20
20
  velocity/aws/handlers/mixins/__init__.py,sha256=_zyEpsnKikF7D7X-F0GA4cyIrQ6wBq7k5j6Vhp17vaQ,623
21
- velocity/aws/handlers/mixins/activity_tracker.py,sha256=b2Cu46FM0fLS2-FkWXXAPw6yvMV_Viu5-IlpGkVAlmk,5254
21
+ velocity/aws/handlers/mixins/activity_tracker.py,sha256=vyQ_8kpSprjzLoALDv7g2rVkfstn89Tbsg6Zb9GmVOk,6579
22
22
  velocity/aws/handlers/mixins/error_handler.py,sha256=uN2YF9v-3LzS3o_HdVpO-XMcPy3sS7SHjUg_LfbsG7Q,6803
23
23
  velocity/aws/handlers/mixins/legacy_mixin.py,sha256=_YhiPU-zzXQjGNSAKhoUwfTFlnczmU-3BkwNFqr0hYE,2117
24
24
  velocity/aws/handlers/mixins/standard_mixin.py,sha256=-wBX0PFlZAnxQsaMDEWr-xmU8TcRbQ4BZD3wmAKR2d0,2489
@@ -121,8 +121,8 @@ velocity/misc/tests/test_merge.py,sha256=Vm5_jY5cVczw0hZF-3TYzmxFw81heJOJB-dvhCg
121
121
  velocity/misc/tests/test_oconv.py,sha256=fy4DwWGn_v486r2d_3ACpuBD-K1oOngNq1HJCGH7X-M,4694
122
122
  velocity/misc/tests/test_original_error.py,sha256=iWSd18tckOA54LoPQOGV5j9LAz2W-3_ZOwmyZ8-4YQc,1742
123
123
  velocity/misc/tests/test_timer.py,sha256=l9nrF84kHaFofvQYKInJmfoqC01wBhsUB18lVBgXCoo,2758
124
- velocity_python-0.0.138.dist-info/licenses/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
125
- velocity_python-0.0.138.dist-info/METADATA,sha256=Rt_XjAFeisvsIMrNAx1j4whaIjqHk8aHcFKg7IOGIxk,34262
126
- velocity_python-0.0.138.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
127
- velocity_python-0.0.138.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
128
- velocity_python-0.0.138.dist-info/RECORD,,
124
+ velocity_python-0.0.140.dist-info/licenses/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
125
+ velocity_python-0.0.140.dist-info/METADATA,sha256=1ILF_tgyA45S-ax-Me6sC9D7Dqcb8zohfPe60SYyHEQ,34262
126
+ velocity_python-0.0.140.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
127
+ velocity_python-0.0.140.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
128
+ velocity_python-0.0.140.dist-info/RECORD,,