switch-api 0.6.27__tar.gz → 0.6.28__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.
- {switch_api-0.6.27 → switch_api-0.6.28}/PKG-INFO +1 -1
- {switch_api-0.6.27 → switch_api-0.6.28}/setup.py +1 -1
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/__init__.py +1 -1
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_utils/_mqtt.py +20 -14
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/integration/_utils.py +1 -1
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/realtime/_mqtt.py +14 -14
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/realtime/_redis.py +45 -18
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/realtime/realtime.py +1 -1
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api.egg-info/PKG-INFO +1 -1
- {switch_api-0.6.27 → switch_api-0.6.28}/AUTHORS.rst +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/HISTORY.md +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/LICENCE +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/MANIFEST.in +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/README.md +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/pyproject.toml +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/setup.cfg +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_authentication.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_credentials_store/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_credentials_store/_credentials_store.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_msal/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_msal/_custom_application.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_compute/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_compute/_commands.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_compute/_compute.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_compute/_iotservice.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_compute/_models.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_compute/_utils.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_guide/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_guide/main.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_guide/processor.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_utils/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_utils/_constants.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_utils/_marketplace.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_utils/_platform.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_utils/_utils.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/analytics/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/analytics/analytics.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/cache/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/cache/cache.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/controls/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/controls/_constants.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/controls/_enums.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/controls/_mqtt.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/controls/controls.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/dataset/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/dataset/dataset.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/email/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/email/email_sender.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/error_handlers/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/error_handlers/error_handlers.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/extensions/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/extensions/extensions.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/extensions/field_meta.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/extensions/helpers.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/extensions/pipeline.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/initialize.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/integration/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/integration/helpers.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/integration/integration.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/pipeline/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/pipeline/automation.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/pipeline/definitions.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/pipeline/pipeline.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/platform_insights/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/platform_insights/platform_insights.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api/realtime/__init__.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api.egg-info/SOURCES.txt +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api.egg-info/dependency_links.txt +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api.egg-info/requires.txt +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/switch_api.egg-info/top_level.txt +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/tests/test_dataset.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/tests/test_error_handlers.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/tests/test_initialize.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/tests/test_integration.py +0 -0
- {switch_api-0.6.27 → switch_api-0.6.28}/tests/test_pipeline.py +0 -0
|
@@ -16,7 +16,7 @@ setup(
|
|
|
16
16
|
long_description_content_type='text/markdown',
|
|
17
17
|
license='MIT License',
|
|
18
18
|
name="switch_api",
|
|
19
|
-
version="0.6.
|
|
19
|
+
version="0.6.28",
|
|
20
20
|
packages=find_packages(include=["switch_api", "switch_api.*"]),
|
|
21
21
|
install_requires=['pandas==1.5.3', 'requests', 'azure-storage-blob', 'pandera[io]==0.7.1', 'azure-servicebus',
|
|
22
22
|
'msal>=1.11.0', 'paho-mqtt==1.6.1', 'uvicorn==0.22.0', 'fastapi==0.98.0', 'pyodbc==4.0.39', 'cachetools==5.5.0',
|
|
@@ -17,7 +17,7 @@ global _control_ws_port
|
|
|
17
17
|
global _control_ws_username
|
|
18
18
|
global _control_ws_password
|
|
19
19
|
global _control_ws_max_timeout
|
|
20
|
-
global
|
|
20
|
+
global _control_ws_ca_certs
|
|
21
21
|
|
|
22
22
|
_control_api_endpoint = ''
|
|
23
23
|
_control_ws_host = ''
|
|
@@ -25,7 +25,7 @@ _control_ws_port = WS_DEFAULT_PORT
|
|
|
25
25
|
_control_ws_username = ''
|
|
26
26
|
_control_ws_password = ''
|
|
27
27
|
_control_ws_max_timeout = WS_MQTT_DEFAULT_MAX_TIMEOUT
|
|
28
|
-
|
|
28
|
+
_control_ws_ca_certs = ''
|
|
29
29
|
|
|
30
30
|
def get_control_config():
|
|
31
31
|
"""
|
|
@@ -53,10 +53,10 @@ def get_control_config():
|
|
|
53
53
|
Username for MQTT authentication.
|
|
54
54
|
- password : str
|
|
55
55
|
Password for MQTT authentication.
|
|
56
|
-
- ssl_pwd : str
|
|
57
|
-
Password for SSL authentication.
|
|
58
56
|
- max_timeout : int
|
|
59
57
|
Maximum timeout (in seconds) for control operations.
|
|
58
|
+
- ca_certs : str (optional)
|
|
59
|
+
A string path to the Certificate Authority certificate files in Server
|
|
60
60
|
"""
|
|
61
61
|
return {
|
|
62
62
|
"api_endpoint": _control_api_endpoint,
|
|
@@ -64,13 +64,19 @@ def get_control_config():
|
|
|
64
64
|
"ws_port": _control_ws_port,
|
|
65
65
|
"username": _control_ws_username,
|
|
66
66
|
"password": _control_ws_password,
|
|
67
|
-
"ssl_pwd": _control_ws_ssl_pwd,
|
|
68
67
|
"max_timeout": _control_ws_max_timeout,
|
|
68
|
+
"ca_certs": _control_ws_ca_certs
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def set_mqtt_broker_config(api_endpoint: str,
|
|
73
|
-
|
|
72
|
+
def set_mqtt_broker_config(api_endpoint: str,
|
|
73
|
+
ws_host: str,
|
|
74
|
+
user_name: str,
|
|
75
|
+
password: str,
|
|
76
|
+
ws_port: int = WS_DEFAULT_PORT,
|
|
77
|
+
max_timeout: int = WS_MQTT_DEFAULT_MAX_TIMEOUT,
|
|
78
|
+
ca_certs: str = None,
|
|
79
|
+
bypass_username_password: bool = False):
|
|
74
80
|
"""Set Control Variables
|
|
75
81
|
|
|
76
82
|
Set Control Variables needed to enable control request to MQTT Broker when running locally.
|
|
@@ -98,17 +104,17 @@ def set_mqtt_broker_config(api_endpoint: str, ws_host: str, user_name: str, pass
|
|
|
98
104
|
global _control_ws_username
|
|
99
105
|
global _control_ws_password
|
|
100
106
|
global _control_ws_max_timeout
|
|
101
|
-
global
|
|
107
|
+
global _control_ws_ca_certs
|
|
102
108
|
|
|
103
109
|
# Check if endpoint is a valid URL
|
|
104
110
|
if not api_endpoint.startswith('https://'):
|
|
105
111
|
raise ValueError(
|
|
106
112
|
"Invalid IoT API Endpoint. The IoT host should start with 'https://'.")
|
|
107
113
|
|
|
108
|
-
#
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
# Check if host is a valid URL
|
|
115
|
+
if not ws_host.startswith('wss://'):
|
|
116
|
+
raise ValueError(
|
|
117
|
+
"Invalid IoT Websocket MQTT Host. The IoT host should start with 'wss://'.")
|
|
112
118
|
|
|
113
119
|
# Check if user_name and password are not empty
|
|
114
120
|
if not bypass_username_password:
|
|
@@ -127,5 +133,5 @@ def set_mqtt_broker_config(api_endpoint: str, ws_host: str, user_name: str, pass
|
|
|
127
133
|
_control_ws_port = ws_port
|
|
128
134
|
_control_ws_username = user_name
|
|
129
135
|
_control_ws_password = password
|
|
130
|
-
|
|
131
|
-
|
|
136
|
+
_control_ws_max_timeout = max_timeout
|
|
137
|
+
_control_ws_ca_certs = ca_certs
|
|
@@ -201,7 +201,7 @@ def _timezone_dst_offsets(api_inputs: ApiInputs, date_from: datetime.date, date_
|
|
|
201
201
|
else:
|
|
202
202
|
return timezone_offsets
|
|
203
203
|
except Exception as ex:
|
|
204
|
-
logger.error("API Call was not successful.", ex)
|
|
204
|
+
logger.error("API Call was not successful. %s", ex)
|
|
205
205
|
return pandas.DataFrame()
|
|
206
206
|
|
|
207
207
|
def _upsert_entities_affected_count(api_inputs: ApiInputs, entities_affected_count: int):
|
|
@@ -44,10 +44,10 @@ class SwitchRealtime:
|
|
|
44
44
|
port: int,
|
|
45
45
|
username: str,
|
|
46
46
|
password: str,
|
|
47
|
-
ssl_pwd: str,
|
|
48
47
|
client_id: str,
|
|
49
48
|
email: str,
|
|
50
|
-
project_id: str
|
|
49
|
+
project_id: str,
|
|
50
|
+
ca_certs: str = None
|
|
51
51
|
):
|
|
52
52
|
self.host = host
|
|
53
53
|
self.port = port
|
|
@@ -57,18 +57,18 @@ class SwitchRealtime:
|
|
|
57
57
|
|
|
58
58
|
self.client_id = client_id
|
|
59
59
|
self.client = mqtt.Client(client_id=client_id, transport='websockets', clean_session=True)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
|
|
61
|
+
if ca_certs:
|
|
62
|
+
# -- adhoc for cds engine server --
|
|
63
|
+
self.client.ws_set_options(path="/mqtt")
|
|
64
|
+
self.client.tls_set(
|
|
65
|
+
ca_certs=ca_certs,
|
|
66
|
+
cert_reqs=ssl.CERT_REQUIRED,
|
|
67
|
+
tls_version=ssl.PROTOCOL_TLS_CLIENT,
|
|
68
|
+
)
|
|
69
|
+
self.client.tls_insecure_set(False)
|
|
70
|
+
else:
|
|
71
|
+
self.client.tls_set()
|
|
72
72
|
|
|
73
73
|
if username and password:
|
|
74
74
|
self.client.username_pw_set(username, password)
|
|
@@ -102,6 +102,7 @@ def set_realtime_redis_config(
|
|
|
102
102
|
retry_max_delay: float = 0.05,
|
|
103
103
|
socket_timeout: int = None,
|
|
104
104
|
socket_connect_timeout: int = None,
|
|
105
|
+
ca_cert: str = None
|
|
105
106
|
):
|
|
106
107
|
"""
|
|
107
108
|
Configure Redis state storage for realtime MQTT dataset updates.
|
|
@@ -199,6 +200,8 @@ def set_realtime_redis_config(
|
|
|
199
200
|
socket_connect_timeout : int, optional
|
|
200
201
|
Redis socket connection timeout in seconds.
|
|
201
202
|
Defaults to None.
|
|
203
|
+
ca_cert: str, optional
|
|
204
|
+
A string path to the Certificate Authority certificate files in Server
|
|
202
205
|
|
|
203
206
|
Returns
|
|
204
207
|
-------
|
|
@@ -255,14 +258,23 @@ def set_realtime_redis_config(
|
|
|
255
258
|
"retry_max_delay": retry_max_delay,
|
|
256
259
|
"socket_timeout": socket_timeout,
|
|
257
260
|
"socket_connect_timeout": socket_connect_timeout,
|
|
261
|
+
"ca_cert": ca_cert
|
|
258
262
|
}
|
|
259
263
|
_redis_client = None
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
if ca_cert:
|
|
265
|
+
logger.info(
|
|
266
|
+
f"Configured Redis realtime state. host={host}, port={port}, "
|
|
267
|
+
f"ssl={ssl}, db={db}, key_prefix={key_prefix}, "
|
|
268
|
+
f"max_retries={max_retries}, timeout_max_retries={timeout_max_retries}, "
|
|
269
|
+
f"retry_min_delay={retry_min_delay}, retry_max_delay={retry_max_delay}, ca_cert={ca_cert}"
|
|
270
|
+
)
|
|
271
|
+
else:
|
|
272
|
+
logger.info(
|
|
273
|
+
f"Configured Redis realtime state. host={host}, port={port}, "
|
|
274
|
+
f"ssl={ssl}, db={db}, key_prefix={key_prefix}, "
|
|
275
|
+
f"max_retries={max_retries}, timeout_max_retries={timeout_max_retries}, "
|
|
276
|
+
f"retry_min_delay={retry_min_delay}, retry_max_delay={retry_max_delay}"
|
|
277
|
+
)
|
|
266
278
|
|
|
267
279
|
|
|
268
280
|
def get_realtime_redis_config():
|
|
@@ -296,18 +308,33 @@ def get_realtime_redis_client():
|
|
|
296
308
|
f"port={_redis_config['port']}, ssl={_redis_config['ssl']}, "
|
|
297
309
|
f"db={_redis_config['db']}"
|
|
298
310
|
)
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
|
|
312
|
+
if _redis_config["ca_cert"]:
|
|
313
|
+
_redis_client = redis.Redis(
|
|
314
|
+
host=_redis_config["host"],
|
|
315
|
+
port=_redis_config["port"],
|
|
316
|
+
username=_redis_config["username"],
|
|
317
|
+
password=_redis_config["password"],
|
|
318
|
+
ssl=_redis_config["ssl"],
|
|
319
|
+
db=_redis_config["db"],
|
|
320
|
+
decode_responses=True,
|
|
321
|
+
socket_timeout=_redis_config["socket_timeout"],
|
|
322
|
+
socket_connect_timeout=_redis_config["socket_connect_timeout"],
|
|
323
|
+
ssl_ca_certs=_redis_config["ca_cert"]
|
|
324
|
+
)
|
|
325
|
+
else:
|
|
326
|
+
_redis_client = redis.Redis(
|
|
327
|
+
host=_redis_config["host"],
|
|
328
|
+
port=_redis_config["port"],
|
|
329
|
+
username=_redis_config["username"],
|
|
330
|
+
password=_redis_config["password"],
|
|
331
|
+
ssl=_redis_config["ssl"],
|
|
332
|
+
db=_redis_config["db"],
|
|
333
|
+
decode_responses=True,
|
|
334
|
+
socket_timeout=_redis_config["socket_timeout"],
|
|
335
|
+
socket_connect_timeout=_redis_config["socket_connect_timeout"]
|
|
336
|
+
)
|
|
337
|
+
|
|
311
338
|
|
|
312
339
|
return _redis_client
|
|
313
340
|
|
|
@@ -300,10 +300,10 @@ def submit_realtime_updates(
|
|
|
300
300
|
port=mqtt_config["ws_port"],
|
|
301
301
|
username=mqtt_config["username"],
|
|
302
302
|
password=mqtt_config["password"],
|
|
303
|
-
ssl_pwd=mqtt_config["ssl_pwd"],
|
|
304
303
|
client_id=api_inputs.data_feed_id,
|
|
305
304
|
email=api_inputs.email_address,
|
|
306
305
|
project_id=api_inputs.api_project_id,
|
|
306
|
+
ca_certs=mqtt_config["ca_certs"]
|
|
307
307
|
)
|
|
308
308
|
|
|
309
309
|
# ----------------------------
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_credentials_store/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{switch_api-0.6.27 → switch_api-0.6.28}/switch_api/_authentication/_msal/_custom_application.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|