python-sdk-remote 0.0.127__tar.gz → 0.0.128__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.127 → python_sdk_remote-0.0.128}/PKG-INFO +1 -1
- python_sdk_remote-0.0.128/README.md +11 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/constants.py +0 -9
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/http_response.py +51 -16
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/item.py +2 -3
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/our_object.py +0 -9
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/unified_json.py +0 -7
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/utilities.py +32 -32
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/PKG-INFO +1 -1
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/setup.py +1 -1
- python_sdk_remote-0.0.127/README.md +0 -27
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/pyproject.toml +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/__init__.py +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/mini_logger.py +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/valid_json_versions.py +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/validate_environment.py +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/SOURCES.txt +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/dependency_links.txt +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/requires.txt +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/top_level.txt +0 -0
- {python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/setup.cfg +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# TODO: rewrite with more example
|
|
2
|
+
|
|
3
|
+
In serverless, use this decorator:
|
|
4
|
+
```py
|
|
5
|
+
from python_sdk_remote.http_response import handler_decorator
|
|
6
|
+
from logger_local.Logger import Logger
|
|
7
|
+
logger = Logger.create_logger(object=your_logger_object)
|
|
8
|
+
@handler_decorator(logger=logger)
|
|
9
|
+
def my_handler(request_parameters: dict) -> dict:
|
|
10
|
+
# here you can use both camelCase and snake_case keys from request_parameters
|
|
11
|
+
```
|
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
1
|
from logger_local.LoggerComponentEnum import LoggerComponentEnum
|
|
4
2
|
|
|
5
3
|
PYTHON_SDK_REMOTE_COMPONENT_ID = 184
|
|
6
4
|
PYTHON_SDK_REMOTE_COMPONENT_NAME = 'python_sdk_remote'
|
|
7
5
|
|
|
8
|
-
ENVIRONMENT_NAME = os.getenv("ENVIRONMENT_NAME")
|
|
9
|
-
BRAND_NAME = os.getenv("BRAND_NAME")
|
|
10
|
-
LOGZIO_TOKEN = os.getenv("LOGZIO_TOKEN")
|
|
11
|
-
# TODO Shall Can we use python-sdk function to get the value from Environment?
|
|
12
|
-
# TODO Shall we get the value from environment here of send the value to the function as @akiva-skolnik did?
|
|
13
|
-
GOOGLE_PORT_FOR_AUTHENTICATION = os.getenv("PORT_FOR_AUTHENTICATION")
|
|
14
|
-
|
|
15
6
|
OBJECT_TO_INSERT_CODE = {
|
|
16
7
|
'component_id': PYTHON_SDK_REMOTE_COMPONENT_ID,
|
|
17
8
|
'component_name': PYTHON_SDK_REMOTE_COMPONENT_NAME,
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/http_response.py
RENAMED
|
@@ -1,10 +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
|
-
import
|
|
7
|
+
from .utilities import camel_to_snake, snake_to_camel, to_dict, to_json
|
|
8
8
|
|
|
9
9
|
HEADERS_KEY = 'headers'
|
|
10
10
|
AUTHORIZATION_KEY = 'authorization'
|
|
@@ -17,26 +17,65 @@ AUTHORIZATION_PREFIX = 'Bearer '
|
|
|
17
17
|
# TODO: add handler wrapper?
|
|
18
18
|
|
|
19
19
|
def get_payload_dict_from_event(event: dict) -> dict:
|
|
20
|
-
warnings.warn("DELETE get_payload_dict_from_event",DeprecationWarning,stacklevel=2)
|
|
21
20
|
"""Extracts params sent with payload"""
|
|
22
|
-
return
|
|
21
|
+
return to_dict(event.get('body'))
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
def get_path_parameters_dict_from_event(event: dict) -> dict:
|
|
26
|
-
warnings.warn("DELETE get_path_parameters_dict_from_event",DeprecationWarning,stacklevel=2)
|
|
27
25
|
"""Extracts params sent implicitly: `url/param?test=5` -> param
|
|
28
26
|
(when the path is defined with /{param})"""
|
|
29
27
|
return event.get('pathParameters') or {}
|
|
30
28
|
|
|
31
29
|
|
|
32
30
|
def get_query_string_parameters_from_event(event: dict) -> dict:
|
|
33
|
-
warnings.warn("DELETE get_query_string_parameters_from_event",DeprecationWarning,stacklevel=2)
|
|
34
31
|
"""Extracts params sent explicitly: `url/test?a=1&b=2` -> {'a': '1', 'b': '2'}"""
|
|
35
32
|
return event.get("queryStringParameters") or {} # params sent with ?a=1&b=2
|
|
36
33
|
|
|
37
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_parameters_dict = get_payload_dict_from_event(event)
|
|
40
|
+
all_parameters_dict.update(get_path_parameters_dict_from_event(event))
|
|
41
|
+
all_parameters_dict.update(get_query_string_parameters_from_event(event))
|
|
42
|
+
all_parameters_dict = {camel_to_snake(key): value for key, value in all_parameters_dict.items()}
|
|
43
|
+
all_parameters_dict.update({snake_to_camel(key): value for key, value in all_parameters_dict.items()})
|
|
44
|
+
return all_parameters_dict
|
|
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
|
+
|
|
77
|
+
# TODO: should we auto detect user_jwt if not provided?
|
|
38
78
|
def create_authorization_http_headers(user_jwt: str) -> dict:
|
|
39
|
-
warnings.warn("DELETE create_authorization_http_headers",DeprecationWarning,stacklevel=2)
|
|
40
79
|
logger.start(object={"user_jwt": user_jwt})
|
|
41
80
|
#TODO check the validity of user_jwt and it is not None and raise exception, please do the same in all other functions.
|
|
42
81
|
authorization_http_headers = {
|
|
@@ -48,7 +87,6 @@ def create_authorization_http_headers(user_jwt: str) -> dict:
|
|
|
48
87
|
|
|
49
88
|
|
|
50
89
|
def get_user_jwt_from_event(event: dict) -> str:
|
|
51
|
-
warnings.warn("DELETE get_user_jwt_from_event",DeprecationWarning,stacklevel=2)
|
|
52
90
|
logger.start(object={"event": event})
|
|
53
91
|
auth_header = event.get(HEADERS_KEY, {}).get(AUTHORIZATION_KEY)
|
|
54
92
|
if auth_header is None:
|
|
@@ -59,7 +97,6 @@ def get_user_jwt_from_event(event: dict) -> str:
|
|
|
59
97
|
|
|
60
98
|
|
|
61
99
|
def create_return_http_headers() -> dict:
|
|
62
|
-
warnings.warn("DELETE create_return_http_headers",DeprecationWarning,stacklevel=2)
|
|
63
100
|
logger.start()
|
|
64
101
|
# Adding "Access-Control-Allow-Origin" : "*" to take care of CORS from localhost
|
|
65
102
|
# TODO Do we need to add those? In which cases? try adding crossDomain: true, to the request, 'Access-Control-Allow-Credentials': true to header
|
|
@@ -72,7 +109,6 @@ def create_return_http_headers() -> dict:
|
|
|
72
109
|
|
|
73
110
|
|
|
74
111
|
def create_error_http_response(exception: Exception, status_code: HTTPStatus = HTTPStatus.BAD_REQUEST) -> dict:
|
|
75
|
-
warnings.warn("DELETE create_error_http_response",DeprecationWarning,stacklevel=2)
|
|
76
112
|
logger.start(object={"exception": exception})
|
|
77
113
|
error_http_response = {
|
|
78
114
|
"statusCode": status_code.value,
|
|
@@ -85,12 +121,12 @@ def create_error_http_response(exception: Exception, status_code: HTTPStatus = H
|
|
|
85
121
|
|
|
86
122
|
|
|
87
123
|
def create_ok_http_response(body: Any) -> dict:
|
|
88
|
-
warnings.warn("DELETE create_ok_http_response",DeprecationWarning,stacklevel=2)
|
|
89
124
|
logger.start(object={"body": body})
|
|
125
|
+
# TODO: test sending statusCode/headers/body inside the body
|
|
90
126
|
ok_http_response = {
|
|
91
|
-
"statusCode": HTTPStatus.OK.value,
|
|
92
|
-
"headers": create_return_http_headers(),
|
|
93
|
-
"body": create_http_body(body)
|
|
127
|
+
"statusCode": body.get("statusCode") or HTTPStatus.OK.value,
|
|
128
|
+
"headers": body.get("headers") or create_return_http_headers(),
|
|
129
|
+
"body": create_http_body(body.get("body") or body)
|
|
94
130
|
}
|
|
95
131
|
logger.end(object={"ok_http_response": ok_http_response})
|
|
96
132
|
return ok_http_response
|
|
@@ -98,10 +134,9 @@ def create_ok_http_response(body: Any) -> dict:
|
|
|
98
134
|
|
|
99
135
|
# https://google.github.io/styleguide/jsoncstyleguide.xml?showone=Property_Name_Format#Property_Name_Format
|
|
100
136
|
def create_http_body(body: Any) -> str:
|
|
101
|
-
warnings.warn("DELETE create_http_body",DeprecationWarning,stacklevel=2)
|
|
102
137
|
# TODO console.warning() if the body is not a valid camelCase JSON
|
|
103
138
|
# https://stackoverflow.com/questions/17156078/converting-identifier-naming-between-camelcase-and-underscores-during-json-seria
|
|
104
139
|
logger.start(object={"body": body})
|
|
105
|
-
http_body =
|
|
140
|
+
http_body = to_json(body)
|
|
106
141
|
logger.end(object={"http_body": http_body})
|
|
107
142
|
return http_body
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
3
|
from .our_object import OurObject
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
|
|
5
6
|
class Item(OurObject):
|
|
6
7
|
def __init__(self, **kwargs):
|
|
7
|
-
warnings.warn("DELETE __init__",DeprecationWarning,stacklevel=2)
|
|
8
8
|
super().__init__(**kwargs)
|
|
9
9
|
|
|
10
10
|
@abstractmethod
|
|
11
11
|
def get_id(self):
|
|
12
|
-
warnings.warn("DELETE get_id",DeprecationWarning,stacklevel=2)
|
|
13
12
|
raise NotImplementedError("Subclasses must implement the 'get_id' method.")
|
|
@@ -2,13 +2,11 @@ import json
|
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
|
|
4
4
|
from .mini_logger import MiniLogger as logger
|
|
5
|
-
import warnings
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
# TODO Where are we using it? Shall we extend the usage of OurObject as the father of all our entities?
|
|
9
8
|
class OurObject(ABC):
|
|
10
9
|
def __init__(self, **kwargs):
|
|
11
|
-
warnings.warn("DELETE __init__",DeprecationWarning,stacklevel=2)
|
|
12
10
|
INIT_METHOD_NAME = '__init__'
|
|
13
11
|
logger.start(INIT_METHOD_NAME, object={'kwargs': kwargs})
|
|
14
12
|
self.kwargs = kwargs
|
|
@@ -16,13 +14,11 @@ class OurObject(ABC):
|
|
|
16
14
|
|
|
17
15
|
@abstractmethod
|
|
18
16
|
def get_name(self):
|
|
19
|
-
warnings.warn("DELETE get_name",DeprecationWarning,stacklevel=2)
|
|
20
17
|
"""Returns the name of the object"""
|
|
21
18
|
raise NotImplementedError(
|
|
22
19
|
"Subclasses must implement the 'get_name' method.")
|
|
23
20
|
|
|
24
21
|
def get(self, attr_name: str):
|
|
25
|
-
warnings.warn("DELETE get",DeprecationWarning,stacklevel=2)
|
|
26
22
|
"""Returns the value of the attribute with the given name"""
|
|
27
23
|
GET_METHOD_NAME = 'get'
|
|
28
24
|
logger.start(GET_METHOD_NAME, object={'attr_name': attr_name})
|
|
@@ -32,17 +28,14 @@ class OurObject(ABC):
|
|
|
32
28
|
return value
|
|
33
29
|
|
|
34
30
|
def get_all_arguments(self):
|
|
35
|
-
warnings.warn("DELETE get_all_arguments",DeprecationWarning,stacklevel=2)
|
|
36
31
|
"""Returns all the arguments passed to the constructor as a dictionary"""
|
|
37
32
|
return getattr(self, 'kwargs', None)
|
|
38
33
|
|
|
39
34
|
def to_json(self) -> str:
|
|
40
|
-
warnings.warn("DELETE to_json",DeprecationWarning,stacklevel=2)
|
|
41
35
|
"""Returns a json string representation of this object"""
|
|
42
36
|
return json.dumps(self.__dict__)
|
|
43
37
|
|
|
44
38
|
def from_json(self, json_string: str) -> 'OurObject':
|
|
45
|
-
warnings.warn("DELETE from_json",DeprecationWarning,stacklevel=2)
|
|
46
39
|
"""Returns an instance of the class from a json string"""
|
|
47
40
|
FROM_JSON_METHOD_NAME = 'from_json'
|
|
48
41
|
logger.start(FROM_JSON_METHOD_NAME,
|
|
@@ -53,13 +46,11 @@ class OurObject(ABC):
|
|
|
53
46
|
return self
|
|
54
47
|
|
|
55
48
|
def __eq__(self, other) -> bool:
|
|
56
|
-
warnings.warn("DELETE __eq__",DeprecationWarning,stacklevel=2)
|
|
57
49
|
"""Checks if two objects are equal"""
|
|
58
50
|
if not isinstance(other, OurObject):
|
|
59
51
|
return False
|
|
60
52
|
return self.__dict__ == other.__dict__
|
|
61
53
|
|
|
62
54
|
def __ne__(self, other) -> bool:
|
|
63
|
-
warnings.warn("DELETE __ne__",DeprecationWarning,stacklevel=2)
|
|
64
55
|
"""Checks if two objects are not equal"""
|
|
65
56
|
return not self.__eq__(other)
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/unified_json.py
RENAMED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
from .valid_json_versions import valid_json_versions
|
|
2
|
-
import warnings
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
# TODO Shall we merge it with the machine-learning-unified-json?
|
|
6
5
|
class UnifiedJson:
|
|
7
6
|
def __init__(self, data: dict, json_version: str):
|
|
8
|
-
warnings.warn("DELETE __init__",DeprecationWarning,stacklevel=2)
|
|
9
7
|
if json_version not in valid_json_versions:
|
|
10
8
|
raise Exception(
|
|
11
9
|
f"version {json_version} is not in valid_json_versions {valid_json_versions}, "
|
|
@@ -15,21 +13,16 @@ class UnifiedJson:
|
|
|
15
13
|
self.data = data
|
|
16
14
|
|
|
17
15
|
def get_unified_json(self):
|
|
18
|
-
warnings.warn("DELETE get_unified_json",DeprecationWarning,stacklevel=2)
|
|
19
16
|
return {"version": self.json_version, "data": self.data}
|
|
20
17
|
|
|
21
18
|
def get_data(self):
|
|
22
|
-
warnings.warn("DELETE get_data",DeprecationWarning,stacklevel=2)
|
|
23
19
|
return self.data
|
|
24
20
|
|
|
25
21
|
def get_json_version(self):
|
|
26
|
-
warnings.warn("DELETE get_json_version",DeprecationWarning,stacklevel=2)
|
|
27
22
|
return self.json_version
|
|
28
23
|
|
|
29
24
|
def __str__(self):
|
|
30
|
-
warnings.warn("DELETE __str__",DeprecationWarning,stacklevel=2)
|
|
31
25
|
return self.get_unified_json()
|
|
32
26
|
|
|
33
27
|
def __repr__(self):
|
|
34
|
-
warnings.warn("DELETE __repr__",DeprecationWarning,stacklevel=2)
|
|
35
28
|
return self.__str__()
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
+
import inspect
|
|
1
2
|
import json
|
|
2
|
-
import jwt
|
|
3
|
-
import requests
|
|
4
|
-
import re
|
|
5
3
|
import os
|
|
6
4
|
import random
|
|
5
|
+
import re
|
|
7
6
|
from datetime import date, datetime, time, timedelta, timezone
|
|
7
|
+
from functools import lru_cache
|
|
8
8
|
from urllib.parse import urlparse
|
|
9
|
-
import warnings
|
|
10
9
|
|
|
10
|
+
import jwt
|
|
11
|
+
import requests
|
|
11
12
|
from dotenv import load_dotenv
|
|
12
13
|
from url_remote.environment_name_enum import EnvironmentName
|
|
13
14
|
|
|
14
15
|
from .mini_logger import MiniLogger as logger
|
|
15
|
-
from .http_response import (create_authorization_http_headers, # noqa - used for backwards compatibility
|
|
16
|
-
get_user_jwt_from_event,
|
|
17
|
-
create_return_http_headers, create_error_http_response, create_ok_http_response,
|
|
18
|
-
create_http_body)
|
|
19
16
|
|
|
20
17
|
load_dotenv()
|
|
21
18
|
# TODO Let's do brainstorming on this
|
|
@@ -36,13 +33,11 @@ DEFAULT_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
|
|
|
36
33
|
|
|
37
34
|
|
|
38
35
|
def append_if_not_exist(lst: list, item: object) -> None:
|
|
39
|
-
warnings.warn("DELETE append_if_not_exist",DeprecationWarning,stacklevel=2)
|
|
40
36
|
if item not in lst:
|
|
41
37
|
lst.append(item)
|
|
42
38
|
|
|
43
39
|
|
|
44
40
|
def to_dict(data: json or dict or None) -> dict:
|
|
45
|
-
warnings.warn("DELETE to_dict",DeprecationWarning,stacklevel=2)
|
|
46
41
|
if data is None:
|
|
47
42
|
return {}
|
|
48
43
|
if isinstance(data, dict):
|
|
@@ -51,7 +46,6 @@ def to_dict(data: json or dict or None) -> dict:
|
|
|
51
46
|
|
|
52
47
|
|
|
53
48
|
def to_json(data: json or dict or None) -> json:
|
|
54
|
-
warnings.warn("DELETE to_json",DeprecationWarning,stacklevel=2)
|
|
55
49
|
if data is None:
|
|
56
50
|
data = {}
|
|
57
51
|
if isinstance(data, dict):
|
|
@@ -60,7 +54,6 @@ def to_json(data: json or dict or None) -> json:
|
|
|
60
54
|
|
|
61
55
|
|
|
62
56
|
def timedelta_to_time_format(time_delta: timedelta) -> str:
|
|
63
|
-
warnings.warn("DELETE timedelta_to_time_format",DeprecationWarning,stacklevel=2)
|
|
64
57
|
"""
|
|
65
58
|
Convert a timedelta to a time format in HH:MM:SS.
|
|
66
59
|
|
|
@@ -97,7 +90,6 @@ def timedelta_to_time_format(time_delta: timedelta) -> str:
|
|
|
97
90
|
|
|
98
91
|
|
|
99
92
|
def is_valid_time_range(time_range: tuple) -> bool:
|
|
100
|
-
warnings.warn("DELETE is_valid_time_range",DeprecationWarning,stacklevel=2)
|
|
101
93
|
"""
|
|
102
94
|
Validate that the time range is in the format 'HH:MM:SS'.
|
|
103
95
|
"""
|
|
@@ -124,7 +116,6 @@ def is_valid_time_range(time_range: tuple) -> bool:
|
|
|
124
116
|
# TODO shall we also use Url type and not only str? - Strongly Type which I prefer
|
|
125
117
|
# (if yes we should change it also in all the calls to this function)
|
|
126
118
|
def validate_url(url: str):
|
|
127
|
-
warnings.warn("DELETE validate_url",DeprecationWarning,stacklevel=2)
|
|
128
119
|
logger.start(object={"url": url})
|
|
129
120
|
if url is not None or url != "":
|
|
130
121
|
parsed_url = urlparse(url)
|
|
@@ -136,7 +127,6 @@ def validate_url(url: str):
|
|
|
136
127
|
|
|
137
128
|
|
|
138
129
|
def is_valid_date_range(date_range: tuple) -> bool:
|
|
139
|
-
warnings.warn("DELETE is_valid_date_range",DeprecationWarning,stacklevel=2)
|
|
140
130
|
"""
|
|
141
131
|
Validate that the date range is in the format 'YYYY-MM-DD'.
|
|
142
132
|
"""
|
|
@@ -155,7 +145,6 @@ def is_valid_date_range(date_range: tuple) -> bool:
|
|
|
155
145
|
|
|
156
146
|
|
|
157
147
|
def is_valid_datetime_range(datetime_range: (datetime, datetime)) -> bool:
|
|
158
|
-
warnings.warn("DELETE is_valid_datetime_range",DeprecationWarning,stacklevel=2)
|
|
159
148
|
"""
|
|
160
149
|
Validate that the datetime range is in the format 'YYYY-MM-DD HH:MM:SS'.
|
|
161
150
|
"""
|
|
@@ -173,7 +162,6 @@ def is_valid_datetime_range(datetime_range: (datetime, datetime)) -> bool:
|
|
|
173
162
|
|
|
174
163
|
|
|
175
164
|
def is_list_of_dicts(obj: object) -> bool:
|
|
176
|
-
warnings.warn("DELETE is_list_of_dicts",DeprecationWarning,stacklevel=2)
|
|
177
165
|
"""
|
|
178
166
|
Check if an object is a list of dictionaries.
|
|
179
167
|
|
|
@@ -218,7 +206,6 @@ def is_list_of_dicts(obj: object) -> bool:
|
|
|
218
206
|
|
|
219
207
|
|
|
220
208
|
def is_time_in_time_range(check_time: time, time_range: tuple) -> bool:
|
|
221
|
-
warnings.warn("DELETE is_time_in_time_range",DeprecationWarning,stacklevel=2)
|
|
222
209
|
"""
|
|
223
210
|
Check if the given time is within the specified time range.
|
|
224
211
|
|
|
@@ -242,7 +229,6 @@ def is_time_in_time_range(check_time: time, time_range: tuple) -> bool:
|
|
|
242
229
|
|
|
243
230
|
|
|
244
231
|
def is_date_in_date_range(check_date: date, date_range: tuple) -> bool:
|
|
245
|
-
warnings.warn("DELETE is_date_in_date_range",DeprecationWarning,stacklevel=2)
|
|
246
232
|
"""
|
|
247
233
|
Check if the given date is within the specified date range.
|
|
248
234
|
|
|
@@ -267,7 +253,6 @@ def is_date_in_date_range(check_date: date, date_range: tuple) -> bool:
|
|
|
267
253
|
|
|
268
254
|
|
|
269
255
|
def is_datetime_in_datetime_range(check_datetime: datetime, datetime_range: (datetime, datetime)) -> bool:
|
|
270
|
-
warnings.warn("DELETE is_datetime_in_datetime_range",DeprecationWarning,stacklevel=2)
|
|
271
256
|
"""
|
|
272
257
|
Check if the given datetime is within the specified datetime range.
|
|
273
258
|
|
|
@@ -331,7 +316,6 @@ def get_dialog_jwt_secret_key() -> str:
|
|
|
331
316
|
|
|
332
317
|
|
|
333
318
|
def encode_jwt(payload: dict, key: str) -> str:
|
|
334
|
-
warnings.warn("DELETE encode_jwt",DeprecationWarning,stacklevel=2)
|
|
335
319
|
"""Example:
|
|
336
320
|
payload = {
|
|
337
321
|
"user_id": 123,
|
|
@@ -343,7 +327,6 @@ def encode_jwt(payload: dict, key: str) -> str:
|
|
|
343
327
|
|
|
344
328
|
|
|
345
329
|
def decode_jwt(token: str, key: str) -> dict:
|
|
346
|
-
warnings.warn("DELETE decode_jwt",DeprecationWarning,stacklevel=2)
|
|
347
330
|
"""key can be private / public"""
|
|
348
331
|
return jwt.decode(token, key, algorithms=['HS256'])
|
|
349
332
|
|
|
@@ -369,44 +352,39 @@ def obfuscate_log_dict(log_dict: dict) -> dict:
|
|
|
369
352
|
if isinstance(value, dict):
|
|
370
353
|
obfuscated_log_dict[key] = obfuscate_log_dict(value)
|
|
371
354
|
elif re.search(r'password|secret|token|jwt|e[\-_]?mail|phone|name|address|ssn', key, re.IGNORECASE):
|
|
372
|
-
|
|
355
|
+
# TODO Maybe we can reveal a small part
|
|
373
356
|
obfuscated_log_dict[key] = "***"
|
|
374
357
|
else:
|
|
375
358
|
obfuscated_log_dict[key] = value
|
|
376
359
|
return obfuscated_log_dict
|
|
377
360
|
|
|
361
|
+
|
|
378
362
|
# TODO: add tests to the following functions
|
|
379
363
|
|
|
380
364
|
def remove_digits(text: str) -> str:
|
|
381
|
-
warnings.warn("DELETE remove_digits",DeprecationWarning,stacklevel=2)
|
|
382
365
|
return ''.join(i for i in text if not i.isdigit())
|
|
383
366
|
|
|
384
367
|
|
|
385
368
|
def generate_otp():
|
|
386
|
-
warnings.warn("DELETE generate_otp",DeprecationWarning,stacklevel=2)
|
|
387
369
|
"""Generates a 6-digit OTP"""
|
|
388
370
|
otp = random.randint(100000, 999999)
|
|
389
371
|
return otp
|
|
390
372
|
|
|
391
373
|
|
|
392
374
|
def get_current_datetime_string(datetime_format: str = DEFAULT_DATETIME_FORMAT, tz: timezone = None) -> str:
|
|
393
|
-
warnings.warn("DELETE get_current_datetime_string",DeprecationWarning,stacklevel=2)
|
|
394
375
|
current_datetime_string = datetime.now(tz).strftime(datetime_format)
|
|
395
376
|
return current_datetime_string
|
|
396
377
|
|
|
397
378
|
|
|
398
379
|
def datetime_from_str(date_str: str, datetime_format: str = DEFAULT_DATETIME_FORMAT) -> datetime:
|
|
399
|
-
warnings.warn("DELETE datetime_from_str",DeprecationWarning,stacklevel=2)
|
|
400
380
|
return datetime.strptime(date_str, datetime_format)
|
|
401
381
|
|
|
402
382
|
|
|
403
383
|
def datetime_to_str(input_datetime: datetime, datetime_format: str = DEFAULT_DATETIME_FORMAT) -> str:
|
|
404
|
-
warnings.warn("DELETE datetime_to_str",DeprecationWarning,stacklevel=2)
|
|
405
384
|
return input_datetime.strftime(datetime_format)
|
|
406
385
|
|
|
407
386
|
|
|
408
387
|
def validate_arguments(args: dict) -> None:
|
|
409
|
-
warnings.warn("DELETE validate_arguments",DeprecationWarning,stacklevel=2)
|
|
410
388
|
"""
|
|
411
389
|
Validate method arguments to ensure they are not None or ''
|
|
412
390
|
:param args: arguments to be validated (usually locals())
|
|
@@ -418,7 +396,6 @@ def validate_arguments(args: dict) -> None:
|
|
|
418
396
|
|
|
419
397
|
|
|
420
398
|
def reformat_time_string(input_str: str) -> str:
|
|
421
|
-
warnings.warn("DELETE reformat_time_string",DeprecationWarning,stacklevel=2)
|
|
422
399
|
"""Example:
|
|
423
400
|
"1234" -> "12:34:00:00"
|
|
424
401
|
"""
|
|
@@ -432,10 +409,33 @@ def reformat_time_string(input_str: str) -> str:
|
|
|
432
409
|
|
|
433
410
|
|
|
434
411
|
def get_ip_v4():
|
|
435
|
-
warnings.warn("DELETE get_ip_v4",DeprecationWarning,stacklevel=2)
|
|
436
412
|
return requests.get('https://ipv4.seeip.org/jsonip').json()['ip']
|
|
437
413
|
|
|
438
414
|
|
|
439
415
|
def get_ip_v6():
|
|
440
|
-
warnings.warn("DELETE get_ip_v6",DeprecationWarning,stacklevel=2)
|
|
441
416
|
return requests.get('https://api.seeip.org/jsonip').json()['ip']
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def snake_to_camel(snake_str: str) -> str:
|
|
420
|
+
"""Converts snake_case to camelCase."""
|
|
421
|
+
components = snake_str.split('_')
|
|
422
|
+
camel_str = components[0] + ''.join(x.title() for x in components[1:])
|
|
423
|
+
return camel_str
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def camel_to_snake(camel_str: str) -> str:
|
|
427
|
+
"""Converts camelCase to snake_case."""
|
|
428
|
+
snake_str = re.sub(r'(?<!^)(?=[A-Z])', '_', camel_str).lower()
|
|
429
|
+
return snake_str
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
@lru_cache(maxsize=64) # don't print the same warning multiple times
|
|
433
|
+
def deprecation_warning(old_name: str, new_name: str, start_date: date = None) -> None:
|
|
434
|
+
if start_date and start_date < date.today():
|
|
435
|
+
return
|
|
436
|
+
warnings_message = f"Please use {old_name} instead of {new_name}."
|
|
437
|
+
try:
|
|
438
|
+
warnings_message += " Called from: " + inspect.stack()[2].filename
|
|
439
|
+
except Exception:
|
|
440
|
+
pass
|
|
441
|
+
logger.warning(warnings_message)
|
|
@@ -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.128', # 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",
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# python-sdk-package
|
|
2
|
-
|
|
3
|
-
https://github.com/grosser/repo_dependency_graph Ruby, Graph the dependencies of your repositories
|
|
4
|
-
https://github.com/thebjorn/pydeps Python
|
|
5
|
-
|
|
6
|
-
To create local package and remote package layers (not to create GraphQL and REST-API layers)
|
|
7
|
-
|
|
8
|
-
#database Python scripts in /db folder
|
|
9
|
-
Please place <table-name>.py in /db<br>
|
|
10
|
-
No need for seperate file for _ml table<br>
|
|
11
|
-
Please delete the example file if not needed<br>
|
|
12
|
-
|
|
13
|
-
# Create the files to create the database schema, tables, view and populate Meta Data and Test Date
|
|
14
|
-
|
|
15
|
-
/db/<table-name>.py - CREATE SCHEMA ... CREATE TABLE ... CREATE VIEW ...<br>
|
|
16
|
-
/db/<table-name>_insert.py to create records
|
|
17
|
-
|
|
18
|
-
# Update the setup.py (i.e.name, version)
|
|
19
|
-
|
|
20
|
-
# Please create test directory inside the directory of the project i.e. /<project-name>/tests
|
|
21
|
-
|
|
22
|
-
# Update the serverless.yml in the root directory
|
|
23
|
-
|
|
24
|
-
provider:
|
|
25
|
-
stage: play1
|
|
26
|
-
|
|
27
|
-
Update the endpoints in serverless.yml
|
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/mini_logger.py
RENAMED
|
File without changes
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote/src/valid_json_versions.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/requires.txt
RENAMED
|
File without changes
|
{python_sdk_remote-0.0.127 → python_sdk_remote-0.0.128}/python_sdk_remote.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|