omnata-plugin-runtime 0.8.0a188__py3-none-any.whl → 0.8.0a190__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.
@@ -19,7 +19,9 @@ if tuple(sys.version_info[:2]) >= (3, 9):
19
19
  else:
20
20
  # Python 3.8 and below
21
21
  from typing_extensions import Annotated
22
+ from opentelemetry import trace
22
23
 
24
+ tracer = trace.get_tracer(__name__)
23
25
 
24
26
  class MapperType(str, Enum):
25
27
  FIELD_MAPPING_SELECTOR = "field_mapping_selector"
@@ -871,7 +873,7 @@ InboundSyncStreamsConfiguration.model_rebuild()
871
873
  StoredFieldMappings.model_rebuild()
872
874
  OutboundSyncConfigurationParameters.model_rebuild()
873
875
 
874
-
876
+ @tracer.start_as_current_span("get_secrets")
875
877
  def get_secrets(oauth_secret_name: Optional[str], other_secrets_name: Optional[str]
876
878
  ) -> Dict[str, StoredConfigurationValue]:
877
879
  connection_secrets = {}
@@ -39,7 +39,7 @@ from .rate_limiting import ApiLimits, RateLimitState
39
39
  from opentelemetry import trace
40
40
 
41
41
  IMPORT_DIRECTORY_NAME = "snowflake_import_directory"
42
-
42
+ tracer = trace.get_tracer(__name__)
43
43
 
44
44
  class PluginEntrypoint:
45
45
  """
@@ -51,8 +51,7 @@ class PluginEntrypoint:
51
51
  self, plugin_fqn: str, session: Session, module_name: str, class_name: str
52
52
  ):
53
53
  logger.info(f"Initialising plugin entrypoint for {plugin_fqn}")
54
- self.tracer = trace.get_tracer(__name__)
55
- with self.tracer.start_as_current_span("plugin_initialization") as span:
54
+ with tracer.start_as_current_span("plugin_initialization") as span:
56
55
  self._session = session
57
56
  import_dir = sys._xoptions[IMPORT_DIRECTORY_NAME]
58
57
  span.add_event("Adding plugin zip to path")
@@ -93,7 +92,7 @@ class PluginEntrypoint:
93
92
  logger.add_extra('omnata.sync_branch.id', request.sync_branch_id)
94
93
  logger.add_extra('omnata.sync_branch.name', request.sync_branch_name)
95
94
  logger.info("Entered sync method")
96
- with self.tracer.start_as_current_span("sync_initialization") as span:
95
+ with tracer.start_as_current_span("initialization") as span:
97
96
  span.add_event("Fetching secrets")
98
97
 
99
98
  request = TypeAdapter(SyncRequestPayload).validate_python(sync_request)
@@ -186,11 +185,11 @@ class PluginEntrypoint:
186
185
  )
187
186
  try:
188
187
  self._plugin_instance._configuration_parameters = parameters
189
- with self.tracer.start_as_current_span("sync_execution") as span:
188
+ with tracer.start_as_current_span("invoke_plugin") as span:
190
189
  with HttpRateLimiting(outbound_sync_request, parameters):
191
190
  self._plugin_instance.sync_outbound(parameters, outbound_sync_request)
192
191
  if self._plugin_instance.disable_background_workers is False:
193
- with self.tracer.start_as_current_span("results_finalization") as span:
192
+ with tracer.start_as_current_span("results_finalization") as span:
194
193
  outbound_sync_request.apply_results_queue()
195
194
  outbound_sync_request.apply_rate_limit_state()
196
195
  if outbound_sync_request.deadline_reached:
@@ -246,12 +245,12 @@ class PluginEntrypoint:
246
245
  inbound_sync_request.update_activity("Invoking plugin")
247
246
  logger.info(f"inbound sync request: {inbound_sync_request}")
248
247
  # plugin_instance._inbound_sync_request = outbound_sync_request
249
- with self.tracer.start_as_current_span("sync_execution") as span:
248
+ with tracer.start_as_current_span("invoke_plugin"):
250
249
  with HttpRateLimiting(inbound_sync_request, parameters):
251
250
  self._plugin_instance.sync_inbound(parameters, inbound_sync_request)
252
251
  logger.info("Finished invoking plugin")
253
252
  if self._plugin_instance.disable_background_workers is False:
254
- with self.tracer.start_as_current_span("results_finalization") as span:
253
+ with tracer.start_as_current_span("results_finalization") as span:
255
254
  inbound_sync_request.update_activity("Staging remaining records")
256
255
  logger.info("Calling apply_results_queue")
257
256
  inbound_sync_request.apply_results_queue()
@@ -304,6 +303,8 @@ class PluginEntrypoint:
304
303
  sync_parameters: Dict,
305
304
  current_form_parameters: Optional[Dict],
306
305
  ):
306
+ if function_name is None:
307
+ function_name = f"{sync_direction}_configuration_form"
307
308
  logger.add_extra('omnata.operation', 'configuration_form')
308
309
  logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
309
310
  logger.add_extra('omnata.connection.connection_method', connection_method)
@@ -349,9 +350,10 @@ class PluginEntrypoint:
349
350
  parameters.access_token_secret_name = oauth_secret_name
350
351
  the_function = getattr(
351
352
  self._plugin_instance,
352
- function_name or f"{sync_direction}_configuration_form",
353
+ function_name
353
354
  )
354
- script_result = the_function(parameters)
355
+ with tracer.start_as_current_span("invoke_plugin"):
356
+ script_result = the_function(parameters)
355
357
  if isinstance(script_result, BaseModel):
356
358
  script_result = script_result.model_dump()
357
359
  elif isinstance(script_result, List):
@@ -393,8 +395,8 @@ class PluginEntrypoint:
393
395
  )
394
396
  if oauth_secret_name is not None:
395
397
  parameters.access_token_secret_name = oauth_secret_name
396
-
397
- script_result = self._plugin_instance.inbound_stream_list(parameters)
398
+ with tracer.start_as_current_span("invoke_plugin"):
399
+ script_result = self._plugin_instance.inbound_stream_list(parameters)
398
400
  if isinstance(script_result, BaseModel):
399
401
  script_result = script_result.model_dump()
400
402
  elif isinstance(script_result, List):
@@ -428,19 +430,21 @@ class PluginEntrypoint:
428
430
  logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
429
431
  connectivity_option = TypeAdapter(ConnectivityOption).validate_python(connectivity_option)
430
432
  logger.info("Entered connection_form method")
431
- if self._plugin_instance.connection_form.__code__.co_argcount==1:
432
- form: List[ConnectionMethod] = self._plugin_instance.connection_form()
433
- else:
434
- form: List[ConnectionMethod] = self._plugin_instance.connection_form(connectivity_option)
433
+ with tracer.start_as_current_span("invoke_plugin"):
434
+ if self._plugin_instance.connection_form.__code__.co_argcount==1:
435
+ form: List[ConnectionMethod] = self._plugin_instance.connection_form()
436
+ else:
437
+ form: List[ConnectionMethod] = self._plugin_instance.connection_form(connectivity_option)
435
438
  return [f.model_dump() for f in form]
436
439
 
437
440
  def create_billing_events(self, session, event_request: Dict):
438
441
  logger.add_extra('omnata.operation', 'create_billing_events')
439
442
  logger.info("Entered create_billing_events method")
440
443
  request = TypeAdapter(BillingEventRequest).validate_python(event_request)
441
- events: List[SnowflakeBillingEvent] = self._plugin_instance.create_billing_events(
442
- request
443
- )
444
+ with tracer.start_as_current_span("invoke_plugin"):
445
+ events: List[SnowflakeBillingEvent] = self._plugin_instance.create_billing_events(
446
+ request
447
+ )
444
448
  # create each billing event, waiting a second between each one
445
449
  first_time = True
446
450
  for billing_event in events:
@@ -527,31 +531,35 @@ class PluginEntrypoint:
527
531
  )
528
532
  if oauth_secret_name is not None:
529
533
  parameters.access_token_secret_name = oauth_secret_name
530
- connect_response = self._plugin_instance.connect(
531
- parameters=parameters
532
- )
534
+ with tracer.start_as_current_span("invoke_plugin"):
535
+ connect_response = self._plugin_instance.connect(
536
+ parameters=parameters
537
+ )
533
538
  # the connect method can also return more network addresses. If so, we need to update the
534
539
  # network rule associated with the external access integration
535
540
  if connect_response is None:
536
541
  raise ValueError("Plugin did not return a ConnectResponse object from the connect method")
537
542
  if connect_response.network_addresses is not None:
538
- existing_rule_result = self._session.sql(
539
- f"desc network rule {network_rule_name}"
540
- ).collect()
541
- rule_values: List[str] = existing_rule_result[0].value_list.split(",")
542
- rule_values = [r for r in rule_values if r != '']
543
- logger.info(f"Existing rules for {network_rule_name}: {rule_values}")
544
- for network_address in connect_response.network_addresses:
545
- if network_address not in rule_values:
546
- rule_values.append(network_address)
547
- #if len(rule_values)==0:
548
- # logger.info("No network addresses for plugin, adding localhost")
549
- # rule_values.append("https://localhost")
550
- logger.info(f"New rules for {network_rule_name}: {rule_values}")
551
- rule_values_string = ",".join([f"'{value}'" for value in rule_values])
552
- self._session.sql(
553
- f"alter network rule {network_rule_name} set value_list = ({rule_values_string})"
554
- ).collect()
543
+ with tracer.start_as_current_span("network_rule_update") as network_rule_update_span:
544
+ network_rule_update_span.add_event("Retrieving existing network rule")
545
+ existing_rule_result = self._session.sql(
546
+ f"desc network rule {network_rule_name}"
547
+ ).collect()
548
+ rule_values: List[str] = existing_rule_result[0].value_list.split(",")
549
+ rule_values = [r for r in rule_values if r != '']
550
+ logger.info(f"Existing rules for {network_rule_name}: {rule_values}")
551
+ for network_address in connect_response.network_addresses:
552
+ if network_address not in rule_values:
553
+ rule_values.append(network_address)
554
+ #if len(rule_values)==0:
555
+ # logger.info("No network addresses for plugin, adding localhost")
556
+ # rule_values.append("https://localhost")
557
+ logger.info(f"New rules for {network_rule_name}: {rule_values}")
558
+ rule_values_string = ",".join([f"'{value}'" for value in rule_values])
559
+ network_rule_update_span.add_event("Updating network rule")
560
+ self._session.sql(
561
+ f"alter network rule {network_rule_name} set value_list = ({rule_values_string})"
562
+ ).collect()
555
563
 
556
564
  return connect_response.model_dump()
557
565
 
@@ -578,7 +586,8 @@ class PluginEntrypoint:
578
586
  )
579
587
  if oauth_secret_name is not None:
580
588
  connection_parameters.access_token_secret_name = oauth_secret_name
581
- response: List[ApiLimits] = self._plugin_instance.api_limits(connection_parameters)
589
+ with tracer.start_as_current_span("invoke_plugin"):
590
+ response: List[ApiLimits] = self._plugin_instance.api_limits(connection_parameters)
582
591
  return [api_limit.model_dump() for api_limit in response]
583
592
 
584
593
  def outbound_record_validator(
@@ -19,6 +19,9 @@ from .logging import logger
19
19
  import pytz
20
20
  from requests.adapters import HTTPAdapter
21
21
  from urllib3.util.retry import Retry
22
+ from opentelemetry import trace
23
+
24
+ tracer = trace.get_tracer(__name__)
22
25
 
23
26
  TimeUnitType = Literal["second", "minute", "hour", "day"]
24
27
 
@@ -383,11 +386,12 @@ class RetryWithLogging(Retry):
383
386
  retry_after = self.get_retry_after(response)
384
387
  if retry_after:
385
388
  logger.info(f"Retrying after {retry_after} seconds due to Retry-After header")
386
- if self.thread_cancellation_token is None:
387
- time.sleep(retry_after)
388
- else:
389
- if self.thread_cancellation_token.wait(retry_after):
390
- raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting to expire")
389
+ with tracer.start_as_current_span("http_retry_wait"):
390
+ if self.thread_cancellation_token is None:
391
+ time.sleep(retry_after)
392
+ else:
393
+ if self.thread_cancellation_token.wait(retry_after):
394
+ raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting to expire")
391
395
  return True
392
396
  return False
393
397
 
@@ -504,8 +508,9 @@ class RateLimitedSession(requests.Session):
504
508
  raise InterruptedWhileWaitingException(message=f"The rate limiting wait time ({wait_time} seconds) would exceed the run deadline")
505
509
  logger.info(f"Waiting for {wait_time} seconds before retrying {method} request to {url}")
506
510
  # if wait() returns true, it means that the thread was cancelled
507
- if self.thread_cancellation_token.wait(wait_time):
508
- raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting to expire")
511
+ with tracer.start_as_current_span("http_retry_wait"):
512
+ if self.thread_cancellation_token.wait(wait_time):
513
+ raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting to expire")
509
514
  else:
510
515
  current_url_retries = self.increment_retries(url)
511
516
  if current_url_retries >= self.max_retries:
@@ -514,8 +519,9 @@ class RateLimitedSession(requests.Session):
514
519
  if datetime.datetime.now(pytz.UTC) + datetime.timedelta(seconds=backoff_time) > self.run_deadline:
515
520
  raise InterruptedWhileWaitingException(message=f"The rate limiting backoff time ({backoff_time} seconds) would exceed the run deadline")
516
521
  logger.info(f"Waiting for {backoff_time} seconds before retrying {method} request to {url}")
517
- if self.thread_cancellation_token.wait(backoff_time):
518
- raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting backoff")
522
+ with tracer.start_as_current_span("http_retry_wait"):
523
+ if self.thread_cancellation_token.wait(backoff_time):
524
+ raise InterruptedWhileWaitingException(message="The sync was interrupted while waiting for rate limiting backoff")
519
525
  else:
520
526
  self.set_retries(url,0) # Reset retries if the request is successful
521
527
  return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omnata-plugin-runtime
3
- Version: 0.8.0a188
3
+ Version: 0.8.0a190
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=tVi4KLL0v5N3yz3Ie0kSyFemryu572gCbtSRfWN6wBU,6523
3
+ omnata_plugin_runtime/configuration.py,sha256=uMGMqKYy4XmntX1ROungUwTJXeY2ciczAb_PtRCFZZI,38441
4
+ omnata_plugin_runtime/forms.py,sha256=ueodN2GIMS5N9fqebpY4uNGJnjEb9HcuaVQVfWH-cGg,19838
5
+ omnata_plugin_runtime/logging.py,sha256=u_Bo2v4jS3C_2E_Y8a7yfZZcIP-h5Mak_FPnFHUwFbU,4378
6
+ omnata_plugin_runtime/omnata_plugin.py,sha256=aggjb_CTTjhgqjS8CHPOm4ENU0jNcYoT6LC8yI1IeF4,130048
7
+ omnata_plugin_runtime/plugin_entrypoints.py,sha256=dK2mdH9-HRa4vjCso3SIblC72wRU2txDJJBBwMbruo0,32760
8
+ omnata_plugin_runtime/rate_limiting.py,sha256=6fn_h2vxcHbqqiW-OZ6FKfNYv_XlNvorsrCknVce2PA,25929
9
+ omnata_plugin_runtime-0.8.0a190.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
10
+ omnata_plugin_runtime-0.8.0a190.dist-info/METADATA,sha256=NUbYL0R296nnATkJJF4YAV4F8W47yrqiIJ70KNtoSXc,2148
11
+ omnata_plugin_runtime-0.8.0a190.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
12
+ omnata_plugin_runtime-0.8.0a190.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=5M7dmQu9BO2msES9Foa8fOKfWui7iPSExAJdj9TeI98,38329
4
- omnata_plugin_runtime/forms.py,sha256=ueodN2GIMS5N9fqebpY4uNGJnjEb9HcuaVQVfWH-cGg,19838
5
- omnata_plugin_runtime/logging.py,sha256=u_Bo2v4jS3C_2E_Y8a7yfZZcIP-h5Mak_FPnFHUwFbU,4378
6
- omnata_plugin_runtime/omnata_plugin.py,sha256=aggjb_CTTjhgqjS8CHPOm4ENU0jNcYoT6LC8yI1IeF4,130048
7
- omnata_plugin_runtime/plugin_entrypoints.py,sha256=z1NJpWvEj5TizCEU8YLnO5cWmeU8iSEsMK9CQaL47RA,32021
8
- omnata_plugin_runtime/rate_limiting.py,sha256=JKtyz8mA9D0FSZgQplPusmk2rVclcjkwtE59fQQrQ_I,25610
9
- omnata_plugin_runtime-0.8.0a188.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
10
- omnata_plugin_runtime-0.8.0a188.dist-info/METADATA,sha256=OrGtX56IyJCjpFTsxkVu0IZI3Z9zJ5aHSzpgI0Mg3Bk,2148
11
- omnata_plugin_runtime-0.8.0a188.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
12
- omnata_plugin_runtime-0.8.0a188.dist-info/RECORD,,