python-sdk-remote 0.0.60__tar.gz → 0.0.63__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.60 → python-sdk-remote-0.0.63}/PKG-INFO +1 -1
- {python-sdk-remote-0.0.60 → python-sdk-remote-0.0.63}/README.md +7 -4
- {python-sdk-remote-0.0.60 → python-sdk-remote-0.0.63}/pyproject.toml +1 -1
- python-sdk-remote-0.0.63/python_sdk_remote/src/__init__.py +0 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/constants.py +25 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/item.py +12 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/mini_logger.py +91 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/our_object.py +59 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/unified_json.py +18 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/utilities.py +303 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/valid_json_versions.py +4 -0
- python-sdk-remote-0.0.63/python_sdk_remote/src/validate_environment.py +32 -0
- {python-sdk-remote-0.0.60 → python-sdk-remote-0.0.63}/python_sdk_remote.egg-info/PKG-INFO +1 -1
- python-sdk-remote-0.0.63/python_sdk_remote.egg-info/SOURCES.txt +16 -0
- python-sdk-remote-0.0.63/python_sdk_remote.egg-info/top_level.txt +1 -0
- {python-sdk-remote-0.0.60 → python-sdk-remote-0.0.63}/setup.py +11 -6
- python-sdk-remote-0.0.60/python_sdk_remote.egg-info/SOURCES.txt +0 -7
- python-sdk-remote-0.0.60/python_sdk_remote.egg-info/top_level.txt +0 -1
- {python-sdk-remote-0.0.60 → python-sdk-remote-0.0.63}/python_sdk_remote.egg-info/dependency_links.txt +0 -0
- {python-sdk-remote-0.0.60 → python-sdk-remote-0.0.63}/setup.cfg +0 -0
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
# python-package-backend-template
|
|
2
|
+
|
|
2
3
|
To create local package and remote package layers (not to create GraphQL and REST-API layers)
|
|
3
4
|
|
|
4
5
|
#database Python scripts in /db folder
|
|
5
6
|
Please place <table-name>.py in /db<br>
|
|
6
7
|
No need for seperate file for _ml table<br>
|
|
7
8
|
Please delete the example file if not needed<br>
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
# Create the files to create the database schema, tables, view and populate Meta Data and Test Date
|
|
11
|
+
|
|
10
12
|
/db/<table-name>.py - CREATE SCHEMA ... CREATE TABLE ... CREATE VIEW ...<br>
|
|
11
13
|
/db/<table-name>_insert.py to create records
|
|
12
14
|
|
|
13
15
|
# Update the setup.py (i.e.name, version)
|
|
14
|
-
|
|
16
|
+
|
|
15
17
|
# Please create test directory inside the directory of the project i.e. /<project-name>/tests
|
|
16
18
|
|
|
17
19
|
# Update the serverless.yml in the root directory
|
|
20
|
+
|
|
18
21
|
provider:
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
stage: play1
|
|
23
|
+
|
|
21
24
|
Update the endpoints in serverless.yml
|
|
@@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
|
|
|
10
10
|
[tool.poetry]
|
|
11
11
|
name = "python-sdk-local"
|
|
12
12
|
# I believe we are still using the version from setup.py and not from here until potery will work
|
|
13
|
-
version = "0.0.
|
|
13
|
+
version = "0.0.1" # https://pypi.org/project/python-sdk-local i.e. https://pypi.org/project/storage-local/
|
|
14
14
|
description = "python-sdk-local Python Package"
|
|
15
15
|
readme = "README.md"
|
|
16
16
|
authors = [
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from logger_local.LoggerComponentEnum import LoggerComponentEnum
|
|
4
|
+
|
|
5
|
+
PYTHON_SDK_LOCAL_COMPONENT_ID = 184
|
|
6
|
+
PYTHON_SDK_LOCAL_COMPONENT_NAME = 'python_sdk_local'
|
|
7
|
+
|
|
8
|
+
ENVIRONMENT_NAME = os.getenv("ENVIRONMENT_NAME")
|
|
9
|
+
BRAND_NAME = os.getenv("BRAND_NAME")
|
|
10
|
+
LOGZIO_TOKEN = os.getenv("LOGZIO_TOKEN")
|
|
11
|
+
|
|
12
|
+
OBJECT_TO_INSERT_CODE = {
|
|
13
|
+
'component_id': PYTHON_SDK_LOCAL_COMPONENT_ID,
|
|
14
|
+
'component_name': PYTHON_SDK_LOCAL_COMPONENT_NAME,
|
|
15
|
+
'component_category': LoggerComponentEnum.ComponentCategory.Code.value,
|
|
16
|
+
'developer_email': 'sahar.g@circ.zone'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
OBJECT_TO_INSERT_TEST = {
|
|
20
|
+
'component_id': PYTHON_SDK_LOCAL_COMPONENT_ID,
|
|
21
|
+
'component_name': PYTHON_SDK_LOCAL_COMPONENT_NAME,
|
|
22
|
+
'component_category': LoggerComponentEnum.ComponentCategory.Unit_Test.value,
|
|
23
|
+
'testing_framework': LoggerComponentEnum.testingFramework.pytest.value,
|
|
24
|
+
'developer_email': 'sahar.g@circ.zone'
|
|
25
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
from .our_object import OurObject
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Item(OurObject):
|
|
7
|
+
def __init__(self, **kwargs):
|
|
8
|
+
super().__init__(**kwargs)
|
|
9
|
+
|
|
10
|
+
@abstractmethod
|
|
11
|
+
def get_id(self):
|
|
12
|
+
raise NotImplementedError("Subclasses must implement the 'get_id' method.")
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MiniLogger:
|
|
6
|
+
# TODO Can we so one generic function call by all
|
|
7
|
+
# TODO Shall we user the Python logging package?
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def start(message: str = "", object: dict = None):
|
|
11
|
+
"""
|
|
12
|
+
Print a log message with the current time.
|
|
13
|
+
|
|
14
|
+
Parameters:
|
|
15
|
+
message (str): The message to be printed.
|
|
16
|
+
"""
|
|
17
|
+
if object is None:
|
|
18
|
+
print(f"{datetime.now()} - START - {message}")
|
|
19
|
+
else:
|
|
20
|
+
print(f"{datetime.now()} - START - {message} - {str(object)}")
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def end(message: str = "", object: dict = None):
|
|
24
|
+
"""
|
|
25
|
+
Print a log message with the current time.
|
|
26
|
+
|
|
27
|
+
Parameters:
|
|
28
|
+
message (str): The message to be printed.
|
|
29
|
+
"""
|
|
30
|
+
if object is None:
|
|
31
|
+
print(f"{datetime.now()} - END - {message}")
|
|
32
|
+
else:
|
|
33
|
+
print(f"{datetime.now()} - END - {message} - {str(object)}")
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def info(message: str = "", object: dict = None):
|
|
37
|
+
"""
|
|
38
|
+
Print a log message with the current time.
|
|
39
|
+
|
|
40
|
+
Parameters:
|
|
41
|
+
message (str): The message to be printed.
|
|
42
|
+
object (dict): The object to be printed.
|
|
43
|
+
"""
|
|
44
|
+
if object is None:
|
|
45
|
+
print(f"{datetime.now()} - INFO - {message}")
|
|
46
|
+
else:
|
|
47
|
+
print(f"{datetime.now()} - INFO {message} - {str(object)}")
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def warning(message: str = "", object: dict = None):
|
|
51
|
+
"""
|
|
52
|
+
Print a log message with the current time.
|
|
53
|
+
|
|
54
|
+
Parameters:
|
|
55
|
+
message (str): The message to be printed.
|
|
56
|
+
object (dict): The object to be printed.
|
|
57
|
+
"""
|
|
58
|
+
if object is None:
|
|
59
|
+
print(f"{datetime.now()} - WARNING - {message}")
|
|
60
|
+
else:
|
|
61
|
+
print(f"{datetime.now()} - WARNING {message} - {str(object)}")
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def error(message: str = "", object: dict = None):
|
|
65
|
+
"""
|
|
66
|
+
Print a log error message with the current time.
|
|
67
|
+
|
|
68
|
+
Parameters:
|
|
69
|
+
message (str): The message to be printed.
|
|
70
|
+
object (dict): The object to be printed.
|
|
71
|
+
"""
|
|
72
|
+
if object is None:
|
|
73
|
+
print(f"{datetime.now()} - ERROR - {message}", file=sys.stderr)
|
|
74
|
+
else:
|
|
75
|
+
print(
|
|
76
|
+
f"{datetime.now()} - ERROR - {message} - {str(object)}", file=sys.stderr)
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def exception(message: str = "", object: dict = None):
|
|
80
|
+
"""
|
|
81
|
+
Print a log error message with the current time.
|
|
82
|
+
|
|
83
|
+
Parameters:
|
|
84
|
+
message (str): The message to be printed.
|
|
85
|
+
object (dict): The object to be printed.
|
|
86
|
+
"""
|
|
87
|
+
if object is None:
|
|
88
|
+
print(f"{datetime.now()} - EXCEPTION - {message}", file=sys.stderr)
|
|
89
|
+
else:
|
|
90
|
+
print(
|
|
91
|
+
f"{datetime.now()} - EXCEPTION- {message} - {str(object)}", file=sys.stderr)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
|
|
4
|
+
from logger_local.Logger import Logger # TODO Shouldn't we use mini logger?
|
|
5
|
+
|
|
6
|
+
from .constants import OBJECT_TO_INSERT_CODE
|
|
7
|
+
|
|
8
|
+
logger = Logger.create_logger(object=OBJECT_TO_INSERT_CODE)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class OurObject(ABC):
|
|
12
|
+
def __init__(self, **kwargs):
|
|
13
|
+
INIT_METHOD_NAME = '__init__'
|
|
14
|
+
logger.start(INIT_METHOD_NAME, object={'kwargs': kwargs})
|
|
15
|
+
self.kwargs = kwargs
|
|
16
|
+
logger.end(INIT_METHOD_NAME, object={'kwargs': kwargs})
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
def get_name(self):
|
|
20
|
+
"""Returns the name of the object"""
|
|
21
|
+
raise NotImplementedError(
|
|
22
|
+
"Subclasses must implement the 'get_name' method.")
|
|
23
|
+
|
|
24
|
+
def get(self, attr_name: str):
|
|
25
|
+
"""Returns the value of the attribute with the given name"""
|
|
26
|
+
GET_METHOD_NAME = 'get'
|
|
27
|
+
logger.start(GET_METHOD_NAME, object={'attr_name': attr_name})
|
|
28
|
+
arguments = getattr(self, 'kwargs', None)
|
|
29
|
+
value = arguments.get(attr_name, None)
|
|
30
|
+
logger.end(GET_METHOD_NAME, object={'attr_name': attr_name})
|
|
31
|
+
return value
|
|
32
|
+
|
|
33
|
+
def get_all_arguments(self):
|
|
34
|
+
"""Returns all the arguments passed to the constructor as a dictionary"""
|
|
35
|
+
return getattr(self, 'kwargs', None)
|
|
36
|
+
|
|
37
|
+
def to_json(self) -> str:
|
|
38
|
+
"""Returns a json string representation of this object"""
|
|
39
|
+
return json.dumps(self.__dict__)
|
|
40
|
+
|
|
41
|
+
def from_json(self, json_string: str) -> 'OurObject':
|
|
42
|
+
"""Returns an instance of the class from a json string"""
|
|
43
|
+
FROM_JSON_METHOD_NAME = 'from_json'
|
|
44
|
+
logger.start(FROM_JSON_METHOD_NAME,
|
|
45
|
+
object={'json_string': json_string})
|
|
46
|
+
self.__dict__ = json.loads(json_string)
|
|
47
|
+
logger.end(FROM_JSON_METHOD_NAME,
|
|
48
|
+
object={'json_dict': self.__dict__})
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
def __eq__(self, other) -> bool:
|
|
52
|
+
"""Checks if two objects are equal"""
|
|
53
|
+
if not isinstance(other, OurObject):
|
|
54
|
+
return False
|
|
55
|
+
return self.__dict__ == other.__dict__
|
|
56
|
+
|
|
57
|
+
def __ne__(self, other) -> bool:
|
|
58
|
+
"""Checks if two objects are not equal"""
|
|
59
|
+
return not self.__eq__(other)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .valid_json_version import valid_json_versions
|
|
2
|
+
class UnifiedJson:
|
|
3
|
+
def __init__(self, data: dict, version: str):
|
|
4
|
+
if version not in valid_json_versions:
|
|
5
|
+
raise Exception(
|
|
6
|
+
f"version {version} is not in valid_json_versions {valid_json_versions}"
|
|
7
|
+
)
|
|
8
|
+
self.version = version
|
|
9
|
+
self.data = data
|
|
10
|
+
|
|
11
|
+
def get_unified_json(self):
|
|
12
|
+
return {"version": self.version, "data": self.data}
|
|
13
|
+
|
|
14
|
+
def __str__(self):
|
|
15
|
+
return self.get_unified_json()
|
|
16
|
+
|
|
17
|
+
def __repr__(self):
|
|
18
|
+
return self.__str__()
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
from datetime import date, datetime, time, timedelta
|
|
4
|
+
from urllib.parse import urlparse
|
|
5
|
+
|
|
6
|
+
from dotenv import load_dotenv
|
|
7
|
+
from logger_local.Logger import Logger
|
|
8
|
+
|
|
9
|
+
from .constants import (BRAND_NAME, ENVIRONMENT_NAME, # noqa: E402
|
|
10
|
+
OBJECT_TO_INSERT_CODE)
|
|
11
|
+
from .validate_environment import validate_brand_name # noqa: E402
|
|
12
|
+
from .validate_environment import validate_environment_name
|
|
13
|
+
|
|
14
|
+
load_dotenv() # for our_get_env
|
|
15
|
+
logger = Logger.create_logger(object=OBJECT_TO_INSERT_CODE)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def timedelta_to_time_format(time_delta: timedelta) -> str:
|
|
19
|
+
"""
|
|
20
|
+
Convert a timedelta to a time format in HH:MM:SS.
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
time_delta (datetime.timedelta): The timedelta to be converted.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
str: A string in HH:MM:SS format representing the time duration.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
Usage of timedelta_to_time_format:
|
|
30
|
+
|
|
31
|
+
>>> from datetime import timedelta
|
|
32
|
+
>>> duration = timedelta(hours=2, minutes=30, seconds=45)
|
|
33
|
+
>>> formatted_time = timedelta_to_time_format(duration)
|
|
34
|
+
>>> print(formatted_time)
|
|
35
|
+
'02:30:45'
|
|
36
|
+
"""
|
|
37
|
+
TIMEDELTA_TO_TIME_FORMAT_METHOD_NAME = "timedelta_to_time_format"
|
|
38
|
+
logger.start(TIMEDELTA_TO_TIME_FORMAT_METHOD_NAME, object={'time_delta': time_delta})
|
|
39
|
+
|
|
40
|
+
# Calculate the total seconds and convert to HH:MM:SS format
|
|
41
|
+
total_seconds = int(time_delta.total_seconds())
|
|
42
|
+
hours = total_seconds // 3600
|
|
43
|
+
minutes = (total_seconds % 3600) // 60
|
|
44
|
+
seconds = total_seconds % 60
|
|
45
|
+
|
|
46
|
+
# Format as "HH:MM:SS"
|
|
47
|
+
formatted_time = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
|
48
|
+
|
|
49
|
+
logger.end(TIMEDELTA_TO_TIME_FORMAT_METHOD_NAME,
|
|
50
|
+
object={'formatted_time': formatted_time})
|
|
51
|
+
return formatted_time
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def is_valid_time_range(time_range: tuple) -> bool:
|
|
55
|
+
"""
|
|
56
|
+
Validate that the time range is in the format 'HH:MM:SS'.
|
|
57
|
+
"""
|
|
58
|
+
IS_VALID_TIME_RANGE_METHOD_NAME = "is_valid_time_range"
|
|
59
|
+
logger.start(IS_VALID_TIME_RANGE_METHOD_NAME, object={
|
|
60
|
+
"time_range": time_range.__str__()})
|
|
61
|
+
if len(time_range) != 2:
|
|
62
|
+
logger.end(IS_VALID_TIME_RANGE_METHOD_NAME, object={
|
|
63
|
+
"is_valid_time_range_result": False, "reason": "len(time_range) != 2"})
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
for time_obj in time_range:
|
|
67
|
+
if not isinstance(time_obj, time):
|
|
68
|
+
logger.end(IS_VALID_TIME_RANGE_METHOD_NAME, object={
|
|
69
|
+
"is_valid_time_range_result": False, "reason": "time_range contains non-time objects"})
|
|
70
|
+
return False
|
|
71
|
+
time_str = time_obj.strftime('%H:%M:%S')
|
|
72
|
+
if time_obj.strftime('%H:%M:%S') != time_str:
|
|
73
|
+
logger.end(IS_VALID_TIME_RANGE_METHOD_NAME, object={
|
|
74
|
+
"is_valid_time_range_result": False, "reason": "time_range contains invalid time format"})
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
logger.end(IS_VALID_TIME_RANGE_METHOD_NAME, object={
|
|
78
|
+
"is_valid_time_range_result": True})
|
|
79
|
+
return True
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def validate_url(url):
|
|
83
|
+
if url is not None or url != "":
|
|
84
|
+
parsed_url = urlparse(url)
|
|
85
|
+
return parsed_url.scheme and parsed_url.netloc
|
|
86
|
+
return True
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def is_valid_date_range(date_range: tuple) -> bool:
|
|
90
|
+
"""
|
|
91
|
+
Validate that the date range is in the format 'YYYY-MM-DD'.
|
|
92
|
+
"""
|
|
93
|
+
IS_VALID_DATE_RANGE_METHOD_NAME = "is_valid_date_range"
|
|
94
|
+
logger.start(IS_VALID_DATE_RANGE_METHOD_NAME, object={
|
|
95
|
+
"date_range": date_range.__str__()})
|
|
96
|
+
if len(date_range) != 2:
|
|
97
|
+
logger.end(IS_VALID_DATE_RANGE_METHOD_NAME, object={
|
|
98
|
+
"is_valid_date_range_result": False, "reason": "len(date_range) != 2"})
|
|
99
|
+
return False
|
|
100
|
+
|
|
101
|
+
for date_obj in date_range:
|
|
102
|
+
if not isinstance(date_obj, date):
|
|
103
|
+
logger.end(IS_VALID_DATE_RANGE_METHOD_NAME, object={
|
|
104
|
+
"is_valid_date_range_result": False, "reason": "date_range contains non-date objects"})
|
|
105
|
+
return False
|
|
106
|
+
logger.end(IS_VALID_DATE_RANGE_METHOD_NAME, object={
|
|
107
|
+
"is_valid_date_range_result": True})
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def is_valid_datetime_range(datetime_range: tuple) -> bool:
|
|
112
|
+
"""
|
|
113
|
+
Validate that the datetime range is in the format 'YYYY-MM-DD HH:MM:SS'.
|
|
114
|
+
"""
|
|
115
|
+
IS_VALID_DATETIME_RANGE_METHOD_NAME = "is_valid_datetime_range"
|
|
116
|
+
logger.start(IS_VALID_DATETIME_RANGE_METHOD_NAME, object={
|
|
117
|
+
"datetime_range": datetime_range.__str__()})
|
|
118
|
+
if len(datetime_range) != 2:
|
|
119
|
+
logger.end(IS_VALID_DATETIME_RANGE_METHOD_NAME, object={
|
|
120
|
+
"is_valid_datetime_range_result": False, "reason": "len(datetime_range) != 2"})
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
for datetime_obj in datetime_range:
|
|
124
|
+
if not isinstance(datetime_obj, datetime):
|
|
125
|
+
logger.end(IS_VALID_DATETIME_RANGE_METHOD_NAME, object={
|
|
126
|
+
"is_valid_datetime_range_result": False, "reason": "datetime_range contains non-datetime objects"})
|
|
127
|
+
return False
|
|
128
|
+
logger.end(IS_VALID_DATETIME_RANGE_METHOD_NAME, object={
|
|
129
|
+
"is_valid_datetime_range_result": True})
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def is_list_of_dicts(obj):
|
|
134
|
+
"""
|
|
135
|
+
Check if an object is a list of dictionaries.
|
|
136
|
+
|
|
137
|
+
Parameters:
|
|
138
|
+
obj (object): The object to be checked.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
bool: True if the object is a list of dictionaries, False otherwise.
|
|
142
|
+
|
|
143
|
+
Example:
|
|
144
|
+
Usage of is_list_of_dicts:
|
|
145
|
+
|
|
146
|
+
>>> data = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]
|
|
147
|
+
>>> result = is_list_of_dicts(data)
|
|
148
|
+
>>> print(result)
|
|
149
|
+
True
|
|
150
|
+
|
|
151
|
+
>>> data = [1, 2, 3]
|
|
152
|
+
>>> result = is_list_of_dicts(data)
|
|
153
|
+
>>> print(result)
|
|
154
|
+
False
|
|
155
|
+
"""
|
|
156
|
+
IS_LIST_OF_DICTS_FUNCTION_NAME = "is_list_of_dicts"
|
|
157
|
+
logger.start(IS_LIST_OF_DICTS_FUNCTION_NAME, object={"obj": obj})
|
|
158
|
+
try:
|
|
159
|
+
if not isinstance(obj, list):
|
|
160
|
+
is_list_of_dicts_result = False
|
|
161
|
+
logger.end(IS_LIST_OF_DICTS_FUNCTION_NAME, object={
|
|
162
|
+
"is_list_of_dicts_result": is_list_of_dicts_result})
|
|
163
|
+
return is_list_of_dicts_result
|
|
164
|
+
for item in obj:
|
|
165
|
+
if not isinstance(item, dict):
|
|
166
|
+
is_list_of_dicts_result = False
|
|
167
|
+
logger.end(IS_LIST_OF_DICTS_FUNCTION_NAME, object={
|
|
168
|
+
"is_list_of_dicts_result": is_list_of_dicts_result})
|
|
169
|
+
return is_list_of_dicts_result
|
|
170
|
+
is_list_of_dicts_result = True
|
|
171
|
+
logger.end(IS_LIST_OF_DICTS_FUNCTION_NAME, object={
|
|
172
|
+
"is_list_of_dicts_result": is_list_of_dicts_result})
|
|
173
|
+
return is_list_of_dicts_result
|
|
174
|
+
except Exception as e:
|
|
175
|
+
logger.end(IS_LIST_OF_DICTS_FUNCTION_NAME, exception=e)
|
|
176
|
+
raise e
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def is_time_in_time_range(check_time: time, time_range: tuple) -> bool:
|
|
180
|
+
"""
|
|
181
|
+
Check if the given time is within the specified time range.
|
|
182
|
+
|
|
183
|
+
Parameters:
|
|
184
|
+
check_time (str): The time to check in 'HH:MM:SS' format.
|
|
185
|
+
time_range (tuple): A tuple containing start and end times in 'HH:MM:SS' format.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
bool: True if the check_time is within the time range, False otherwise.
|
|
189
|
+
"""
|
|
190
|
+
IS_TIME_IN_TIME_RANGE_METHOD_NAME = "is_time_in_time_range"
|
|
191
|
+
logger.start(IS_TIME_IN_TIME_RANGE_METHOD_NAME, object={
|
|
192
|
+
"check_time": check_time.__str__(), "time_range": time_range.__str__()})
|
|
193
|
+
if not is_valid_time_range(time_range) or not isinstance(check_time, time):
|
|
194
|
+
logger.end(IS_TIME_IN_TIME_RANGE_METHOD_NAME, object={
|
|
195
|
+
"is_time_in_time_range_result": False})
|
|
196
|
+
return False
|
|
197
|
+
start_time, end_time = time_range
|
|
198
|
+
logger.end(IS_TIME_IN_TIME_RANGE_METHOD_NAME, object={
|
|
199
|
+
"is_time_in_time_range_result": start_time <= check_time <= end_time})
|
|
200
|
+
return start_time <= check_time <= end_time
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def is_date_in_date_range(check_date: date, date_range: tuple) -> bool:
|
|
204
|
+
"""
|
|
205
|
+
Check if the given date is within the specified date range.
|
|
206
|
+
|
|
207
|
+
Parameters:
|
|
208
|
+
check_date (str): The date to check in 'YYYY-MM-DD' format.
|
|
209
|
+
date_range (tuple): A tuple containing start and end dates in 'YYYY-MM-DD' format.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
bool: True if the check_date is within the date range, False otherwise.
|
|
213
|
+
"""
|
|
214
|
+
IS_DATE_IN_DATE_RANGE_METHOD_NAME = "is_date_in_date_range"
|
|
215
|
+
logger.start(IS_DATE_IN_DATE_RANGE_METHOD_NAME, object={
|
|
216
|
+
"check_date": check_date.__str__(), "date_range": date_range.__str__()})
|
|
217
|
+
if not is_valid_date_range(date_range) or not isinstance(check_date, date):
|
|
218
|
+
logger.end(IS_DATE_IN_DATE_RANGE_METHOD_NAME, object={
|
|
219
|
+
"is_date_in_date_range_result": False})
|
|
220
|
+
return False
|
|
221
|
+
|
|
222
|
+
start_date, end_date = date_range
|
|
223
|
+
logger.end(IS_DATE_IN_DATE_RANGE_METHOD_NAME, object={
|
|
224
|
+
"is_date_in_date_range_result": start_date <= check_date <= end_date})
|
|
225
|
+
return start_date <= check_date <= end_date
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def is_datetime_in_datetime_range(check_datetime: datetime, datetime_range: tuple) -> bool:
|
|
229
|
+
"""
|
|
230
|
+
Check if the given datetime is within the specified datetime range.
|
|
231
|
+
|
|
232
|
+
Parameters:
|
|
233
|
+
check_datetime (str): The datetime to check in 'YYYY-MM-DD HH:MM:SS' format.
|
|
234
|
+
datetime_range (tuple): A tuple containing start and end datetimes in 'YYYY-MM-DD HH:MM:SS' format.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
bool: True if the check_datetime is within the datetime range, False otherwise.
|
|
238
|
+
"""
|
|
239
|
+
IS_DATETIME_IN_DATETIME_RANGE_METHOD_NAME = "is_datetime_in_datetime_range"
|
|
240
|
+
logger.start(IS_DATETIME_IN_DATETIME_RANGE_METHOD_NAME)
|
|
241
|
+
if not is_valid_datetime_range(datetime_range) or not isinstance(check_datetime, datetime):
|
|
242
|
+
logger.end(IS_DATETIME_IN_DATETIME_RANGE_METHOD_NAME, object={
|
|
243
|
+
"is_valid_datetime_range": False})
|
|
244
|
+
return False
|
|
245
|
+
|
|
246
|
+
start_datetime, end_datetime = datetime_range
|
|
247
|
+
is_datetime_in_datetime_range_result = start_datetime <= check_datetime <= end_datetime
|
|
248
|
+
logger.end(IS_DATETIME_IN_DATETIME_RANGE_METHOD_NAME, object={
|
|
249
|
+
"is_datetime_in_datetime_range_result": is_datetime_in_datetime_range_result})
|
|
250
|
+
return is_datetime_in_datetime_range_result
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
# TODO Align those methods with typescript-sdk https://github.com/circles-zone/typescript-sdk-remote-typescript-package/blob/dev/typescript-sdk/src/utils/index.ts # noqa501
|
|
254
|
+
# TODO Take those three functions to a separate file http_response.py
|
|
255
|
+
# TODO Shall we create also createInternalServerErrorHttpResponse(), createOkHttpResponse() like we have in TypeScript?
|
|
256
|
+
|
|
257
|
+
# Former name was create_http_headers()
|
|
258
|
+
def create_authorization_http_headers(user_jwt: str):
|
|
259
|
+
http_headers = {
|
|
260
|
+
'Content-Type': 'application/json',
|
|
261
|
+
'Authorization': f'Bearer {user_jwt}',
|
|
262
|
+
}
|
|
263
|
+
return http_headers
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def create_return_http_headers():
|
|
267
|
+
return {
|
|
268
|
+
"Content-Type": "application/json",
|
|
269
|
+
"Access-Control-Allow-Origin": "*",
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
# https://google.github.io/styleguide/jsoncstyleguide.xml?showone=Property_Name_Format#Property_Name_Format
|
|
274
|
+
def create_http_body(body):
|
|
275
|
+
# TODO console.warning() if the body is not a valid camelCase JSON
|
|
276
|
+
# https://stackoverflow.com/questions/17156078/converting-identifier-naming-between-camelcase-and-underscores-during-json-seria
|
|
277
|
+
return json.dumps(body)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def get_brand_name():
|
|
281
|
+
validate_brand_name()
|
|
282
|
+
return BRAND_NAME
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def get_environment_name():
|
|
286
|
+
validate_environment_name()
|
|
287
|
+
return ENVIRONMENT_NAME
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def our_get_env(key: str) -> str:
|
|
291
|
+
return os.getenv(key)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def get_sql_hostname():
|
|
295
|
+
return our_get_env("RDS_HOSTNAME")
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def get_sql_username():
|
|
299
|
+
return our_get_env("RDS_USERNAME")
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def get_sql_password():
|
|
303
|
+
return our_get_env("RDS_PASSWORD")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from .constants import BRAND_NAME, ENVIRONMENT_NAME, LOGZIO_TOKEN
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# TODO Align with https://github.com/circles-zone/typescript-sdk-remote-typescript-package/edit/dev/typescript-sdk/src/utils/index.ts validateTenantEnvironmentVariables() # noqa501
|
|
5
|
+
def validate_enviroment_variables():
|
|
6
|
+
validate_brand_name()
|
|
7
|
+
validate_environment_name()
|
|
8
|
+
# if(os.getenv("PRODUCT_USER_IDENTIFIER") is None):
|
|
9
|
+
# raise Exception("logger-local-python-package LoggerLocal.py please add Environment Variable called "
|
|
10
|
+
# "PRODUCT_USER_IDENTIFIER (instead of PRODUCT_USERNAME)")
|
|
11
|
+
# removed by Idan because it dont has to be in every project
|
|
12
|
+
# if(os.getenv("PRODUCT_PASSWORD") is None):
|
|
13
|
+
# raise Exception("logger-local-python-package LoggerLocal.py please add Environment Variable called PRODUCT_PASSWORD")
|
|
14
|
+
validate_logzio_token()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def validate_environment_name():
|
|
18
|
+
if ENVIRONMENT_NAME is None:
|
|
19
|
+
raise Exception("logger-local-python-package LoggerLocal.py please add Environment Variable called "
|
|
20
|
+
"ENVIRONMENT_NAME=local or play1 (instead of ENVIRONMENT)")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def validate_brand_name():
|
|
24
|
+
if BRAND_NAME is None:
|
|
25
|
+
raise Exception(
|
|
26
|
+
"logger-local-python-package LoggerLocal.py please add Environment Variable called BRAND_NAME=Circlez")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_logzio_token():
|
|
30
|
+
if LOGZIO_TOKEN is None:
|
|
31
|
+
raise Exception("logger-local-python-package LoggerLocal.py please add Environment Variable called"
|
|
32
|
+
" LOGZIO_TOKEN=cXNHuVkkffkilnkKzZlWExECRlSKqopE")
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
setup.py
|
|
4
|
+
python_sdk_remote.egg-info/PKG-INFO
|
|
5
|
+
python_sdk_remote.egg-info/SOURCES.txt
|
|
6
|
+
python_sdk_remote.egg-info/dependency_links.txt
|
|
7
|
+
python_sdk_remote.egg-info/top_level.txt
|
|
8
|
+
python_sdk_remote/src/__init__.py
|
|
9
|
+
python_sdk_remote/src/constants.py
|
|
10
|
+
python_sdk_remote/src/item.py
|
|
11
|
+
python_sdk_remote/src/mini_logger.py
|
|
12
|
+
python_sdk_remote/src/our_object.py
|
|
13
|
+
python_sdk_remote/src/unified_json.py
|
|
14
|
+
python_sdk_remote/src/utilities.py
|
|
15
|
+
python_sdk_remote/src/valid_json_versions.py
|
|
16
|
+
python_sdk_remote/src/validate_environment.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
python_sdk_remote
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import setuptools
|
|
2
2
|
|
|
3
|
+
PACKAGE_NAME = "python-sdk-remote"
|
|
4
|
+
package_dir = PACKAGE_NAME.replace("-", "_")
|
|
5
|
+
|
|
3
6
|
# used by python -m build
|
|
4
7
|
# python -m build needs pyproject.toml or setup.py
|
|
5
8
|
setuptools.setup(
|
|
6
|
-
name=
|
|
7
|
-
version='0.0.
|
|
9
|
+
name=PACKAGE_NAME,
|
|
10
|
+
version='0.0.63', # https://pypi.org/project/python-sdk-remote/
|
|
8
11
|
author="Circles",
|
|
9
12
|
author_email="info@circles.life",
|
|
10
13
|
description="PyPI Package for Circles Python SDK Local Python",
|
|
11
14
|
long_description="This is a package for sharing common functions used in different repositories",
|
|
12
15
|
long_description_content_type="text/markdown",
|
|
13
16
|
url="https://github.com/circles-zone/python-sdk-remote-python-package",
|
|
14
|
-
packages=
|
|
17
|
+
packages=[package_dir],
|
|
18
|
+
package_dir={package_dir: f'{package_dir}/src'},
|
|
19
|
+
package_data={package_dir: ['*.py']},
|
|
15
20
|
classifiers=[
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"License :: Other/Proprietary License",
|
|
23
|
+
"Operating System :: OS Independent",
|
|
19
24
|
],
|
|
20
25
|
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|