omnata-plugin-runtime 0.7.0a185__tar.gz → 0.8.0a187__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omnata-plugin-runtime
3
- Version: 0.7.0a185
3
+ Version: 0.8.0a187
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
@@ -19,9 +19,11 @@ Requires-Dist: idna (<=3.7)
19
19
  Requires-Dist: jinja2 (>=3.1.2,<=3.1.4)
20
20
  Requires-Dist: markupsafe (<=2.1.3)
21
21
  Requires-Dist: numpy (<1.27.0)
22
+ Requires-Dist: opentelemetry-api (<=1.23.0)
22
23
  Requires-Dist: packaging (<=24.1)
23
24
  Requires-Dist: pandas (<=2.2.2)
24
25
  Requires-Dist: platformdirs (<=3.10.0)
26
+ Requires-Dist: protobuf (<=4.25.3)
25
27
  Requires-Dist: pyarrow (<=16.1.0)
26
28
  Requires-Dist: pycparser (<=2.21)
27
29
  Requires-Dist: pydantic (>=2,<=2.8.2)
@@ -34,10 +36,12 @@ Requires-Dist: requests (>=2,<=2.32.3)
34
36
  Requires-Dist: setuptools (<=72.1.0)
35
37
  Requires-Dist: snowflake-connector-python (>=3,<=3.12.0)
36
38
  Requires-Dist: snowflake-snowpark-python (==1.23.0)
39
+ Requires-Dist: snowflake-telemetry-python (<=0.5.0)
37
40
  Requires-Dist: tenacity (>=8,<=8.2.3)
38
41
  Requires-Dist: tomlkit (<=0.11.1)
39
42
  Requires-Dist: urllib3 (<=2.2.2)
40
43
  Requires-Dist: wheel (<=0.43.0)
44
+ Requires-Dist: wrapt (<=1.14.1)
41
45
  Description-Content-Type: text/markdown
42
46
 
43
47
  # omnata-plugin-runtime
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "omnata-plugin-runtime"
3
- version = "0.7.0-a185"
3
+ version = "0.8.0-a187"
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"
@@ -38,6 +38,10 @@ wheel = "<=0.43.0" # latest version available on Snowflake Anaconda
38
38
  pyyaml = "<=6.0.1" # latest version available on Snowflake Anaconda
39
39
  cffi = "<=1.16.0" # latest version available on Snowflake Anaconda
40
40
  pyarrow = "<=16.1.0" # latest version available on Snowflake Anaconda
41
+ wrapt = "<=1.14.1" # latest version available on Snowflake Anaconda
42
+ opentelemetry-api = "<=1.23.0" # latest version available on Snowflake Anaconda
43
+ snowflake-telemetry-python = "<=0.5.0" # latest version available on Snowflake Anaconda
44
+ protobuf = "<=4.25.3" # latest version available on Snowflake Anaconda
41
45
 
42
46
  [tool.poetry.dev-dependencies]
43
47
  pytest = "^6.2.4"
@@ -11,6 +11,7 @@ from enum import Enum
11
11
 
12
12
  from abc import ABC
13
13
  from pydantic import BaseModel, Field, PrivateAttr, SerializationInfo, TypeAdapter, field_validator, model_serializer, validator # pylint: disable=no-name-in-module
14
+ from .logging import logger
14
15
 
15
16
  if tuple(sys.version_info[:2]) >= (3, 9):
16
17
  # Python 3.9 and above
@@ -19,8 +20,6 @@ else:
19
20
  # Python 3.8 and below
20
21
  from typing_extensions import Annotated
21
22
 
22
- logger = logging.getLogger(__name__)
23
-
24
23
 
25
24
  class MapperType(str, Enum):
26
25
  FIELD_MAPPING_SELECTOR = "field_mapping_selector"
@@ -4,12 +4,38 @@ Custom logging functionality for Omnata
4
4
  import logging
5
5
  import logging.handlers
6
6
  import traceback
7
- from logging import Logger
7
+ from logging import Logger, getLogger
8
8
  from typing import Dict, List, Optional
9
9
  from snowflake.snowpark import Session
10
10
  from pydantic import ValidationError
11
+ from opentelemetry import trace
11
12
 
12
13
 
14
+ class CustomLoggerAdapter(logging.LoggerAdapter):
15
+ """
16
+ A logger adapter which attaches current trace and span IDs to log messages, so that they can be correlated to traces.
17
+ Also offers the ability to add static extras.
18
+ """
19
+ def __init__(self, logger:logging.Logger, extra):
20
+ super(CustomLoggerAdapter, self).__init__(logger, extra)
21
+ self.extra_extras = {}
22
+
23
+ def add_extra(self, key, value):
24
+ self.extra_extras[key] = value
25
+
26
+ def process(self, msg, kwargs):
27
+ extra = kwargs.get("extra", {})
28
+ current_span = trace.get_current_span()
29
+ context = current_span.get_span_context() if current_span is not None else None
30
+ if context is not None:
31
+ extra["trace_id"] = format(context.trace_id, 'x') # format as hex string to be consistent with Snowflake's handler
32
+ extra["span_id"] = format(context.span_id, 'x')
33
+ extra.update(self.extra_extras)
34
+ kwargs["extra"] = extra
35
+ return msg, kwargs
36
+
37
+ logger = CustomLoggerAdapter(getLogger("omnata_plugin"), {})
38
+
13
39
  def log_exception(exception: Exception, logger_instance: Logger):
14
40
  """
15
41
  Logs an exception to a logger
@@ -24,7 +24,7 @@ from .configuration import (
24
24
  ConnectivityOption
25
25
  )
26
26
  from .forms import ConnectionMethod, FormInputField, FormOption
27
- from .logging import OmnataPluginLogHandler
27
+ from .logging import OmnataPluginLogHandler, logger
28
28
  from .omnata_plugin import (
29
29
  SnowflakeBillingEvent,
30
30
  BillingEventRequest,
@@ -37,9 +37,6 @@ from .omnata_plugin import (
37
37
  from pydantic import TypeAdapter
38
38
  from .rate_limiting import ApiLimits, RateLimitState
39
39
 
40
- # set the logger class to our custom logger so that pydantic errors are handled correctly
41
- logger = logging.getLogger(__name__)
42
-
43
40
  IMPORT_DIRECTORY_NAME = "snowflake_import_directory"
44
41
 
45
42
 
@@ -93,6 +90,14 @@ class PluginEntrypoint:
93
90
  connection_id=request.connection_id,
94
91
  sync_run_id=request.run_id,
95
92
  )
93
+ logger.add_extra('omnata.operation', 'sync')
94
+ logger.add_extra('omnata.sync.id', request.sync_id)
95
+ logger.add_extra('omnata.sync.direction', request.sync_direction)
96
+ logger.add_extra('omnata.connection.id', request.connection_id)
97
+ logger.add_extra('omnata.sync.run_id', request.run_id)
98
+ logger.add_extra('omnata.sync_branch.id', request.sync_branch_id)
99
+ logger.add_extra('omnata.sync_branch.name', request.sync_branch_name)
100
+
96
101
  omnata_log_handler.register(
97
102
  request.logging_level, self._plugin_instance.additional_loggers()
98
103
  )
@@ -283,6 +288,12 @@ class PluginEntrypoint:
283
288
  sync_parameters: Dict,
284
289
  current_form_parameters: Optional[Dict],
285
290
  ):
291
+ logger.add_extra('omnata.operation', 'configuration_form')
292
+ logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
293
+ logger.add_extra('omnata.connection.connection_method', connection_method)
294
+ logger.add_extra('omnata.configuration_form.function_name', function_name)
295
+ logger.add_extra('omnata.sync.direction', sync_direction)
296
+
286
297
  logger.info("Entered configuration_form method")
287
298
  sync_strategy = normalise_nulls(sync_strategy)
288
299
  oauth_secret_name = normalise_nulls(oauth_secret_name)
@@ -342,6 +353,10 @@ class PluginEntrypoint:
342
353
  sync_parameters: Dict,
343
354
  selected_streams: Optional[List[str]], # None to return all streams without requiring schema
344
355
  ):
356
+ logger.add_extra('omnata.operation', 'list_streams')
357
+ logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
358
+ logger.add_extra('omnata.connection.connection_method', connection_method)
359
+ logger.add_extra('omnata.sync.direction', 'inbound')
345
360
  logger.debug("Entered list_streams method")
346
361
  oauth_secret_name = normalise_nulls(oauth_secret_name)
347
362
  other_secrets_name = normalise_nulls(other_secrets_name)
@@ -393,6 +408,8 @@ class PluginEntrypoint:
393
408
  return results
394
409
 
395
410
  def connection_form(self,connectivity_option: str):
411
+ logger.add_extra('omnata.operation', 'connection_form')
412
+ logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
396
413
  connectivity_option = TypeAdapter(ConnectivityOption).validate_python(connectivity_option)
397
414
  logger.info("Entered connection_form method")
398
415
  if self._plugin_instance.connection_form.__code__.co_argcount==1:
@@ -402,6 +419,7 @@ class PluginEntrypoint:
402
419
  return [f.model_dump() for f in form]
403
420
 
404
421
  def create_billing_events(self, session, event_request: Dict):
422
+ logger.add_extra('omnata.operation', 'create_billing_events')
405
423
  logger.info("Entered create_billing_events method")
406
424
  request = TypeAdapter(BillingEventRequest).validate_python(event_request)
407
425
  events: List[SnowflakeBillingEvent] = self._plugin_instance.create_billing_events(
@@ -474,6 +492,9 @@ class PluginEntrypoint:
474
492
  oauth_secret_name: Optional[str],
475
493
  other_secrets_name: Optional[str],
476
494
  ):
495
+ logger.add_extra('omnata.operation', 'connection_test')
496
+ logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
497
+ logger.add_extra('omnata.connection.connection_method', method)
477
498
  logger.info("Entered connect method")
478
499
  logger.info(f"Connection parameters: {connection_parameters}")
479
500
  connection_secrets = get_secrets(oauth_secret_name, other_secrets_name)
@@ -524,6 +545,9 @@ class PluginEntrypoint:
524
545
  connection_parameters: Dict,
525
546
  oauth_secret_name: Optional[str],
526
547
  other_secrets_name: Optional[str]):
548
+ logger.add_extra('omnata.operation', 'api_limits')
549
+ logger.add_extra('omnata.connection.connectivity_option', connectivity_option)
550
+ logger.add_extra('omnata.connection.connection_method', method)
527
551
  logger.info("Entered api_limits method")
528
552
  connection_secrets = get_secrets(oauth_secret_name, other_secrets_name)
529
553
  from omnata_plugin_runtime.omnata_plugin import (
@@ -15,12 +15,11 @@ import logging
15
15
  from pydantic import Field, root_validator, PrivateAttr, field_serializer
16
16
  from pydantic_core import to_jsonable_python
17
17
  from .configuration import SubscriptableBaseModel
18
+ from .logging import logger
18
19
  import pytz
19
20
  from requests.adapters import HTTPAdapter
20
21
  from urllib3.util.retry import Retry
21
22
 
22
- logger = getLogger(__name__)
23
-
24
23
  TimeUnitType = Literal["second", "minute", "hour", "day"]
25
24
 
26
25
  HttpMethodType = Literal[