velocity-python 0.0.169__tar.gz → 0.0.171__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.
- {velocity_python-0.0.169 → velocity_python-0.0.171}/PKG-INFO +1 -1
- {velocity_python-0.0.169 → velocity_python-0.0.171}/pyproject.toml +1 -1
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/__init__.py +1 -1
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/base_handler.py +20 -23
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/context.py +5 -6
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/lambda_handler.py +123 -122
- velocity_python-0.0.171/src/velocity/aws/handlers/mixins/__init__.py +10 -0
- velocity_python-0.0.171/src/velocity/aws/handlers/mixins/web_handler.py +357 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/sqs_handler.py +1 -1
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity_python.egg-info/PKG-INFO +1 -1
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity_python.egg-info/SOURCES.txt +2 -4
- velocity_python-0.0.171/tests/test_mixins_import.py +14 -0
- velocity_python-0.0.169/src/velocity/aws/handlers/mixins/__init__.py +0 -14
- velocity_python-0.0.169/src/velocity/aws/handlers/mixins/activity_tracker.py +0 -181
- velocity_python-0.0.169/src/velocity/aws/handlers/mixins/enhanced_handler_mixin.py +0 -55
- velocity_python-0.0.169/src/velocity/aws/handlers/mixins/error_handler.py +0 -206
- velocity_python-0.0.169/src/velocity/aws/handlers/mixins/legacy_mixin.py +0 -55
- {velocity_python-0.0.169 → velocity_python-0.0.171}/LICENSE +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/README.md +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/setup.cfg +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/invoices.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/orders.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/payments.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/purchase_orders.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/tests/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/tests/test_email_processing.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/tests/test_payment_profile_sorting.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/app/tests/test_spreadsheet_functions.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/amplify.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/exceptions.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/response.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/tests/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/tests/test_response.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/column.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/database.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/decorators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/engine.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/result.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/row.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/sequence.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/table.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/core/transaction.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/exceptions.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/base/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/base/initializer.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/base/operators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/base/sql.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/base/types.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/mysql/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/mysql/operators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/mysql/reserved.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/mysql/sql.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/mysql/types.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/postgres/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/postgres/operators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/postgres/reserved.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/postgres/sql.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/postgres/types.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlite/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlite/operators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlite/reserved.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlite/sql.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlite/types.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlserver/operators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlserver/sql.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/sqlserver/types.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/servers/tablehelper.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/common_db_test.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/common.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_column.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_connections.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_database.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_engine.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_imports.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_result.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_row.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_table.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/sql/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/sql/common.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_db_utils.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_postgres.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_result_caching.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_sql_builder.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/tests/test_tablehelper.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/db/utils.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/logging.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/conv/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/conv/iconv.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/conv/oconv.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/db.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/export.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/format.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/mail.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/merge.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/__init__.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_db.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_fix.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_format.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_iconv.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_merge.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_oconv.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_original_error.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tests/test_timer.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/timer.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/misc/tools.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity_python.egg-info/dependency_links.txt +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity_python.egg-info/requires.txt +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity_python.egg-info/top_level.txt +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/tests/test_decorators.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/tests/test_lambda_handler.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/tests/test_sys_modified_count_postgres_demo.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/tests/test_table_alter.py +0 -0
- {velocity_python-0.0.169 → velocity_python-0.0.171}/tests/test_where_clause_validation.py +0 -0
{velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/base_handler.py
RENAMED
|
@@ -5,7 +5,6 @@ This module provides a base class for handling AWS Lambda events.
|
|
|
5
5
|
It includes common functionality shared between LambdaHandler and SqsHandler.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import logging
|
|
9
8
|
import os
|
|
10
9
|
import sys
|
|
11
10
|
import traceback
|
|
@@ -146,10 +145,14 @@ class BaseHandler:
|
|
|
146
145
|
if hasattr(self, action):
|
|
147
146
|
result = getattr(self, action)(tx, local_context)
|
|
148
147
|
if result is not None:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
self.logger.warning(
|
|
149
|
+
"Action %s returned an unexpected non-None result (%r).",
|
|
150
|
+
action,
|
|
151
|
+
result,
|
|
152
|
+
extra={
|
|
153
|
+
"note": "Handlers should return None so results are not ignored.",
|
|
154
|
+
"action": action,
|
|
155
|
+
},
|
|
153
156
|
)
|
|
154
157
|
action_executed = True
|
|
155
158
|
break
|
|
@@ -180,31 +183,25 @@ class BaseHandler:
|
|
|
180
183
|
# Re-raise if no error handler is defined
|
|
181
184
|
raise exception
|
|
182
185
|
|
|
183
|
-
def log(self, tx, message: str, function: Optional[str] = None):
|
|
184
|
-
"""
|
|
185
|
-
Log a message to the system log table.
|
|
186
|
-
This is a base implementation that should be overridden by subclasses
|
|
187
|
-
to provide handler-specific logging details.
|
|
188
|
-
|
|
189
|
-
Args:
|
|
190
|
-
tx: Database transaction object
|
|
191
|
-
message: The message to log
|
|
192
|
-
function: Optional function name, auto-detected if not provided
|
|
193
|
-
"""
|
|
186
|
+
def log(self, tx, message: str, function: Optional[str] = None, level: str = "info"):
|
|
187
|
+
"""Emit structured log output through the shared logger."""
|
|
194
188
|
if not function:
|
|
195
189
|
function = self.get_calling_function()
|
|
196
190
|
|
|
197
|
-
|
|
198
|
-
data = {
|
|
191
|
+
log_data = {
|
|
199
192
|
"app_name": os.environ.get("ProjectName", "Unknown"),
|
|
200
193
|
"function": function,
|
|
201
194
|
"message": message,
|
|
202
195
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
self.
|
|
206
|
-
|
|
207
|
-
|
|
196
|
+
self._extend_log_data(log_data)
|
|
197
|
+
|
|
198
|
+
log_method = getattr(self.logger, level, self.logger.info)
|
|
199
|
+
log_method(
|
|
200
|
+
"%s %s",
|
|
201
|
+
function,
|
|
202
|
+
message,
|
|
203
|
+
extra={"log_data": log_data, "tx_present": tx is not None},
|
|
204
|
+
)
|
|
208
205
|
|
|
209
206
|
def _extend_log_data(self, data: Dict[str, Any]):
|
|
210
207
|
"""
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import logging
|
|
3
2
|
import os
|
|
4
3
|
import re
|
|
5
4
|
import boto3
|
|
@@ -12,12 +11,13 @@ from botocore.exceptions import ClientError
|
|
|
12
11
|
import hashlib
|
|
13
12
|
import velocity
|
|
14
13
|
import velocity.db
|
|
14
|
+
from velocity.logging import get_logger
|
|
15
15
|
|
|
16
16
|
engine = velocity.db.postgres.initialize()
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
cognito_client = boto3.client("cognito-idp")
|
|
20
|
-
logger =
|
|
20
|
+
logger = get_logger("velocity.aws.handlers.context")
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
@engine.transaction
|
|
@@ -83,11 +83,10 @@ class Context:
|
|
|
83
83
|
def log(self, message, function=None):
|
|
84
84
|
if self.__log:
|
|
85
85
|
return self.__log(message, function)
|
|
86
|
+
if function:
|
|
87
|
+
logger.info("%s: %s", function, message)
|
|
86
88
|
else:
|
|
87
|
-
|
|
88
|
-
print(f"{function}: {message}")
|
|
89
|
-
else:
|
|
90
|
-
print(f"{message}")
|
|
89
|
+
logger.info("%s", message)
|
|
91
90
|
|
|
92
91
|
def update_job(self, tx, data=None):
|
|
93
92
|
"""Update job status and message in aws_job_activity table.
|
{velocity_python-0.0.169 → velocity_python-0.0.171}/src/velocity/aws/handlers/lambda_handler.py
RENAMED
|
@@ -14,11 +14,6 @@ configure_logging()
|
|
|
14
14
|
logger = get_logger("velocity.aws.handlers.lambda")
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def log_debug(*args) -> None:
|
|
18
|
-
if args:
|
|
19
|
-
logger.debug(" ".join(str(arg) for arg in args))
|
|
20
|
-
|
|
21
|
-
|
|
22
17
|
class LambdaHandler(BaseHandler):
|
|
23
18
|
def __init__(
|
|
24
19
|
self,
|
|
@@ -59,143 +54,91 @@ class LambdaHandler(BaseHandler):
|
|
|
59
54
|
else:
|
|
60
55
|
self.session["device_type"] = "unknown"
|
|
61
56
|
|
|
62
|
-
def get_pass_through_vars(self, tx, context):
|
|
63
|
-
"""Get pass-through variables: environment vars, layers, and user data"""
|
|
64
|
-
temp = context.get_pass_through_vars(tx, self.current_user)
|
|
65
|
-
|
|
66
|
-
log_debug(
|
|
67
|
-
"LAYER_DEBUG: vars object contains:",
|
|
68
|
-
list(temp.get("controls", {}).get("vars", {}).keys()),
|
|
69
|
-
)
|
|
70
|
-
if "layers" in temp.get("controls", {}).get("vars", {}):
|
|
71
|
-
log_debug("LAYER_DEBUG: layers value:", temp["controls"]["vars"]["layers"])
|
|
72
|
-
|
|
73
|
-
# Merge with user data from database
|
|
74
|
-
temp = context.merge_user_data(tx, temp, self.session["email_address"])
|
|
75
|
-
|
|
76
|
-
return temp
|
|
77
|
-
|
|
78
|
-
def _summarize_postdata(self, postdata):
|
|
79
|
-
"""Extract key fields from postdata for logging without storing entire payload"""
|
|
80
|
-
if not postdata:
|
|
81
|
-
return {}
|
|
82
|
-
|
|
83
|
-
summary = {
|
|
84
|
-
"action": postdata.get("action"),
|
|
85
|
-
"payload_keys": (
|
|
86
|
-
list(postdata.get("payload", {}).keys())
|
|
87
|
-
if isinstance(postdata.get("payload"), dict)
|
|
88
|
-
else None
|
|
89
|
-
),
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
# Add size info
|
|
93
|
-
try:
|
|
94
|
-
summary["payload_size_bytes"] = len(json.dumps(postdata.get("payload", {})))
|
|
95
|
-
except:
|
|
96
|
-
summary["payload_size_bytes"] = 0
|
|
97
|
-
|
|
98
|
-
return summary
|
|
99
57
|
|
|
100
58
|
def beforeAction(self, tx, context):
|
|
101
59
|
# Enhanced activity tracking
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# All other return values are ignored
|
|
105
|
-
if result is True:
|
|
60
|
+
stop_processing = self._enhanced_before_action(tx, context)
|
|
61
|
+
if stop_processing is True:
|
|
106
62
|
return
|
|
107
|
-
|
|
63
|
+
logger.debug("starting LamdaHandler.beforeAction")
|
|
108
64
|
|
|
109
|
-
postdata = context.postdata()
|
|
110
|
-
payload = context.payload()
|
|
111
|
-
args = context.args()
|
|
112
65
|
self.start = time.time()
|
|
113
66
|
self.cognito_user = context.get_cognito_user(self.aws_event)
|
|
114
|
-
self.current_user = {}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
# Legacy activity tracking (keep for compatibility) - store summary not full postdata
|
|
118
|
-
data = {}
|
|
119
|
-
data["action"] = context.action()
|
|
120
|
-
data["args"] = json.dumps(args)
|
|
121
|
-
# Store postdata summary instead of full payload to avoid bloat
|
|
122
|
-
data["postdata"] = json.dumps(self._summarize_postdata(postdata))
|
|
67
|
+
self.current_user = {}
|
|
68
|
+
|
|
69
|
+
logger.debug("DEBUG: !!! cognito_user %s", self.cognito_user)
|
|
123
70
|
try:
|
|
124
71
|
email_address = self.cognito_user["attributes"]["email"]
|
|
125
72
|
self.session["email_address"] = email_address
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
73
|
+
except Exception:
|
|
74
|
+
self.logger.warning("Unable to read email from Cognito user", exc_info=True)
|
|
75
|
+
|
|
76
|
+
self.logger.info(
|
|
77
|
+
"Starting action",
|
|
78
|
+
extra={
|
|
79
|
+
"action": context.action(),
|
|
80
|
+
"context_args": context.args(),
|
|
81
|
+
"summary": self._summarize_postdata(context.postdata()),
|
|
82
|
+
"session_email": self.session.get("email_address"),
|
|
83
|
+
},
|
|
84
|
+
)
|
|
131
85
|
|
|
132
86
|
row = tx.table(user_table).find(
|
|
133
|
-
{"email_address": self.session
|
|
87
|
+
{"email_address": self.session.get("email_address")}
|
|
134
88
|
)
|
|
135
89
|
if not row:
|
|
136
90
|
raise Exception(
|
|
137
91
|
"A valid user with permission is required to access this function [DB]"
|
|
138
92
|
)
|
|
139
93
|
self.current_user = row.to_dict()
|
|
140
|
-
temp = copy.deepcopy(postdata)
|
|
94
|
+
temp = copy.deepcopy(context.postdata())
|
|
141
95
|
temp["payload"].pop("cognito_user", None)
|
|
142
|
-
self.
|
|
96
|
+
self.logger.debug(
|
|
97
|
+
"Events.OnAction %s",
|
|
98
|
+
temp.get("action"),
|
|
99
|
+
extra={"payload": pprint.pformat(temp)},
|
|
100
|
+
)
|
|
143
101
|
|
|
144
102
|
def afterAction(self, tx, context):
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
result = self._enhanced_after_action(tx, context)
|
|
149
|
-
# You can prevent further processing by returning True
|
|
150
|
-
# All other return values are ignored
|
|
151
|
-
if result is True:
|
|
103
|
+
stop_processing = self._enhanced_after_action(tx, context)
|
|
104
|
+
if stop_processing is True:
|
|
152
105
|
return
|
|
153
|
-
|
|
154
|
-
log_debug("starting BackOfficeEvents.afterAction")
|
|
155
106
|
|
|
156
|
-
|
|
107
|
+
logger.debug("starting LamdaHandler.afterAction")
|
|
108
|
+
|
|
157
109
|
self.end = time.time()
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
110
|
+
self.logger.info(
|
|
111
|
+
"Completed action",
|
|
112
|
+
extra={
|
|
113
|
+
"action": context.action(),
|
|
114
|
+
"duration": self.end - self.start,
|
|
115
|
+
},
|
|
116
|
+
)
|
|
162
117
|
|
|
163
118
|
def onError(self, tx, context, exc, tb):
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
# You can prevent further processing by returning True
|
|
167
|
-
# All other return values are ignored
|
|
168
|
-
if result is True:
|
|
119
|
+
stop_processing = self._enhanced_error_handler(tx, context, exc, tb)
|
|
120
|
+
if stop_processing is True:
|
|
169
121
|
return
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
temp = copy.deepcopy(context.postdata())
|
|
191
|
-
log_debug("starting BackOfficeEvents.log")
|
|
192
|
-
temp["payload"].pop("cognito_user", None)
|
|
193
|
-
self.log(
|
|
194
|
-
error_tx,
|
|
195
|
-
f"{pprint.pformat(temp)}\n\n{tb}\n\n{exc}",
|
|
196
|
-
f"Events.OnError {temp['action']}",
|
|
197
|
-
)
|
|
198
|
-
log_debug("Ending BackOfficeEvents.OnError Done")
|
|
122
|
+
logger.debug("starting LamdaHandler.aws_api_activity")
|
|
123
|
+
request_id = getattr(self.aws_context, "aws_request_id", None)
|
|
124
|
+
self.logger.error(
|
|
125
|
+
"Unhandled exception for action %s",
|
|
126
|
+
context.action(),
|
|
127
|
+
exc_info=exc,
|
|
128
|
+
extra={"request_id": request_id},
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
logger.debug("starting BackOfficeEvents.onError")
|
|
132
|
+
|
|
133
|
+
temp = copy.deepcopy(context.postdata())
|
|
134
|
+
logger.debug("starting BackOfficeEvents.log")
|
|
135
|
+
temp["payload"].pop("cognito_user", None)
|
|
136
|
+
self.logger.error(
|
|
137
|
+
"Events.OnError %s",
|
|
138
|
+
temp.get("action"),
|
|
139
|
+
extra={"payload": pprint.pformat(temp), "traceback": tb},
|
|
140
|
+
)
|
|
141
|
+
logger.debug("Ending BackOfficeEvents.OnError Done")
|
|
199
142
|
|
|
200
143
|
def serve(self, tx):
|
|
201
144
|
response = Response()
|
|
@@ -223,7 +166,7 @@ class LambdaHandler(BaseHandler):
|
|
|
223
166
|
postdata=postdata,
|
|
224
167
|
response=response,
|
|
225
168
|
session=self.session,
|
|
226
|
-
log=lambda message, function=None: self.log(message, function),
|
|
169
|
+
log=lambda message, function=None: self.log(tx, message, function),
|
|
227
170
|
)
|
|
228
171
|
|
|
229
172
|
# Determine action from postdata or query parameters
|
|
@@ -268,11 +211,69 @@ class LambdaHandler(BaseHandler):
|
|
|
268
211
|
except Exception as exc: # pragma: no cover - best effort logging
|
|
269
212
|
self.log(tx, f"Failed to write tracking record: {exc}", "track")
|
|
270
213
|
|
|
214
|
+
def validate(self, user_required=True):
|
|
215
|
+
if user_required:
|
|
216
|
+
try:
|
|
217
|
+
attrs = self.cognito_user["attributes"]
|
|
218
|
+
assert attrs
|
|
219
|
+
assert attrs["email"]
|
|
220
|
+
assert attrs["sub"]
|
|
221
|
+
assert self.session["sub"]
|
|
222
|
+
assert self.session["sub"] == attrs["sub"]
|
|
223
|
+
except:
|
|
224
|
+
raise Exception("User Authentication Error [Cognito]")
|
|
225
|
+
else:
|
|
226
|
+
try:
|
|
227
|
+
if not self.session["sub"]:
|
|
228
|
+
# User is not signed in. If user_required
|
|
229
|
+
# is false, then simply return
|
|
230
|
+
return
|
|
231
|
+
attrs = self.cognito_user["attributes"]
|
|
232
|
+
assert attrs
|
|
233
|
+
assert attrs["email"]
|
|
234
|
+
assert attrs["sub"]
|
|
235
|
+
assert self.session["sub"]
|
|
236
|
+
assert self.session["sub"] == attrs["sub"]
|
|
237
|
+
except:
|
|
238
|
+
raise Exception("User Authentication Error [Cognito]")
|
|
239
|
+
|
|
240
|
+
def get_pass_through_vars(self, tx, context):
|
|
241
|
+
"""Get pass-through variables: environment vars, layers, and user data"""
|
|
242
|
+
temp = context.get_pass_through_vars(tx, self.current_user)
|
|
271
243
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
context.payload().get("data", {}),
|
|
276
|
-
user=context.session(),
|
|
277
|
-
context_obj=context,
|
|
244
|
+
logger.debug(
|
|
245
|
+
"LAYER_DEBUG: vars object contains: %s",
|
|
246
|
+
list(temp.get("controls", {}).get("vars", {}).keys()),
|
|
278
247
|
)
|
|
248
|
+
if "layers" in temp.get("controls", {}).get("vars", {}):
|
|
249
|
+
logger.debug(
|
|
250
|
+
"LAYER_DEBUG: layers value: %s",
|
|
251
|
+
temp["controls"]["vars"]["layers"],
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# Merge with user data from database
|
|
255
|
+
temp = context.merge_user_data(tx, temp, self.session["email_address"])
|
|
256
|
+
|
|
257
|
+
return temp
|
|
258
|
+
|
|
259
|
+
def _summarize_postdata(self, postdata):
|
|
260
|
+
"""Extract key fields from postdata for logging without storing entire payload"""
|
|
261
|
+
if not postdata:
|
|
262
|
+
return {}
|
|
263
|
+
|
|
264
|
+
summary = {
|
|
265
|
+
"action": postdata.get("action"),
|
|
266
|
+
"payload_keys": (
|
|
267
|
+
list(postdata.get("payload", {}).keys())
|
|
268
|
+
if isinstance(postdata.get("payload"), dict)
|
|
269
|
+
else None
|
|
270
|
+
),
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
# Add size info
|
|
274
|
+
try:
|
|
275
|
+
summary["payload_size_bytes"] = len(json.dumps(postdata.get("payload", {})))
|
|
276
|
+
except:
|
|
277
|
+
summary["payload_size_bytes"] = 0
|
|
278
|
+
|
|
279
|
+
return summary
|