omnata-plugin-runtime 0.8.3a204__py3-none-any.whl → 0.9.0a208__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- omnata_plugin_runtime/api.py +36 -0
- omnata_plugin_runtime/omnata_plugin.py +28 -17
- omnata_plugin_runtime/plugin_entrypoints.py +30 -52
- {omnata_plugin_runtime-0.8.3a204.dist-info → omnata_plugin_runtime-0.9.0a208.dist-info}/METADATA +1 -1
- omnata_plugin_runtime-0.9.0a208.dist-info/RECORD +12 -0
- omnata_plugin_runtime-0.8.3a204.dist-info/RECORD +0 -12
- {omnata_plugin_runtime-0.8.3a204.dist-info → omnata_plugin_runtime-0.9.0a208.dist-info}/LICENSE +0 -0
- {omnata_plugin_runtime-0.8.3a204.dist-info → omnata_plugin_runtime-0.9.0a208.dist-info}/WHEEL +0 -0
omnata_plugin_runtime/api.py
CHANGED
@@ -120,6 +120,7 @@ class OutboundSyncRequestPayload(BaseModel):
|
|
120
120
|
results_table_name: str # used to stage results back to the engine, resides in the main Omnata app database
|
121
121
|
logging_level: str
|
122
122
|
connection_method: str
|
123
|
+
target_type: Optional[str] = None
|
123
124
|
connectivity_option: ConnectivityOption = Field(default=ConnectivityOption.DIRECT)
|
124
125
|
connection_parameters: Dict[str, StoredConfigurationValue]
|
125
126
|
oauth_secret_name: Optional[str] = None
|
@@ -166,6 +167,41 @@ SyncRequestPayload = Annotated[
|
|
166
167
|
Field(discriminator="sync_direction"),
|
167
168
|
]
|
168
169
|
|
170
|
+
class OutboundConfigurationFormPayload(BaseModel):
|
171
|
+
"""
|
172
|
+
Encapsulates the payload that is sent to the plugin when it is invoked to provide a configuration form for an outbound sync.
|
173
|
+
"""
|
174
|
+
connectivity_option: ConnectivityOption = Field(default=ConnectivityOption.DIRECT)
|
175
|
+
connection_method: str
|
176
|
+
connection_parameters: Dict[str, StoredConfigurationValue]
|
177
|
+
oauth_secret_name: Optional[str] = None
|
178
|
+
other_secrets_name: Optional[str] = None
|
179
|
+
sync_direction: Literal["outbound"] = "outbound"
|
180
|
+
target_type: Optional[str] = None
|
181
|
+
sync_strategy: OutboundSyncStrategy
|
182
|
+
function_name: str = "outbound_configuration_form"
|
183
|
+
sync_parameters: Dict[str, StoredConfigurationValue]
|
184
|
+
current_form_parameters: Optional[Dict[str, StoredConfigurationValue]]
|
185
|
+
|
186
|
+
class InboundConfigurationFormPayload(BaseModel):
|
187
|
+
"""
|
188
|
+
Encapsulates the payload that is sent to the plugin when it is invoked to provide a configuration form for an inbound sync.
|
189
|
+
"""
|
190
|
+
connectivity_option: ConnectivityOption = Field(default=ConnectivityOption.DIRECT)
|
191
|
+
connection_method: str
|
192
|
+
connection_parameters: Dict[str, StoredConfigurationValue]
|
193
|
+
oauth_secret_name: Optional[str] = None
|
194
|
+
other_secrets_name: Optional[str] = None
|
195
|
+
sync_direction: Literal["inbound"] = "inbound"
|
196
|
+
function_name: str = "inbound_configuration_form"
|
197
|
+
sync_parameters: Dict[str, StoredConfigurationValue]
|
198
|
+
current_form_parameters: Optional[Dict[str, StoredConfigurationValue]]
|
199
|
+
|
200
|
+
ConfigurationFormPayload = Annotated[
|
201
|
+
Union[OutboundConfigurationFormPayload, InboundConfigurationFormPayload],
|
202
|
+
Field(discriminator="sync_direction"),
|
203
|
+
]
|
204
|
+
|
169
205
|
|
170
206
|
def handle_proc_result(query_result: List[Row]) -> Dict:
|
171
207
|
"""
|
@@ -112,16 +112,14 @@ class PluginManifest(SubscriptableBaseModel):
|
|
112
112
|
docs_url: str
|
113
113
|
supports_inbound: bool
|
114
114
|
supported_outbound_strategies: List[OutboundSyncStrategy] = Field(
|
115
|
-
|
116
|
-
deprecated=True,
|
117
|
-
title="A list of sync strategies that the plugin can support. This has been replaced by OutboundTargetTypes."
|
115
|
+
title="A list of sync strategies that the plugin can support. If outbound_target_types are specified, theses strategies are allocated there. Otherwise, they apply globally"
|
118
116
|
)
|
119
117
|
supported_connectivity_options: List[ConnectivityOption] = Field(
|
120
118
|
default_factory=lambda: [ConnectivityOption.DIRECT]
|
121
119
|
)
|
122
|
-
outbound_target_types: List[OutboundTargetType] = Field(
|
123
|
-
|
124
|
-
title="
|
120
|
+
outbound_target_types: Optional[List[OutboundTargetType]] = Field(
|
121
|
+
default=None,
|
122
|
+
title="An optional list of target types that the plugin can support."
|
125
123
|
)
|
126
124
|
|
127
125
|
class OutboundTargetType(BaseModel):
|
@@ -136,20 +134,33 @@ class OutboundTargetType(BaseModel):
|
|
136
134
|
The target type cannot be changed after the sync is created.
|
137
135
|
"""
|
138
136
|
label: str
|
139
|
-
supported_strategies: List[
|
140
|
-
|
141
|
-
|
142
|
-
|
137
|
+
supported_strategies: List[str] = Field(
|
138
|
+
title="The names of the sync strategies supported by this target. Each one must match the name of a sync strategy declared in supported_outbound_strategies."
|
139
|
+
)
|
140
|
+
target_parameter: Optional[OutboundTargetParameter] = Field(
|
141
|
+
default=None,
|
142
|
+
title="""The sync configuration parameter that designates the target object, if applicable. For example, 'object_name' or 'channel_name'.
|
143
|
+
This will be used for two purposes:
|
144
|
+
1. To show a more readable indication of what this sync is doing in the UI, e.g. Standard object: Account
|
145
|
+
2. Designates this field as serving as a br toggle for testing in production.""")
|
146
|
+
|
147
|
+
class OutboundTargetParameter(BaseModel):
|
143
148
|
"""
|
144
149
|
Accomodates testing outbound syncs in production by nominating a form field who's value stays in the branch.
|
145
|
-
|
146
|
-
|
147
|
-
The field_name must match a field which will be returned by the outbound_configuration_form for this target type.
|
148
|
-
The reason this is set separately here instead of as a flag on the FormField, is so that the sync engine can know
|
149
|
-
whether or not location toggling is supported for a target type without calling the plugin.
|
150
|
+
The reason this information is set statically here instead of as a flag on the FormField, is so that the sync engine
|
151
|
+
can have this information readily available without calling the plugin.
|
150
152
|
"""
|
151
|
-
field_name: str = Field(
|
152
|
-
|
153
|
+
field_name: str = Field(title="""The name of the form field that toggles the location, e.g. 'channel','customer_list'.
|
154
|
+
This must match a field which will be returned by the outbound_configuration_form for this target type.""")
|
155
|
+
is_branching_toggle: bool = Field(title="""Whether or not this field is a target toggle for branching.
|
156
|
+
If true, the value of this field will be used to determine the location of the sync in production.
|
157
|
+
For example, a messaging plugin could have a "channel" field to route messages to an alternate location.
|
158
|
+
Or, a marketing platform could have an alternate customer list name which is connected to test campaigns that don't actually send.
|
159
|
+
|
160
|
+
This should only be used in situations where all other sync parameters and field mappings can remain consistent between branches.""")
|
161
|
+
label: str = Field(title="""Used in the UI when describing the location., e.g. 'Channel','Customer List'.
|
162
|
+
It should completely describe the behaviour when used in a sentence like this:
|
163
|
+
'Changes will be tested against a different <label> when running in a branch.'""")
|
153
164
|
|
154
165
|
class SnowflakeFunctionParameter(BaseModel):
|
155
166
|
"""
|
@@ -6,13 +6,13 @@ import os
|
|
6
6
|
import sys
|
7
7
|
import time
|
8
8
|
import threading
|
9
|
-
from typing import Dict, List, Optional
|
9
|
+
from typing import Dict, List, Optional, cast
|
10
10
|
|
11
11
|
from pydantic import BaseModel,TypeAdapter # pylint: disable=no-name-in-module
|
12
12
|
from pydantic_core import to_jsonable_python
|
13
13
|
from snowflake.snowpark import Session
|
14
14
|
|
15
|
-
from .api import PluginMessageStreamProgressUpdate, SyncRequestPayload,
|
15
|
+
from .api import PluginMessageStreamProgressUpdate, SyncRequestPayload, ConfigurationFormPayload
|
16
16
|
from .configuration import (
|
17
17
|
ConnectionConfigurationParameters,
|
18
18
|
InboundSyncConfigurationParameters,
|
@@ -83,7 +83,7 @@ class PluginEntrypoint:
|
|
83
83
|
|
84
84
|
|
85
85
|
def sync(self, sync_request: Dict):
|
86
|
-
request = TypeAdapter(SyncRequestPayload).validate_python(sync_request)
|
86
|
+
request:SyncRequestPayload = TypeAdapter(SyncRequestPayload).validate_python(sync_request)
|
87
87
|
logger.add_extra('omnata.operation', 'sync')
|
88
88
|
logger.add_extra('omnata.sync.id', request.sync_id)
|
89
89
|
logger.add_extra('omnata.sync.direction', request.sync_direction)
|
@@ -160,6 +160,7 @@ class PluginEntrypoint:
|
|
160
160
|
connection_secrets=connection_secrets,
|
161
161
|
sync_parameters=request.sync_parameters,
|
162
162
|
current_form_parameters={},
|
163
|
+
target_type=request.target_type,
|
163
164
|
sync_strategy=request.sync_strategy,
|
164
165
|
field_mappings=request.field_mappings,
|
165
166
|
)
|
@@ -289,67 +290,43 @@ class PluginEntrypoint:
|
|
289
290
|
logger.info("Finished applying records")
|
290
291
|
return return_dict
|
291
292
|
|
292
|
-
def configuration_form(
|
293
|
-
|
294
|
-
connectivity_option:str,
|
295
|
-
connection_method: str,
|
296
|
-
connection_parameters: Dict,
|
297
|
-
oauth_secret_name: Optional[str],
|
298
|
-
other_secrets_name: Optional[str],
|
299
|
-
sync_direction: str,
|
300
|
-
sync_strategy: Dict,
|
301
|
-
function_name: str,
|
302
|
-
sync_parameters: Dict,
|
303
|
-
current_form_parameters: Optional[Dict],
|
304
|
-
):
|
305
|
-
if function_name is None:
|
306
|
-
function_name = f"{sync_direction}_configuration_form"
|
293
|
+
def configuration_form(self, configuration_form_request: Dict):
|
294
|
+
request:ConfigurationFormPayload = TypeAdapter(ConfigurationFormPayload).validate_python(configuration_form_request)
|
307
295
|
logger.add_extra('omnata.operation', 'configuration_form')
|
308
|
-
logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
|
309
|
-
logger.add_extra('omnata.connection.connection_method', connection_method)
|
310
|
-
logger.add_extra('omnata.configuration_form.function_name', function_name)
|
311
|
-
logger.add_extra('omnata.sync.direction', sync_direction)
|
296
|
+
logger.add_extra('omnata.connection.connectivity_option', request.connectivity_option)
|
297
|
+
logger.add_extra('omnata.connection.connection_method', request.connection_method)
|
298
|
+
logger.add_extra('omnata.configuration_form.function_name', request.function_name)
|
299
|
+
logger.add_extra('omnata.sync.direction', request.sync_direction)
|
312
300
|
|
313
301
|
logger.info("Entered configuration_form method")
|
314
|
-
|
315
|
-
|
316
|
-
other_secrets_name = normalise_nulls(other_secrets_name)
|
317
|
-
connection_secrets = get_secrets(oauth_secret_name, other_secrets_name)
|
318
|
-
connectivity_option = TypeAdapter(ConnectivityOption).validate_python(connectivity_option)
|
319
|
-
connection_parameters = TypeAdapter(
|
320
|
-
Dict[str, StoredConfigurationValue]).validate_python(connection_parameters)
|
321
|
-
sync_parameters = TypeAdapter(
|
322
|
-
Dict[str, StoredConfigurationValue]).validate_python(sync_parameters)
|
323
|
-
form_parameters = None
|
324
|
-
if current_form_parameters is not None:
|
325
|
-
form_parameters = TypeAdapter(Dict[str, StoredConfigurationValue]).validate_python(current_form_parameters)
|
326
|
-
if sync_direction == "outbound":
|
327
|
-
sync_strat = OutboundSyncStrategy.model_validate(sync_strategy) if sync_strategy is not None else None
|
302
|
+
connection_secrets = get_secrets(request.oauth_secret_name, request.other_secrets_name)
|
303
|
+
if request.sync_direction == "outbound":
|
328
304
|
parameters = OutboundSyncConfigurationParameters(
|
329
|
-
connection_parameters=connection_parameters,
|
305
|
+
connection_parameters=request.connection_parameters,
|
330
306
|
connection_secrets=connection_secrets,
|
331
|
-
sync_strategy=
|
332
|
-
sync_parameters=sync_parameters,
|
333
|
-
connection_method=connection_method,
|
334
|
-
connectivity_option=connectivity_option,
|
335
|
-
current_form_parameters=
|
307
|
+
sync_strategy=request.sync_strategy,
|
308
|
+
sync_parameters=request.sync_parameters,
|
309
|
+
connection_method=request.connection_method,
|
310
|
+
connectivity_option=request.connectivity_option,
|
311
|
+
current_form_parameters=request.current_form_parameters,
|
312
|
+
target_type=request.target_type
|
336
313
|
)
|
337
|
-
elif sync_direction == "inbound":
|
314
|
+
elif request.sync_direction == "inbound":
|
338
315
|
parameters = InboundSyncConfigurationParameters(
|
339
|
-
connection_parameters=connection_parameters,
|
316
|
+
connection_parameters=request.connection_parameters,
|
340
317
|
connection_secrets=connection_secrets,
|
341
|
-
sync_parameters=sync_parameters,
|
342
|
-
connection_method=connection_method,
|
343
|
-
connectivity_option=connectivity_option,
|
344
|
-
current_form_parameters=
|
318
|
+
sync_parameters=request.sync_parameters,
|
319
|
+
connection_method=request.connection_method,
|
320
|
+
connectivity_option=request.connectivity_option,
|
321
|
+
current_form_parameters=request.current_form_parameters,
|
345
322
|
)
|
346
323
|
else:
|
347
|
-
raise ValueError(f"Unknown direction {sync_direction}")
|
348
|
-
if oauth_secret_name is not None:
|
349
|
-
parameters.access_token_secret_name = oauth_secret_name
|
324
|
+
raise ValueError(f"Unknown direction {request.sync_direction}")
|
325
|
+
if request.oauth_secret_name is not None:
|
326
|
+
parameters.access_token_secret_name = request.oauth_secret_name
|
350
327
|
the_function = getattr(
|
351
328
|
self._plugin_instance,
|
352
|
-
function_name
|
329
|
+
request.function_name
|
353
330
|
)
|
354
331
|
with tracer.start_as_current_span("invoke_plugin"):
|
355
332
|
script_result = the_function(parameters)
|
@@ -357,6 +334,7 @@ class PluginEntrypoint:
|
|
357
334
|
script_result = script_result.model_dump()
|
358
335
|
elif isinstance(script_result, List):
|
359
336
|
if len(script_result) > 0 and isinstance(script_result[0], BaseModel):
|
337
|
+
script_result = cast(List[BaseModel], script_result)
|
360
338
|
script_result = [r.model_dump() for r in script_result]
|
361
339
|
return script_result
|
362
340
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
omnata_plugin_runtime/__init__.py,sha256=MS9d1whnfT_B3-ThqZ7l63QeC_8OEKTuaYV5wTwRpBA,1576
|
2
|
+
omnata_plugin_runtime/api.py,sha256=baGraSMiD4Yvi3ZWrEv_TKh8Ktd1U8riBdOpe9j0Puw,8202
|
3
|
+
omnata_plugin_runtime/configuration.py,sha256=g6A9sFHBBaCgZPjhTM4iYcyEoZDPjB1F24QMboLteyY,38505
|
4
|
+
omnata_plugin_runtime/forms.py,sha256=ueodN2GIMS5N9fqebpY4uNGJnjEb9HcuaVQVfWH-cGg,19838
|
5
|
+
omnata_plugin_runtime/logging.py,sha256=WBuZt8lF9E5oFWM4KYQbE8dDJ_HctJ1pN3BHwU6rcd0,4461
|
6
|
+
omnata_plugin_runtime/omnata_plugin.py,sha256=WrttykPnWR5ckL2SHUbcU6yYpNb-_HTL3LzFB6cBMd8,134356
|
7
|
+
omnata_plugin_runtime/plugin_entrypoints.py,sha256=iqGl8_nEEnPGKg3Aem4YLSQ6d5xS3ju5gq8MJbx6sCA,31968
|
8
|
+
omnata_plugin_runtime/rate_limiting.py,sha256=eOWVRYWiqPlVeYzmB1exVXfXbrcpmYb7vtTi9B-4zkQ,25868
|
9
|
+
omnata_plugin_runtime-0.9.0a208.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
|
10
|
+
omnata_plugin_runtime-0.9.0a208.dist-info/METADATA,sha256=BdfXNGwXPGhbypwhYNed8BmD6jJanyddwHg1Y8011SU,2158
|
11
|
+
omnata_plugin_runtime-0.9.0a208.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
12
|
+
omnata_plugin_runtime-0.9.0a208.dist-info/RECORD,,
|
@@ -1,12 +0,0 @@
|
|
1
|
-
omnata_plugin_runtime/__init__.py,sha256=MS9d1whnfT_B3-ThqZ7l63QeC_8OEKTuaYV5wTwRpBA,1576
|
2
|
-
omnata_plugin_runtime/api.py,sha256=tVi4KLL0v5N3yz3Ie0kSyFemryu572gCbtSRfWN6wBU,6523
|
3
|
-
omnata_plugin_runtime/configuration.py,sha256=g6A9sFHBBaCgZPjhTM4iYcyEoZDPjB1F24QMboLteyY,38505
|
4
|
-
omnata_plugin_runtime/forms.py,sha256=ueodN2GIMS5N9fqebpY4uNGJnjEb9HcuaVQVfWH-cGg,19838
|
5
|
-
omnata_plugin_runtime/logging.py,sha256=WBuZt8lF9E5oFWM4KYQbE8dDJ_HctJ1pN3BHwU6rcd0,4461
|
6
|
-
omnata_plugin_runtime/omnata_plugin.py,sha256=fs8yrPUhZ3rsU4rcl_MuXNltEufb1nKrcXV-I88MTCA,133443
|
7
|
-
omnata_plugin_runtime/plugin_entrypoints.py,sha256=sB_h6OBEMk7lTLIjdNrNo9Sthk8UE9PnK2AUcQJPe9I,32728
|
8
|
-
omnata_plugin_runtime/rate_limiting.py,sha256=eOWVRYWiqPlVeYzmB1exVXfXbrcpmYb7vtTi9B-4zkQ,25868
|
9
|
-
omnata_plugin_runtime-0.8.3a204.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
|
10
|
-
omnata_plugin_runtime-0.8.3a204.dist-info/METADATA,sha256=nJD4bsjd9pTQaG1pnZc-Wt_1JVEpYH9pX05uNgY06UI,2158
|
11
|
-
omnata_plugin_runtime-0.8.3a204.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
12
|
-
omnata_plugin_runtime-0.8.3a204.dist-info/RECORD,,
|
{omnata_plugin_runtime-0.8.3a204.dist-info → omnata_plugin_runtime-0.9.0a208.dist-info}/LICENSE
RENAMED
File without changes
|
{omnata_plugin_runtime-0.8.3a204.dist-info → omnata_plugin_runtime-0.9.0a208.dist-info}/WHEEL
RENAMED
File without changes
|