omnata-plugin-runtime 0.6.9a179__tar.gz → 0.7.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/PKG-INFO +2 -2
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/pyproject.toml +2 -2
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/api.py +3 -0
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/configuration.py +12 -5
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/forms.py +1 -0
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/omnata_plugin.py +7 -2
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/plugin_entrypoints.py +25 -26
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/LICENSE +0 -0
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/README.md +0 -0
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/__init__.py +0 -0
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/logging.py +0 -0
- {omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/rate_limiting.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: omnata-plugin-runtime
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.7.0
|
4
4
|
Summary: Classes and common runtime components for building and running Omnata Plugins
|
5
5
|
Author: James Weakley
|
6
6
|
Author-email: james.weakley@omnata.com
|
@@ -33,7 +33,7 @@ Requires-Dist: pyyaml (<=6.0.1)
|
|
33
33
|
Requires-Dist: requests (>=2,<=2.32.3)
|
34
34
|
Requires-Dist: setuptools (<=72.1.0)
|
35
35
|
Requires-Dist: snowflake-connector-python (>=3,<=3.12.0)
|
36
|
-
Requires-Dist: snowflake-snowpark-python (==1.
|
36
|
+
Requires-Dist: snowflake-snowpark-python (==1.23.0)
|
37
37
|
Requires-Dist: tenacity (>=8,<=8.2.3)
|
38
38
|
Requires-Dist: tomlkit (<=0.11.1)
|
39
39
|
Requires-Dist: urllib3 (<=2.2.2)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "omnata-plugin-runtime"
|
3
|
-
version = "0.
|
3
|
+
version = "0.7.0"
|
4
4
|
description = "Classes and common runtime components for building and running Omnata Plugins"
|
5
5
|
authors = ["James Weakley <james.weakley@omnata.com>"]
|
6
6
|
readme = "README.md"
|
@@ -8,7 +8,7 @@ packages = [{include = "omnata_plugin_runtime", from = "src"}]
|
|
8
8
|
|
9
9
|
[tool.poetry.dependencies]
|
10
10
|
python = ">=3.8, <3.11"
|
11
|
-
snowflake-snowpark-python = "1.
|
11
|
+
snowflake-snowpark-python = "1.23.0" # latest version available on Snowflake Anaconda
|
12
12
|
snowflake-connector-python = "^3, <=3.12.0" # latest version available on Snowflake Anaconda
|
13
13
|
cryptography = "<=43.0.0"
|
14
14
|
annotated-types = "<=0.6.0"
|
{omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/api.py
RENAMED
@@ -22,6 +22,7 @@ from .configuration import (
|
|
22
22
|
OutboundSyncStrategy,
|
23
23
|
StoredConfigurationValue,
|
24
24
|
StoredMappingValue,
|
25
|
+
ConnectivityOption
|
25
26
|
)
|
26
27
|
from .rate_limiting import ApiLimits, RateLimitState
|
27
28
|
|
@@ -119,6 +120,7 @@ class OutboundSyncRequestPayload(BaseModel):
|
|
119
120
|
results_table_name: str # used to stage results back to the engine, resides in the main Omnata app database
|
120
121
|
logging_level: str
|
121
122
|
connection_method: str
|
123
|
+
connectivity_option: ConnectivityOption = Field(default=ConnectivityOption.DIRECT)
|
122
124
|
connection_parameters: Dict[str, StoredConfigurationValue]
|
123
125
|
oauth_secret_name: Optional[str] = None
|
124
126
|
other_secrets_name: Optional[str] = None
|
@@ -146,6 +148,7 @@ class InboundSyncRequestPayload(BaseModel):
|
|
146
148
|
results_table_name: str # used to stage results back to the engine, resides in the main Omnata app database
|
147
149
|
logging_level: str
|
148
150
|
connection_method: str
|
151
|
+
connectivity_option: ConnectivityOption = Field(default=ConnectivityOption.DIRECT)
|
149
152
|
connection_parameters: Dict[str, StoredConfigurationValue]
|
150
153
|
oauth_secret_name: Optional[str] = None
|
151
154
|
other_secrets_name: Optional[str] = None
|
@@ -37,6 +37,14 @@ class InboundStorageBehaviour(str, Enum):
|
|
37
37
|
MERGE = "merge"
|
38
38
|
REPLACE = "replace" # now deprecated, full refreshes now use merge
|
39
39
|
|
40
|
+
class ConnectivityOption(str, Enum):
|
41
|
+
"""
|
42
|
+
Describes the connectivity options available to a plugin.
|
43
|
+
These result in slightly different network rules and connection onboarding.
|
44
|
+
"""
|
45
|
+
DIRECT = "direct"
|
46
|
+
NGROK = "ngrok"
|
47
|
+
PRIVATELINK = "privatelink"
|
40
48
|
|
41
49
|
class InboundSyncStrategy(str, Enum):
|
42
50
|
FULL_REFRESH = "Full Refresh"
|
@@ -543,6 +551,7 @@ class ConnectionConfigurationParameters(SubscriptableBaseModel):
|
|
543
551
|
"""
|
544
552
|
|
545
553
|
connection_method: str
|
554
|
+
connectivity_option: ConnectivityOption = Field(default=ConnectivityOption.DIRECT)
|
546
555
|
connection_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
547
556
|
connection_secrets: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
548
557
|
ngrok_tunnel_settings: Optional[NgrokTunnelSettings] = Field(default=None)
|
@@ -552,11 +561,9 @@ class ConnectionConfigurationParameters(SubscriptableBaseModel):
|
|
552
561
|
default=None
|
553
562
|
)
|
554
563
|
|
555
|
-
@
|
556
|
-
|
557
|
-
|
558
|
-
A validator which picks out the ngrok tunnel configuration from the secrets and provides it as a typed object.
|
559
|
-
"""
|
564
|
+
@field_validator('ngrok_tunnel_settings',mode='before')
|
565
|
+
@classmethod
|
566
|
+
def validate_ngrok_tunnel_settings(cls, values: Optional[dict[str, Any]]) -> Optional[NgrokTunnelSettings]:
|
560
567
|
if "connection_secrets" in values:
|
561
568
|
connection_secrets:Dict[str, StoredConfigurationValue] = values["connection_secrets"]
|
562
569
|
if "ngrok_client_certificate" in connection_secrets and \
|
{omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/forms.py
RENAMED
@@ -489,5 +489,6 @@ class ConnectionMethod(SubscriptableBaseModel):
|
|
489
489
|
name: str
|
490
490
|
fields: List[FormFieldBase]
|
491
491
|
oauth_template: Optional[SecurityIntegrationTemplate] = Field(default=None)
|
492
|
+
# This is now deprecated, instead signal ngrok support via the plugin manifest
|
492
493
|
ngrok_tunnel_configuration: Optional[NGrokMTLSTunnel] = Field(default=None)
|
493
494
|
description: str = Field(default="")
|
@@ -72,7 +72,8 @@ from .configuration import (
|
|
72
72
|
StreamConfiguration,
|
73
73
|
SubscriptableBaseModel,
|
74
74
|
SyncConfigurationParameters,
|
75
|
-
get_secrets
|
75
|
+
get_secrets,
|
76
|
+
ConnectivityOption
|
76
77
|
)
|
77
78
|
from .forms import (
|
78
79
|
ConnectionMethod,
|
@@ -101,6 +102,7 @@ class PluginManifest(SubscriptableBaseModel):
|
|
101
102
|
:param str docs_url: The URL where plugin documentation can be found, e.g. "https://docs.omnata.com"
|
102
103
|
:param bool supports_inbound: A flag to indicate whether or not the plugin supports inbound sync. Support for inbound sync behaviours (full/incremental) is defined per inbound stream.
|
103
104
|
:param List[OutboundSyncStrategy] supported_outbound_strategies: A list of sync strategies that the plugin can support, e.g. create,upsert.
|
105
|
+
:param List[ConnectivityOption] supported_connectivity_options: A list of connectivity options that the plugin can support, e.g. direct,ngrok,privatelink
|
104
106
|
"""
|
105
107
|
|
106
108
|
plugin_id: str
|
@@ -110,6 +112,9 @@ class PluginManifest(SubscriptableBaseModel):
|
|
110
112
|
docs_url: str
|
111
113
|
supports_inbound: bool
|
112
114
|
supported_outbound_strategies: List[OutboundSyncStrategy]
|
115
|
+
supported_connectivity_options: List[ConnectivityOption] = Field(
|
116
|
+
default_factory=lambda: [ConnectivityOption.DIRECT]
|
117
|
+
)
|
113
118
|
|
114
119
|
|
115
120
|
class SnowflakeFunctionParameter(BaseModel):
|
@@ -1643,7 +1648,7 @@ class OmnataPlugin(ABC):
|
|
1643
1648
|
)
|
1644
1649
|
|
1645
1650
|
@abstractmethod
|
1646
|
-
def connection_form(self) -> List[ConnectionMethod]:
|
1651
|
+
def connection_form(self,connectivity_option:ConnectivityOption) -> List[ConnectionMethod]:
|
1647
1652
|
"""
|
1648
1653
|
Returns a form definition so that user input can be collected, in order to connect to an app
|
1649
1654
|
|
@@ -20,7 +20,8 @@ from .configuration import (
|
|
20
20
|
OutboundSyncStrategy,
|
21
21
|
StoredConfigurationValue,
|
22
22
|
StoredMappingValue,
|
23
|
-
get_secrets
|
23
|
+
get_secrets,
|
24
|
+
ConnectivityOption
|
24
25
|
)
|
25
26
|
from .forms import ConnectionMethod, FormInputField, FormOption
|
26
27
|
from .logging import OmnataPluginLogHandler
|
@@ -98,6 +99,7 @@ class PluginEntrypoint:
|
|
98
99
|
# construct some connection parameters for the purpose of getting the api limits
|
99
100
|
connection_parameters = ConnectionConfigurationParameters(
|
100
101
|
connection_method=request.connection_method,
|
102
|
+
connectivity_option=request.connectivity_option,
|
101
103
|
connection_parameters=request.connection_parameters,
|
102
104
|
connection_secrets=connection_secrets
|
103
105
|
)
|
@@ -138,6 +140,7 @@ class PluginEntrypoint:
|
|
138
140
|
if request.sync_direction == "outbound":
|
139
141
|
parameters = OutboundSyncConfigurationParameters(
|
140
142
|
connection_method=request.connection_method,
|
143
|
+
connectivity_option=request.connectivity_option,
|
141
144
|
connection_parameters=request.connection_parameters,
|
142
145
|
connection_secrets=connection_secrets,
|
143
146
|
sync_parameters=request.sync_parameters,
|
@@ -193,6 +196,7 @@ class PluginEntrypoint:
|
|
193
196
|
logger.info("Running inbound sync")
|
194
197
|
parameters = InboundSyncConfigurationParameters(
|
195
198
|
connection_method=request.connection_method,
|
199
|
+
connectivity_option=request.connectivity_option,
|
196
200
|
connection_parameters=request.connection_parameters,
|
197
201
|
connection_secrets=connection_secrets,
|
198
202
|
sync_parameters=request.sync_parameters,
|
@@ -268,6 +272,7 @@ class PluginEntrypoint:
|
|
268
272
|
|
269
273
|
def configuration_form(
|
270
274
|
self,
|
275
|
+
connectivity_option:str,
|
271
276
|
connection_method: str,
|
272
277
|
connection_parameters: Dict,
|
273
278
|
oauth_secret_name: Optional[str],
|
@@ -283,6 +288,7 @@ class PluginEntrypoint:
|
|
283
288
|
oauth_secret_name = normalise_nulls(oauth_secret_name)
|
284
289
|
other_secrets_name = normalise_nulls(other_secrets_name)
|
285
290
|
connection_secrets = get_secrets(oauth_secret_name, other_secrets_name)
|
291
|
+
connectivity_option = TypeAdapter(ConnectivityOption).validate_python(connectivity_option)
|
286
292
|
connection_parameters = TypeAdapter(
|
287
293
|
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters)
|
288
294
|
sync_parameters = TypeAdapter(
|
@@ -298,6 +304,7 @@ class PluginEntrypoint:
|
|
298
304
|
sync_strategy=sync_strat,
|
299
305
|
sync_parameters=sync_parameters,
|
300
306
|
connection_method=connection_method,
|
307
|
+
connectivity_option=connectivity_option,
|
301
308
|
current_form_parameters=form_parameters,
|
302
309
|
)
|
303
310
|
elif sync_direction == "inbound":
|
@@ -306,6 +313,7 @@ class PluginEntrypoint:
|
|
306
313
|
connection_secrets=connection_secrets,
|
307
314
|
sync_parameters=sync_parameters,
|
308
315
|
connection_method=connection_method,
|
316
|
+
connectivity_option=connectivity_option,
|
309
317
|
current_form_parameters=form_parameters,
|
310
318
|
)
|
311
319
|
else:
|
@@ -326,6 +334,7 @@ class PluginEntrypoint:
|
|
326
334
|
|
327
335
|
def inbound_list_streams(
|
328
336
|
self,
|
337
|
+
connectivity_option:str,
|
329
338
|
connection_method: str,
|
330
339
|
connection_parameters: Dict,
|
331
340
|
oauth_secret_name: Optional[str],
|
@@ -337,6 +346,7 @@ class PluginEntrypoint:
|
|
337
346
|
oauth_secret_name = normalise_nulls(oauth_secret_name)
|
338
347
|
other_secrets_name = normalise_nulls(other_secrets_name)
|
339
348
|
connection_secrets = get_secrets(oauth_secret_name, other_secrets_name)
|
349
|
+
connectivity_option = TypeAdapter(ConnectivityOption).validate_python(connectivity_option)
|
340
350
|
connection_parameters = TypeAdapter(
|
341
351
|
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters)
|
342
352
|
sync_parameters = TypeAdapter(
|
@@ -345,6 +355,7 @@ class PluginEntrypoint:
|
|
345
355
|
connection_parameters=connection_parameters,
|
346
356
|
connection_secrets=connection_secrets,
|
347
357
|
sync_parameters=sync_parameters,
|
358
|
+
connectivity_option=connectivity_option,
|
348
359
|
connection_method=connection_method,
|
349
360
|
current_form_parameters=None,
|
350
361
|
currently_selected_streams=selected_streams
|
@@ -381,9 +392,13 @@ class PluginEntrypoint:
|
|
381
392
|
results.append(script_result.model_dump())
|
382
393
|
return results
|
383
394
|
|
384
|
-
def connection_form(self):
|
395
|
+
def connection_form(self,connectivity_option: str):
|
396
|
+
connectivity_option = TypeAdapter(ConnectivityOption).validate_python(connectivity_option)
|
385
397
|
logger.info("Entered connection_form method")
|
386
|
-
|
398
|
+
if self._plugin_instance.connection_form.__code__.co_argcount==1:
|
399
|
+
form: List[ConnectionMethod] = self._plugin_instance.connection_form()
|
400
|
+
else:
|
401
|
+
form: List[ConnectionMethod] = self._plugin_instance.connection_form(connectivity_option)
|
387
402
|
return [f.model_dump() for f in form]
|
388
403
|
|
389
404
|
def create_billing_events(self, session, event_request: Dict):
|
@@ -431,30 +446,9 @@ class PluginEntrypoint:
|
|
431
446
|
other_secrets_name: Optional[str],
|
432
447
|
function_name: str,
|
433
448
|
) -> List[FormInputField]:
|
434
|
-
|
435
|
-
oauth_secret_name = normalise_nulls(oauth_secret_name)
|
436
|
-
other_secrets_name = normalise_nulls(other_secrets_name)
|
437
|
-
connection_secrets = get_secrets(oauth_secret_name, other_secrets_name)
|
438
|
-
connection_parameters = TypeAdapter(
|
439
|
-
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters)
|
440
|
-
parameters = ConnectionConfigurationParameters(
|
441
|
-
connection_method=connection_method,
|
442
|
-
connection_parameters=connection_parameters,
|
443
|
-
connection_secrets=connection_secrets
|
444
|
-
)
|
445
|
-
the_function = getattr(
|
446
|
-
self._plugin_instance,
|
447
|
-
function_name,
|
448
|
-
)
|
449
|
-
script_result = the_function(parameters)
|
450
|
-
if isinstance(script_result, List):
|
451
|
-
if len(script_result) > 0 and isinstance(script_result[0], BaseModel):
|
452
|
-
script_result = [r.model_dump() for r in script_result]
|
453
|
-
else:
|
454
|
-
raise ValueError(f"Expected a List from function {function_name}, got {type(script_result)}")
|
455
|
-
return script_result
|
449
|
+
raise ValueError(f"ngrok_post_tunnel_fields is deprecated")
|
456
450
|
|
457
|
-
def network_addresses(self, method: str, connection_parameters: Dict) -> List[str]:
|
451
|
+
def network_addresses(self, connectivity_option:str, method: str, connection_parameters: Dict) -> List[str]:
|
458
452
|
logger.info("Entered network_addresses method")
|
459
453
|
logger.info(f"Connection parameters: {connection_parameters}")
|
460
454
|
from omnata_plugin_runtime.omnata_plugin import (
|
@@ -463,6 +457,7 @@ class PluginEntrypoint:
|
|
463
457
|
|
464
458
|
return self._plugin_instance.network_addresses(
|
465
459
|
ConnectionConfigurationParameters(
|
460
|
+
connectivity_option=TypeAdapter(ConnectivityOption).validate_python(connectivity_option),
|
466
461
|
connection_method=method,
|
467
462
|
connection_parameters=TypeAdapter(
|
468
463
|
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters),
|
@@ -472,6 +467,7 @@ class PluginEntrypoint:
|
|
472
467
|
|
473
468
|
def connect(
|
474
469
|
self,
|
470
|
+
connectivity_option:str,
|
475
471
|
method:str,
|
476
472
|
connection_parameters: Dict,
|
477
473
|
network_rule_name: str,
|
@@ -486,6 +482,7 @@ class PluginEntrypoint:
|
|
486
482
|
ConnectionConfigurationParameters,
|
487
483
|
)
|
488
484
|
parameters = ConnectionConfigurationParameters(
|
485
|
+
connectivity_option=TypeAdapter(ConnectivityOption).validate_python(connectivity_option),
|
489
486
|
connection_method=method,
|
490
487
|
connection_parameters=TypeAdapter(
|
491
488
|
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters),
|
@@ -522,6 +519,7 @@ class PluginEntrypoint:
|
|
522
519
|
return connect_response.model_dump()
|
523
520
|
|
524
521
|
def api_limits(self,
|
522
|
+
connectivity_option:str,
|
525
523
|
method:str,
|
526
524
|
connection_parameters: Dict,
|
527
525
|
oauth_secret_name: Optional[str],
|
@@ -532,6 +530,7 @@ class PluginEntrypoint:
|
|
532
530
|
ConnectionConfigurationParameters,
|
533
531
|
)
|
534
532
|
connection_parameters = ConnectionConfigurationParameters(
|
533
|
+
connectivity_option=TypeAdapter(ConnectivityOption).validate_python(connectivity_option),
|
535
534
|
connection_method=method,
|
536
535
|
connection_parameters=TypeAdapter(
|
537
536
|
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters),
|
File without changes
|
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.6.9a179 → omnata_plugin_runtime-0.7.0}/src/omnata_plugin_runtime/logging.py
RENAMED
File without changes
|
File without changes
|