omnata-plugin-runtime 0.8.3a207__py3-none-any.whl → 0.9.0a209__py3-none-any.whl

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.
@@ -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
  """
@@ -220,6 +220,46 @@ STANDARD_OUTBOUND_SYNC_ACTIONS: Dict[str, OutboundSyncAction] = {
220
220
  "Recreate": RecreateSyncAction,
221
221
  }
222
222
 
223
+ class OutboundTargetParameter(BaseModel):
224
+ """
225
+ Accomodates testing outbound syncs in production by nominating a form field who's value stays in the branch.
226
+ The reason this information is set statically here instead of as a flag on the FormField, is so that the sync engine
227
+ can have this information readily available without calling the plugin.
228
+ """
229
+ field_name: str = Field(title="""The name of the form field that toggles the location, e.g. 'channel','customer_list'.
230
+ This must match a field which will be returned by the outbound_configuration_form for this target type.""")
231
+ is_branching_toggle: bool = Field(title="""Whether or not this field is a target toggle for branching.
232
+ If true, the value of this field will be used to determine the location of the sync in production.
233
+ For example, a messaging plugin could have a "channel" field to route messages to an alternate location.
234
+ Or, a marketing platform could have an alternate customer list name which is connected to test campaigns that don't actually send.
235
+
236
+ This should only be used in situations where all other sync parameters and field mappings can remain consistent between branches.""")
237
+ label: str = Field(title="""Used in the UI when describing the location., e.g. 'Channel','Customer List'.
238
+ It should completely describe the behaviour when used in a sentence like this:
239
+ 'Changes will be tested against a different <label> when running in a branch.'""")
240
+
241
+ class OutboundTargetType(BaseModel):
242
+ """
243
+ Some products have APIs that can be grouped together in ways that support different strategies and may or may not support toggling.
244
+ The label should answer the question: "What would you like to sync to?"
245
+ Examples:
246
+ - A CRM system may have "Standard objects", "Custom objects" or "Events"
247
+ - A messaging platform may have "Channels", "Users" or "Messages"
248
+ - A marketing platform may have "Customer lists", "Campaigns" or "Automations"
249
+ - An Ad platform may have "Campaigns", "Ad groups" or "Ads"
250
+ The target type cannot be changed after the sync is created.
251
+ """
252
+ label: str
253
+ supported_strategies: List[str] = Field(
254
+ 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."
255
+ )
256
+ target_parameter: Optional[OutboundTargetParameter] = Field(
257
+ default=None,
258
+ title="""The sync configuration parameter that designates the target object, if applicable. For example, 'object_name' or 'channel_name'.
259
+ This will be used for two purposes:
260
+ 1. To show a more readable indication of what this sync is doing in the UI, e.g. Standard object: Account
261
+ 2. Designates this field as serving as a br toggle for testing in production.""")
262
+
223
263
 
224
264
  class OutboundSyncStrategy(SubscriptableBaseModel, ABC):
225
265
  """OutboundSyncStrategy is a base class for all outbound sync strategies.
@@ -74,7 +74,8 @@ from .configuration import (
74
74
  SubscriptableBaseModel,
75
75
  SyncConfigurationParameters,
76
76
  get_secrets,
77
- ConnectivityOption
77
+ ConnectivityOption,
78
+ OutboundTargetType,
78
79
  )
79
80
  from .forms import (
80
81
  ConnectionMethod,
@@ -122,46 +123,6 @@ class PluginManifest(SubscriptableBaseModel):
122
123
  title="An optional list of target types that the plugin can support."
123
124
  )
124
125
 
125
- class OutboundTargetType(BaseModel):
126
- """
127
- Some products have APIs that can be grouped together in ways that support different strategies and may or may not support toggling.
128
- The label should answer the question: "What would you like to sync to?"
129
- Examples:
130
- - A CRM system may have "Standard objects", "Custom objects" or "Events"
131
- - A messaging platform may have "Channels", "Users" or "Messages"
132
- - A marketing platform may have "Customer lists", "Campaigns" or "Automations"
133
- - An Ad platform may have "Campaigns", "Ad groups" or "Ads"
134
- The target type cannot be changed after the sync is created.
135
- """
136
- label: str
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):
148
- """
149
- Accomodates testing outbound syncs in production by nominating a form field who's value stays in the branch.
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.
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.'""")
164
-
165
126
  class SnowflakeFunctionParameter(BaseModel):
166
127
  """
167
128
  Represents a parameter for a Snowflake UDF or UDTF
@@ -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, handle_proc_result
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
- self,
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
- sync_strategy = normalise_nulls(sync_strategy)
315
- oauth_secret_name = normalise_nulls(oauth_secret_name)
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=sync_strat,
332
- sync_parameters=sync_parameters,
333
- connection_method=connection_method,
334
- connectivity_option=connectivity_option,
335
- current_form_parameters=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=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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omnata-plugin-runtime
3
- Version: 0.8.3a207
3
+ Version: 0.9.0a209
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
@@ -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=hHWaK72q45cCQ2R7x9vX2tGifvUDabMrVXBZF4XX0TY,41286
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=3OPFFYhbxmffAcb5pJA09gV62SLX-1nu2j3mJMy3pis,131600
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.0a209.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
10
+ omnata_plugin_runtime-0.9.0a209.dist-info/METADATA,sha256=3j72wTua0fHhugze-4pSSFl58MR7ODerhgoz7ZWaB10,2158
11
+ omnata_plugin_runtime-0.9.0a209.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
12
+ omnata_plugin_runtime-0.9.0a209.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=WrttykPnWR5ckL2SHUbcU6yYpNb-_HTL3LzFB6cBMd8,134356
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.3a207.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
10
- omnata_plugin_runtime-0.8.3a207.dist-info/METADATA,sha256=aU_EJv5HVn3CXBKKuJaD3JFhBANrOT_o883o2fvIdpA,2158
11
- omnata_plugin_runtime-0.8.3a207.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
12
- omnata_plugin_runtime-0.8.3a207.dist-info/RECORD,,