dt-extensions-sdk 1.7.2__tar.gz → 1.7.3__tar.gz

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.
Files changed (89) hide show
  1. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/PKG-INFO +1 -1
  2. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/__about__.py +1 -1
  3. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/callback.py +4 -4
  4. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/extension.py +16 -15
  5. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_extension.py +5 -5
  6. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/.github/workflows/build-package.yml +0 -0
  7. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/.github/workflows/gh-pages-docs.yml +0 -0
  8. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/.github/workflows/publish.yml +0 -0
  9. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/.gitignore +0 -0
  10. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/LICENSE.txt +0 -0
  11. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/README.md +0 -0
  12. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/dt-sdk-header.png +0 -0
  13. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/dt-sdk-logo.png +0 -0
  14. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/favicon.ico +0 -0
  15. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/img/migrate-01-new-extension.png +0 -0
  16. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/img/migrate-02-type.png +0 -0
  17. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/img/migrate-03-import.png +0 -0
  18. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/img/migrate-04-import-remote.png +0 -0
  19. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/img/migrate-05-activation.png +0 -0
  20. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/_static/img/migrate-06-activation-config.png +0 -0
  21. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/events/event_severity.rst +0 -0
  22. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/events/event_type.rst +0 -0
  23. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/events/index.rst +0 -0
  24. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/extension.rst +0 -0
  25. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/metrics/index.rst +0 -0
  26. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/metrics/metric.rst +0 -0
  27. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/api/metrics/metric_type.rst +0 -0
  28. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/assemble.rst +0 -0
  29. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/build.rst +0 -0
  30. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/create.rst +0 -0
  31. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/gencerts.rst +0 -0
  32. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/help.rst +0 -0
  33. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/run.rst +0 -0
  34. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/sign.rst +0 -0
  35. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/upload.rst +0 -0
  36. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/cli/wheel.rst +0 -0
  37. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/conf.py +0 -0
  38. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/guides/building.rst +0 -0
  39. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/guides/extension_structure.rst +0 -0
  40. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/guides/installation.rst +0 -0
  41. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/guides/migration.rst +0 -0
  42. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/index.rst +0 -0
  43. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/docs/requirements.txt +0 -0
  44. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/__init__.py +0 -0
  45. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/__init__.py +0 -0
  46. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/__init__.py +0 -0
  47. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/create.py +0 -0
  48. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/.gitignore.template +0 -0
  49. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/README.md.template +0 -0
  50. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/activation.json.template +0 -0
  51. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/extension/activationSchema.json.template +0 -0
  52. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/extension/extension.yaml.template +0 -0
  53. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/extension_name/__init__.py.template +0 -0
  54. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/extension_name/__main__.py.template +0 -0
  55. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/ruff.toml.template +0 -0
  56. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/secrets.json.template +0 -0
  57. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/create/extension_template/setup.py.template +0 -0
  58. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/main.py +0 -0
  59. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/cli/schema.py +0 -0
  60. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/__init__.py +0 -0
  61. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/activation.py +0 -0
  62. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/communication.py +0 -0
  63. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/event.py +0 -0
  64. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/helper.py +0 -0
  65. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/metric.py +0 -0
  66. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/runtime.py +0 -0
  67. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/snapshot.py +0 -0
  68. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/status.py +0 -0
  69. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/throttled_logger.py +0 -0
  70. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/vendor/__init__.py +0 -0
  71. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/vendor/mureq/LICENSE +0 -0
  72. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/vendor/mureq/__init__.py +0 -0
  73. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/dynatrace_extension/sdk/vendor/mureq/mureq.py +0 -0
  74. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/pyproject.toml +0 -0
  75. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/__init__.py +0 -0
  76. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/cli/__init__.py +0 -0
  77. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/cli/test_dt_sdk.py +0 -0
  78. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/cli/test_templates.py +0 -0
  79. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/cli/test_types.py +0 -0
  80. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/data/snapshot.json +0 -0
  81. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/__init__.py +0 -0
  82. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_activation.py +0 -0
  83. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_callback.py +0 -0
  84. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_communication.py +0 -0
  85. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_endpoints_sfm.py +0 -0
  86. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_metric.py +0 -0
  87. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_runtime_properties.py +0 -0
  88. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_snapshot.py +0 -0
  89. {dt_extensions_sdk-1.7.2 → dt_extensions_sdk-1.7.3}/tests/sdk/test_status.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dt-extensions-sdk
3
- Version: 1.7.2
3
+ Version: 1.7.3
4
4
  Project-URL: Documentation, https://github.com/dynatrace-extensions/dt-extensions-python-sdk#readme
5
5
  Project-URL: Issues, https://github.com/dynatrace-extensions/dt-extensions-python-sdk/issues
6
6
  Project-URL: Source, https://github.com/dynatrace-extensions/dt-extensions-python-sdk
@@ -3,4 +3,4 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
5
 
6
- __version__ = "1.7.2"
6
+ __version__ = "1.7.3"
@@ -4,6 +4,7 @@
4
4
 
5
5
  import logging
6
6
  import random
7
+ import time
7
8
  from collections.abc import Callable
8
9
  from datetime import datetime, timedelta
9
10
  from timeit import default_timer as timer
@@ -39,6 +40,7 @@ class WrappedCallback:
39
40
  self.duration = 0 # global counter
40
41
  self.duration_interval_total = 0 # counter per interval = 1 min by default
41
42
  self.cluster_time_diff = 0
43
+ self.start_timestamp_monotonic = time.monotonic()
42
44
  self.start_timestamp = self.get_current_time_with_cluster_diff()
43
45
  self.running_in_sim = running_in_sim
44
46
  self.activation_type = activation_type
@@ -147,8 +149,6 @@ class WrappedCallback:
147
149
  """
148
150
  Get the timestamp for the next execution of the callback
149
151
  This is done using execution total, the interval and the start timestamp
150
- :return: datetime
152
+ :return: float
151
153
  """
152
- return (
153
- self.start_timestamp + timedelta(seconds=self.interval.total_seconds() * (self.iterations or 1))
154
- ).timestamp()
154
+ return self.start_timestamp_monotonic + self.interval.total_seconds() * (self.iterations or 1)
@@ -28,10 +28,11 @@ from .snapshot import Snapshot
28
28
  from .status import EndpointStatuses, EndpointStatusesMap, IgnoreStatus, Status, StatusValue
29
29
  from .throttled_logger import StrictThrottledHandler, ThrottledHandler
30
30
 
31
- HEARTBEAT_INTERVAL = timedelta(seconds=50)
32
- METRIC_SENDING_INTERVAL = timedelta(seconds=30)
33
- SFM_METRIC_SENDING_INTERVAL = timedelta(seconds=60)
34
- TIME_DIFF_INTERVAL = timedelta(seconds=60)
31
+ # Intervals defined in seconds for internal callbacks
32
+ HEARTBEAT_INTERVAL = 50
33
+ METRIC_SENDING_INTERVAL = 30
34
+ SFM_METRIC_SENDING_INTERVAL = 60
35
+ TIME_DIFF_INTERVAL = 60
35
36
 
36
37
  CALLBACKS_THREAD_POOL_SIZE = 100
37
38
  INTERNAL_THREAD_POOL_SIZE = 20
@@ -180,7 +181,7 @@ class Extension:
180
181
  """
181
182
 
182
183
  _instance: ClassVar = None
183
- schedule_decorators: ClassVar = []
184
+ schedule_decorators: ClassVar[list[tuple[Callable, timedelta | int, tuple | None, ActivationType | None]]] = []
184
185
 
185
186
  def __new__(cls, *args, **kwargs): # noqa: ARG004
186
187
  if Extension._instance is None:
@@ -240,15 +241,15 @@ class Extension:
240
241
  self._running_callbacks: dict[int, WrappedCallback] = {}
241
242
  self._running_callbacks_lock: Lock = Lock()
242
243
 
243
- self._scheduler = sched.scheduler(time.time, time.sleep)
244
+ self._scheduler = sched.scheduler(time.monotonic, time.sleep)
244
245
 
245
246
  # Timestamps for scheduling of internal callbacks
246
- self._next_internal_callbacks_timestamps: dict[str, datetime] = {
247
- "timediff": datetime.now() + TIME_DIFF_INTERVAL,
248
- "heartbeat": datetime.now() + HEARTBEAT_INTERVAL,
249
- "metrics": datetime.now() + METRIC_SENDING_INTERVAL,
250
- "events": datetime.now() + METRIC_SENDING_INTERVAL,
251
- "sfm_metrics": datetime.now() + SFM_METRIC_SENDING_INTERVAL,
247
+ self._next_internal_callbacks_timestamps: dict[str, float] = {
248
+ "timediff": time.monotonic() + TIME_DIFF_INTERVAL,
249
+ "heartbeat": time.monotonic() + HEARTBEAT_INTERVAL,
250
+ "metrics": time.monotonic() + METRIC_SENDING_INTERVAL,
251
+ "events": time.monotonic() + METRIC_SENDING_INTERVAL,
252
+ "sfm_metrics": time.monotonic() + SFM_METRIC_SENDING_INTERVAL,
252
253
  }
253
254
 
254
255
  # Executors for the callbacks and internal methods
@@ -777,7 +778,7 @@ class Extension:
777
778
  parser.add_argument("--secrets", required=False, default="secrets.json")
778
779
  parser.add_argument("--no-print-metrics", required=False, action="store_true")
779
780
 
780
- args, unknown = parser.parse_known_args()
781
+ args, _ = parser.parse_known_args()
781
782
  self._is_fastcheck = args.fastcheck
782
783
  if args.dsid is None:
783
784
  # DEV mode
@@ -1169,10 +1170,10 @@ class Extension:
1169
1170
  def _send_dt_event(self, event: dict[str, str | int | dict[str, str]]):
1170
1171
  self._client.send_dt_event(event)
1171
1172
 
1172
- def _get_and_set_next_internal_callback_timestamp(self, callback_name: str, interval: timedelta):
1173
+ def _get_and_set_next_internal_callback_timestamp(self, callback_name: str, interval: float) -> float:
1173
1174
  next_timestamp = self._next_internal_callbacks_timestamps[callback_name]
1174
1175
  self._next_internal_callbacks_timestamps[callback_name] += interval
1175
- return next_timestamp.timestamp()
1176
+ return next_timestamp
1176
1177
 
1177
1178
  def get_version(self) -> str:
1178
1179
  """Return the extension version."""
@@ -1,7 +1,7 @@
1
1
  import threading
2
2
  import time
3
3
  import unittest
4
- from datetime import datetime, timedelta
4
+ from datetime import timedelta
5
5
  from unittest.mock import MagicMock, mock_open, patch
6
6
 
7
7
  import pytest
@@ -27,7 +27,7 @@ class TestExtension(unittest.TestCase):
27
27
  extension = Extension()
28
28
  extension.logger = MagicMock()
29
29
  extension._running_in_sim = True
30
- extension._next_heartbeat = datetime.now()
30
+ extension._next_heartbeat = time.monotonic()
31
31
  extension._heartbeat_iteration()
32
32
  extension._heartbeat.assert_called()
33
33
 
@@ -387,15 +387,15 @@ class TestExtension(unittest.TestCase):
387
387
  extension._client = MagicMock()
388
388
 
389
389
  fastcheck = MagicMock()
390
- fastcheck.side_effect = Exception("SomeException")
390
+ fastcheck.side_effect = ImportError("SomeException")
391
391
  extension.register_fastcheck(fastcheck)
392
- self.assertRaises(Exception, extension._run_fastcheck)
392
+ self.assertRaises(ImportError, extension._run_fastcheck)
393
393
 
394
394
  fastcheck.assert_called_once()
395
395
  extension._client.send_status.assert_called_once()
396
396
  self.assertEqual(extension._client.send_status.call_args[0][0].status, StatusValue.GENERIC_ERROR)
397
397
  self.assertIn(
398
- "Python datasource fastcheck error: Exception('SomeException')",
398
+ "Python datasource fastcheck error: ImportError('SomeException')",
399
399
  extension._client.send_status.call_args[0][0].message,
400
400
  )
401
401