velocity-python 0.0.120__tar.gz → 0.0.124__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 velocity-python might be problematic. Click here for more details.
- {velocity_python-0.0.120/src/velocity_python.egg-info → velocity_python-0.0.124}/PKG-INFO +1 -1
- {velocity_python-0.0.120 → velocity_python-0.0.124}/pyproject.toml +1 -1
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/__init__.py +1 -1
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/base_handler.py +9 -6
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/lambda_handler.py +12 -1
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/sqs_handler.py +8 -2
- {velocity_python-0.0.120 → velocity_python-0.0.124/src/velocity_python.egg-info}/PKG-INFO +1 -1
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity_python.egg-info/SOURCES.txt +1 -0
- velocity_python-0.0.124/tests/test_lambda_handler_json_serialization.py +120 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/LICENSE +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/README.md +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/setup.cfg +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/app/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/app/invoices.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/app/orders.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/app/payments.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/app/purchase_orders.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/amplify.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/context.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/exceptions.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/response.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/column.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/database.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/decorators.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/engine.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/result.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/row.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/sequence.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/table.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/core/transaction.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/exceptions.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/mysql.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/mysql_reserved.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/operators.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/reserved.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/sql.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/types.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/sqlite.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/sqlite_reserved.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/sqlserver.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/sqlserver_reserved.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/tablehelper.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/utils.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/conv/__init__.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/conv/iconv.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/conv/oconv.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/db.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/export.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/format.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/mail.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/merge.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/timer.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/misc/tools.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity_python.egg-info/dependency_links.txt +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity_python.egg-info/requires.txt +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity_python.egg-info/top_level.txt +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_cursor_rowcount_fix.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_db.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_db_utils.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_email_processing.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_fix.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_format.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_iconv.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_merge.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_oconv.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_original_error.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_payment_profile_sorting.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_postgres.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_process_error_robustness.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_response.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_result_caching.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_result_sql_aware.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_row_get_missing_column.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_spreadsheet_functions.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_sql_builder.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_tablehelper.py +0 -0
- {velocity_python-0.0.120 → velocity_python-0.0.124}/tests/test_timer.py +0 -0
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/base_handler.py
RENAMED
|
@@ -116,11 +116,12 @@ class BaseHandler:
|
|
|
116
116
|
|
|
117
117
|
return actions
|
|
118
118
|
|
|
119
|
-
def execute_actions(self, local_context, actions: List[str]) -> bool:
|
|
119
|
+
def execute_actions(self, tx, local_context, actions: List[str]) -> bool:
|
|
120
120
|
"""
|
|
121
121
|
Execute the appropriate actions for the given context.
|
|
122
122
|
|
|
123
123
|
Args:
|
|
124
|
+
tx: Database transaction object
|
|
124
125
|
local_context: The context object
|
|
125
126
|
actions: List of action method names to try
|
|
126
127
|
|
|
@@ -129,7 +130,7 @@ class BaseHandler:
|
|
|
129
130
|
"""
|
|
130
131
|
# Execute beforeAction hook if available
|
|
131
132
|
if hasattr(self, "beforeAction"):
|
|
132
|
-
self.beforeAction(local_context)
|
|
133
|
+
self.beforeAction(tx, local_context)
|
|
133
134
|
|
|
134
135
|
action_executed = False
|
|
135
136
|
|
|
@@ -139,7 +140,7 @@ class BaseHandler:
|
|
|
139
140
|
break
|
|
140
141
|
|
|
141
142
|
if hasattr(self, action):
|
|
142
|
-
result = getattr(self, action)(local_context)
|
|
143
|
+
result = getattr(self, action)(tx, local_context)
|
|
143
144
|
|
|
144
145
|
# Check for deprecated return values (LambdaHandler specific)
|
|
145
146
|
if result is not None and hasattr(self, "_check_deprecated_return"):
|
|
@@ -150,27 +151,29 @@ class BaseHandler:
|
|
|
150
151
|
|
|
151
152
|
# Execute afterAction hook if available
|
|
152
153
|
if hasattr(self, "afterAction"):
|
|
153
|
-
self.afterAction(local_context)
|
|
154
|
+
self.afterAction(tx, local_context)
|
|
154
155
|
|
|
155
156
|
return action_executed
|
|
156
157
|
|
|
157
|
-
def handle_error(self, local_context, exception: Exception):
|
|
158
|
+
def handle_error(self, tx, local_context, exception: Exception):
|
|
158
159
|
"""
|
|
159
160
|
Handle errors that occur during action execution.
|
|
160
161
|
|
|
161
162
|
Args:
|
|
163
|
+
tx: Database transaction object
|
|
162
164
|
local_context: The context object
|
|
163
165
|
exception: The exception that occurred
|
|
164
166
|
"""
|
|
165
167
|
if hasattr(self, "onError"):
|
|
166
168
|
self.onError(
|
|
169
|
+
tx,
|
|
167
170
|
local_context,
|
|
168
171
|
exc=exception.__class__.__name__,
|
|
169
172
|
tb=traceback.format_exc(),
|
|
170
173
|
)
|
|
171
174
|
else:
|
|
172
175
|
# Re-raise if no error handler is defined
|
|
173
|
-
raise
|
|
176
|
+
raise exception
|
|
174
177
|
|
|
175
178
|
def log(self, tx, message: str, function: Optional[str] = None):
|
|
176
179
|
"""
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/lambda_handler.py
RENAMED
|
@@ -71,8 +71,19 @@ class LambdaHandler(BaseHandler):
|
|
|
71
71
|
log=lambda message, function=None: self.log(tx, message, function),
|
|
72
72
|
)
|
|
73
73
|
|
|
74
|
+
# Determine action from postdata or query parameters
|
|
75
|
+
action = postdata.get("action") or req_params.get("action")
|
|
76
|
+
|
|
77
|
+
# Get the list of actions to execute
|
|
78
|
+
actions = self.get_actions_to_execute(action)
|
|
79
|
+
|
|
74
80
|
# Use BaseHandler's execute_actions method
|
|
75
|
-
|
|
81
|
+
try:
|
|
82
|
+
self.execute_actions(tx, local_context, actions)
|
|
83
|
+
except Exception as e:
|
|
84
|
+
self.handle_error(tx, local_context, e)
|
|
85
|
+
|
|
86
|
+
return local_context.response.render()
|
|
76
87
|
|
|
77
88
|
def track(self, tx, data={}, user=None):
|
|
78
89
|
data = data.copy()
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/aws/handlers/sqs_handler.py
RENAMED
|
@@ -78,11 +78,17 @@ class SqsHandler(BaseHandler):
|
|
|
78
78
|
session=None,
|
|
79
79
|
)
|
|
80
80
|
|
|
81
|
+
# Determine action from postdata
|
|
82
|
+
action = postdata.get("action") if isinstance(postdata, dict) else None
|
|
83
|
+
|
|
84
|
+
# Get the list of actions to execute
|
|
85
|
+
actions = self.get_actions_to_execute(action)
|
|
86
|
+
|
|
81
87
|
# Use BaseHandler's execute_actions method
|
|
82
88
|
try:
|
|
83
|
-
self.execute_actions(tx, local_context,
|
|
89
|
+
self.execute_actions(tx, local_context, actions)
|
|
84
90
|
except Exception as e:
|
|
85
|
-
self.handle_error(local_context, e)
|
|
91
|
+
self.handle_error(tx, local_context, e)
|
|
86
92
|
|
|
87
93
|
def OnActionDefault(self, tx, context):
|
|
88
94
|
"""
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test Lambda Handler JSON Serialization Fix
|
|
3
|
+
|
|
4
|
+
This test verifies that LambdaHandler.serve() returns a JSON-serializable
|
|
5
|
+
dictionary instead of a Response object, preventing the
|
|
6
|
+
"Object of type method is not JSON serializable" error.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import unittest
|
|
11
|
+
from unittest.mock import MagicMock, patch
|
|
12
|
+
import sys
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
# Add src to path for testing
|
|
16
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
|
17
|
+
|
|
18
|
+
from velocity.aws.handlers.lambda_handler import LambdaHandler
|
|
19
|
+
from velocity.aws.handlers.response import Response
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestLambdaHandlerJSONSerialization(unittest.TestCase):
|
|
23
|
+
"""Test cases for Lambda Handler JSON serialization."""
|
|
24
|
+
|
|
25
|
+
def setUp(self):
|
|
26
|
+
"""Set up test fixtures."""
|
|
27
|
+
self.test_event = {
|
|
28
|
+
"body": '{"action": "test", "payload": {}}',
|
|
29
|
+
"httpMethod": "POST",
|
|
30
|
+
"headers": {"Content-Type": "application/json"},
|
|
31
|
+
"requestContext": {
|
|
32
|
+
"identity": {
|
|
33
|
+
"sourceIp": "127.0.0.1", # localhost test IP for unit testing
|
|
34
|
+
"userAgent": "test-agent"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"queryStringParameters": {}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
self.test_context = MagicMock()
|
|
41
|
+
self.test_context.function_name = "test-function"
|
|
42
|
+
|
|
43
|
+
def test_serve_returns_json_serializable_dict(self):
|
|
44
|
+
"""Test that serve() returns a JSON-serializable dictionary."""
|
|
45
|
+
|
|
46
|
+
# Create handler
|
|
47
|
+
handler = LambdaHandler(self.test_event, self.test_context)
|
|
48
|
+
|
|
49
|
+
# Mock the transaction decorator to pass through tx
|
|
50
|
+
with patch('velocity.aws.handlers.lambda_handler.engine') as mock_engine:
|
|
51
|
+
def mock_transaction(func):
|
|
52
|
+
def wrapper(*args, **kwargs):
|
|
53
|
+
mock_tx = MagicMock()
|
|
54
|
+
return func(mock_tx, *args, **kwargs)
|
|
55
|
+
return wrapper
|
|
56
|
+
|
|
57
|
+
mock_engine.transaction = mock_transaction
|
|
58
|
+
|
|
59
|
+
# Call serve method
|
|
60
|
+
result = handler.serve(MagicMock())
|
|
61
|
+
|
|
62
|
+
# Verify result is a dictionary (JSON-serializable)
|
|
63
|
+
self.assertIsInstance(result, dict)
|
|
64
|
+
|
|
65
|
+
# Verify it has the expected Lambda response structure
|
|
66
|
+
self.assertIn("statusCode", result)
|
|
67
|
+
self.assertIn("headers", result)
|
|
68
|
+
self.assertIn("body", result)
|
|
69
|
+
|
|
70
|
+
# Verify the body is a JSON string
|
|
71
|
+
self.assertIsInstance(result["body"], str)
|
|
72
|
+
|
|
73
|
+
# Verify the entire result can be JSON serialized
|
|
74
|
+
try:
|
|
75
|
+
json.dumps(result)
|
|
76
|
+
except (TypeError, ValueError) as e:
|
|
77
|
+
self.fail(f"Result is not JSON serializable: {e}")
|
|
78
|
+
|
|
79
|
+
def test_response_object_has_render_method(self):
|
|
80
|
+
"""Test that Response object has a proper render method."""
|
|
81
|
+
response = Response()
|
|
82
|
+
|
|
83
|
+
# Verify render method exists
|
|
84
|
+
self.assertTrue(hasattr(response, 'render'))
|
|
85
|
+
self.assertTrue(callable(response.render))
|
|
86
|
+
|
|
87
|
+
# Verify render returns a dictionary
|
|
88
|
+
rendered = response.render()
|
|
89
|
+
self.assertIsInstance(rendered, dict)
|
|
90
|
+
|
|
91
|
+
# Verify structure
|
|
92
|
+
self.assertIn("statusCode", rendered)
|
|
93
|
+
self.assertIn("headers", rendered)
|
|
94
|
+
self.assertIn("body", rendered)
|
|
95
|
+
|
|
96
|
+
# Verify JSON serializable
|
|
97
|
+
try:
|
|
98
|
+
json.dumps(rendered)
|
|
99
|
+
except (TypeError, ValueError) as e:
|
|
100
|
+
self.fail(f"Rendered response is not JSON serializable: {e}")
|
|
101
|
+
|
|
102
|
+
def test_response_render_vs_raw_object(self):
|
|
103
|
+
"""Test the difference between Response object and rendered response."""
|
|
104
|
+
response = Response()
|
|
105
|
+
|
|
106
|
+
# Raw response object should not be directly JSON serializable
|
|
107
|
+
# (it contains method references)
|
|
108
|
+
with self.assertRaises((TypeError, ValueError)):
|
|
109
|
+
json.dumps(response)
|
|
110
|
+
|
|
111
|
+
# But rendered response should be JSON serializable
|
|
112
|
+
rendered = response.render()
|
|
113
|
+
try:
|
|
114
|
+
json.dumps(rendered)
|
|
115
|
+
except (TypeError, ValueError) as e:
|
|
116
|
+
self.fail(f"Rendered response should be JSON serializable: {e}")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
if __name__ == '__main__':
|
|
120
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/mysql_reserved.py
RENAMED
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/postgres/types.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/sqlite_reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity/db/servers/sqlserver_reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{velocity_python-0.0.120 → velocity_python-0.0.124}/src/velocity_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|