python-sdk-remote 0.0.121__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 python-sdk-remote might be problematic. Click here for more details.
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/PKG-INFO +1 -1
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/http_response.py +50 -6
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/utilities.py +15 -5
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/PKG-INFO +1 -1
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/setup.py +1 -1
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/README.md +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/pyproject.toml +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/__init__.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/constants.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/item.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/mini_logger.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/our_object.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/unified_json.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/valid_json_versions.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/validate_environment.py +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/SOURCES.txt +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/dependency_links.txt +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/requires.txt +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/top_level.txt +0 -0
- {python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/setup.cfg +0 -0
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/http_response.py
RENAMED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import traceback
|
|
2
|
+
from functools import wraps
|
|
3
3
|
from http import HTTPStatus
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
6
|
from .mini_logger import MiniLogger as logger
|
|
7
|
+
from .utilities import camel_to_snake, snake_to_camel, to_dict, to_json
|
|
7
8
|
|
|
8
9
|
HEADERS_KEY = 'headers'
|
|
9
10
|
AUTHORIZATION_KEY = 'authorization'
|
|
@@ -17,7 +18,7 @@ AUTHORIZATION_PREFIX = 'Bearer '
|
|
|
17
18
|
|
|
18
19
|
def get_payload_dict_from_event(event: dict) -> dict:
|
|
19
20
|
"""Extracts params sent with payload"""
|
|
20
|
-
return
|
|
21
|
+
return to_dict(event.get('body'))
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def get_path_parameters_dict_from_event(event: dict) -> dict:
|
|
@@ -31,6 +32,48 @@ def get_query_string_parameters_from_event(event: dict) -> dict:
|
|
|
31
32
|
return event.get("queryStringParameters") or {} # params sent with ?a=1&b=2
|
|
32
33
|
|
|
33
34
|
|
|
35
|
+
def get_request_parameters_from_event(event: dict) -> dict:
|
|
36
|
+
"""Extracts all params from the event object.
|
|
37
|
+
The order of precedence is: payload > path > query string
|
|
38
|
+
returns a dictionary with all the parameters, with both camelCase and snake_case keys."""
|
|
39
|
+
all_params = get_payload_dict_from_event(event)
|
|
40
|
+
all_params.update(get_path_parameters_dict_from_event(event))
|
|
41
|
+
all_params.update(get_query_string_parameters_from_event(event))
|
|
42
|
+
all_params = {camel_to_snake(key): value for key, value in all_params.items()}
|
|
43
|
+
all_params.update({snake_to_camel(key): value for key, value in all_params.items()})
|
|
44
|
+
return all_params
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# TODO: test
|
|
48
|
+
def handler_decorator(logger):
|
|
49
|
+
"""Decorator for AWS Lambda handler functions. It wraps the handler function with logging and error handling.
|
|
50
|
+
Usage:
|
|
51
|
+
from python_sdk_remote.http_response import handler_decorator
|
|
52
|
+
logger = ...
|
|
53
|
+
@handler_decorator(logger=logger)
|
|
54
|
+
def my_handler(request_parameters: dict) -> dict:
|
|
55
|
+
return {"message": "Hello, World!"}"""
|
|
56
|
+
|
|
57
|
+
def decorator(handler: callable) -> callable:
|
|
58
|
+
@wraps(handler)
|
|
59
|
+
def wrapper(event, context):
|
|
60
|
+
handler_response = None
|
|
61
|
+
try:
|
|
62
|
+
logger.start(object={"event": event, "context": context})
|
|
63
|
+
request_parameters = get_request_parameters_from_event(event)
|
|
64
|
+
body_result: dict = handler(request_parameters)
|
|
65
|
+
handler_response = create_ok_http_response(body_result)
|
|
66
|
+
except Exception as e:
|
|
67
|
+
handler_response = create_error_http_response(e)
|
|
68
|
+
finally:
|
|
69
|
+
logger.end(object={"handler_response": handler_response})
|
|
70
|
+
return handler_response
|
|
71
|
+
|
|
72
|
+
return wrapper
|
|
73
|
+
|
|
74
|
+
return decorator
|
|
75
|
+
|
|
76
|
+
|
|
34
77
|
def create_authorization_http_headers(user_jwt: str) -> dict:
|
|
35
78
|
logger.start(object={"user_jwt": user_jwt})
|
|
36
79
|
authorization_http_headers = {
|
|
@@ -75,10 +118,11 @@ def create_error_http_response(exception: Exception, status_code: HTTPStatus = H
|
|
|
75
118
|
|
|
76
119
|
def create_ok_http_response(body: Any) -> dict:
|
|
77
120
|
logger.start(object={"body": body})
|
|
121
|
+
# TODO: test sending statusCode/headers/body inside the body
|
|
78
122
|
ok_http_response = {
|
|
79
|
-
"statusCode": HTTPStatus.OK.value,
|
|
80
|
-
"headers": create_return_http_headers(),
|
|
81
|
-
"body": create_http_body(body)
|
|
123
|
+
"statusCode": body.get("statusCode") or HTTPStatus.OK.value,
|
|
124
|
+
"headers": body.get("headers") or create_return_http_headers(),
|
|
125
|
+
"body": create_http_body(body.get("body") or body)
|
|
82
126
|
}
|
|
83
127
|
logger.end(object={"ok_http_response": ok_http_response})
|
|
84
128
|
return ok_http_response
|
|
@@ -89,6 +133,6 @@ def create_http_body(body: Any) -> str:
|
|
|
89
133
|
# TODO console.warning() if the body is not a valid camelCase JSON
|
|
90
134
|
# https://stackoverflow.com/questions/17156078/converting-identifier-naming-between-camelcase-and-underscores-during-json-seria
|
|
91
135
|
logger.start(object={"body": body})
|
|
92
|
-
http_body =
|
|
136
|
+
http_body = to_json(body)
|
|
93
137
|
logger.end(object={"http_body": http_body})
|
|
94
138
|
return http_body
|
|
@@ -11,10 +11,6 @@ from dotenv import load_dotenv
|
|
|
11
11
|
from url_remote.environment_name_enum import EnvironmentName
|
|
12
12
|
|
|
13
13
|
from .mini_logger import MiniLogger as logger
|
|
14
|
-
from .http_response import (create_authorization_http_headers, # noqa - used for backwards compatibility
|
|
15
|
-
get_user_jwt_from_event,
|
|
16
|
-
create_return_http_headers, create_error_http_response, create_ok_http_response,
|
|
17
|
-
create_http_body)
|
|
18
14
|
|
|
19
15
|
load_dotenv()
|
|
20
16
|
# TODO Let's do brainstorming on this
|
|
@@ -354,12 +350,13 @@ def obfuscate_log_dict(log_dict: dict) -> dict:
|
|
|
354
350
|
if isinstance(value, dict):
|
|
355
351
|
obfuscated_log_dict[key] = obfuscate_log_dict(value)
|
|
356
352
|
elif re.search(r'password|secret|token|jwt|e[\-_]?mail|phone|name|address|ssn', key, re.IGNORECASE):
|
|
357
|
-
|
|
353
|
+
# TODO Maybe we can reveal a small part
|
|
358
354
|
obfuscated_log_dict[key] = "***"
|
|
359
355
|
else:
|
|
360
356
|
obfuscated_log_dict[key] = value
|
|
361
357
|
return obfuscated_log_dict
|
|
362
358
|
|
|
359
|
+
|
|
363
360
|
# TODO: add tests to the following functions
|
|
364
361
|
|
|
365
362
|
def remove_digits(text: str) -> str:
|
|
@@ -415,3 +412,16 @@ def get_ip_v4():
|
|
|
415
412
|
|
|
416
413
|
def get_ip_v6():
|
|
417
414
|
return requests.get('https://api.seeip.org/jsonip').json()['ip']
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def snake_to_camel(snake_str: str) -> str:
|
|
418
|
+
"""Converts snake_case to camelCase."""
|
|
419
|
+
components = snake_str.split('_')
|
|
420
|
+
camel_str = components[0] + ''.join(x.title() for x in components[1:])
|
|
421
|
+
return camel_str
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def camel_to_snake(camel_str: str) -> str:
|
|
425
|
+
"""Converts camelCase to snake_case."""
|
|
426
|
+
snake_str = re.sub(r'(?<!^)(?=[A-Z])', '_', camel_str).lower()
|
|
427
|
+
return snake_str
|
|
@@ -7,7 +7,7 @@ package_dir = PACKAGE_NAME.replace("-", "_")
|
|
|
7
7
|
# python -m build needs pyproject.toml or setup.py
|
|
8
8
|
setuptools.setup(
|
|
9
9
|
name=PACKAGE_NAME,
|
|
10
|
-
version='0.0.
|
|
10
|
+
version='0.0.124', # https://pypi.org/project/python-sdk-remote/
|
|
11
11
|
author="Circles",
|
|
12
12
|
author_email="info@circlez.ai",
|
|
13
13
|
description="PyPI Package for Circles Python SDK Local Python",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/mini_logger.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/unified_json.py
RENAMED
|
File without changes
|
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote/src/valid_json_versions.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/requires.txt
RENAMED
|
File without changes
|
{python_sdk_remote-0.0.121 → python_sdk_remote-0.0.124}/python_sdk_remote.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|