omnata-plugin-runtime 0.8.0a188__py3-none-any.whl → 0.8.0a190__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,