datadog-checks-base 37.7.0__py2.py3-none-any.whl → 37.9.0__py2.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.
Files changed (49) hide show
  1. datadog_checks/base/__about__.py +1 -1
  2. datadog_checks/base/__init__.py +3 -43
  3. datadog_checks/base/__init__.pyi +31 -0
  4. datadog_checks/base/checks/__init__.py +2 -4
  5. datadog_checks/base/checks/__init__.pyi +7 -0
  6. datadog_checks/base/checks/base.py +80 -40
  7. datadog_checks/base/checks/kube_leader/__init__.py +2 -5
  8. datadog_checks/base/checks/kube_leader/__init__.pyi +8 -0
  9. datadog_checks/base/checks/kubelet_base/__init__.py +6 -0
  10. datadog_checks/base/checks/kubelet_base/__init__.pyi +6 -0
  11. datadog_checks/base/checks/openmetrics/__init__.py +2 -4
  12. datadog_checks/base/checks/openmetrics/__init__.pyi +6 -0
  13. datadog_checks/base/checks/openmetrics/v2/scraper.py +0 -2
  14. datadog_checks/base/checks/openmetrics/v2/transformers/__init__.py +3 -10
  15. datadog_checks/base/checks/openmetrics/v2/transformers/__init__.pyi +26 -0
  16. datadog_checks/base/checks/prometheus/__init__.py +2 -5
  17. datadog_checks/base/checks/prometheus/__init__.pyi +8 -0
  18. datadog_checks/base/checks/prometheus/mixins.py +1 -1
  19. datadog_checks/base/checks/win/__init__.py +2 -4
  20. datadog_checks/base/checks/win/__init__.pyi +7 -0
  21. datadog_checks/base/checks/win/wmi/__init__.py +2 -386
  22. datadog_checks/base/checks/win/wmi/__init__.pyi +32 -0
  23. datadog_checks/base/checks/win/wmi/base.py +390 -0
  24. datadog_checks/base/log.py +10 -8
  25. datadog_checks/base/stubs/aggregator.py +2 -0
  26. datadog_checks/base/stubs/datadog_agent.py +6 -7
  27. datadog_checks/base/utils/_http_utils.py +51 -0
  28. datadog_checks/base/utils/db/__init__.py +3 -2
  29. datadog_checks/base/utils/db/__init__.pyi +7 -0
  30. datadog_checks/base/utils/db/sql.py +2 -2
  31. datadog_checks/base/utils/db/utils.py +3 -3
  32. datadog_checks/base/utils/discovery/__init__.py +3 -1
  33. datadog_checks/base/utils/discovery/__init__.pyi +6 -0
  34. datadog_checks/base/utils/format/__init__.py +3 -0
  35. datadog_checks/base/utils/format/_json.py +43 -0
  36. datadog_checks/base/utils/format/json.py +30 -0
  37. datadog_checks/base/utils/http.py +37 -66
  38. datadog_checks/base/utils/metadata/__init__.py +3 -1
  39. datadog_checks/base/utils/metadata/__init__.pyi +6 -0
  40. datadog_checks/base/utils/prometheus/__init__.py +2 -1
  41. datadog_checks/base/utils/prometheus/__init__.pyi +6 -0
  42. datadog_checks/base/utils/replay/execute.py +6 -5
  43. datadog_checks/base/utils/replay/redirect.py +8 -7
  44. datadog_checks/base/utils/serialization.py +5 -0
  45. datadog_checks/base/utils/tracing.py +10 -1
  46. {datadog_checks_base-37.7.0.dist-info → datadog_checks_base-37.9.0.dist-info}/METADATA +18 -8
  47. {datadog_checks_base-37.7.0.dist-info → datadog_checks_base-37.9.0.dist-info}/RECORD +48 -31
  48. datadog_checks/base/ddyaml.py +0 -171
  49. {datadog_checks_base-37.7.0.dist-info → datadog_checks_base-37.9.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,30 @@
1
+ # (C) Datadog, Inc. 2025-present
2
+ # All rights reserved
3
+ # Licensed under a 3-clause BSD style license (see LICENSE)
4
+ from __future__ import annotations
5
+
6
+ import warnings
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ import lazy_loader
10
+
11
+ if TYPE_CHECKING:
12
+ from collections.abc import Callable
13
+
14
+ from datadog_checks.base.utils.format import _json
15
+
16
+ with warnings.catch_warnings():
17
+ warnings.filterwarnings('ignore', category=RuntimeWarning, module='lazy_loader')
18
+ json: _json = lazy_loader.load('datadog_checks.base.utils.format._json')
19
+
20
+
21
+ def decode(s: str | bytes) -> Any:
22
+ return json.decode(s)
23
+
24
+
25
+ def encode(obj: Any, *, sort_keys: bool = False, default: Callable[[Any], Any] | None = None) -> str:
26
+ return json.encode(obj, sort_keys=sort_keys, default=default)
27
+
28
+
29
+ def encode_bytes(obj: Any, *, sort_keys: bool = False, default: Callable[[Any], Any] | None = None) -> bytes:
30
+ return json.encode_bytes(obj, sort_keys=sort_keys, default=default)
@@ -1,28 +1,27 @@
1
1
  # (C) Datadog, Inc. 2019-present
2
2
  # All rights reserved
3
3
  # Licensed under a 3-clause BSD style license (see LICENSE)
4
+ from __future__ import annotations
5
+
4
6
  import logging
5
7
  import os
6
8
  import re
7
9
  import ssl
8
- from contextlib import contextmanager
10
+ import warnings
11
+ from contextlib import ExitStack, contextmanager
9
12
  from copy import deepcopy
10
- from io import open
11
- from ipaddress import ip_address, ip_network
12
13
  from urllib.parse import quote, urlparse, urlunparse
13
14
 
15
+ import lazy_loader
14
16
  import requests
15
- import requests_unixsocket
16
17
  from binary import KIBIBYTE
17
- from cryptography.x509 import load_der_x509_certificate
18
- from cryptography.x509.extensions import ExtensionNotFound
19
- from cryptography.x509.oid import AuthorityInformationAccessOID, ExtensionOID
20
18
  from requests import auth as requests_auth
21
19
  from requests.exceptions import SSLError
22
- from requests_toolbelt.adapters import host_header_ssl
20
+ from urllib3.exceptions import InsecureRequestWarning
23
21
  from wrapt import ObjectProxy
24
22
 
25
23
  from datadog_checks.base.agent import datadog_agent
24
+ from datadog_checks.base.utils import _http_utils
26
25
 
27
26
  from ..config import is_affirmative
28
27
  from ..errors import ConfigurationError
@@ -31,19 +30,16 @@ from .headers import get_default_headers, update_headers
31
30
  from .network import CertAdapter, create_socket_connection
32
31
  from .time import get_timestamp
33
32
 
34
- try:
35
- from contextlib import ExitStack
36
- except ImportError:
37
- from contextlib2 import ExitStack
33
+ # See Performance Optimizations in this package's README.md.
34
+ requests_kerberos = lazy_loader.load('requests_kerberos')
35
+ requests_ntlm = lazy_loader.load('requests_ntlm')
36
+ requests_oauthlib = lazy_loader.load('requests_oauthlib')
37
+ requests_unixsocket = lazy_loader.load('requests_unixsocket')
38
+ jwt = lazy_loader.load('jwt')
39
+ ipaddress = lazy_loader.load('ipaddress')
38
40
 
39
- # Import lazily to reduce memory footprint and ease installation for development
40
- requests_aws = None
41
- requests_kerberos = None
42
- requests_ntlm = None
43
- requests_oauthlib = None
44
- oauth2 = None
45
- jwt = None
46
- serialization = None
41
+ # We log instead of emit warnings for unintentionally insecure HTTPS requests
42
+ warnings.simplefilter('ignore', InsecureRequestWarning)
47
43
 
48
44
  LOGGER = logging.getLogger(__file__)
49
45
 
@@ -394,7 +390,7 @@ class RequestsWrapper(object):
394
390
  new_options = self.populate_options(options)
395
391
 
396
392
  if url.startswith('https') and not self.ignore_tls_warning and not new_options['verify']:
397
- self.logger.warning(u'An unverified HTTPS request is being made to %s', url)
393
+ self.logger.debug(u'An unverified HTTPS request is being made to %s', url)
398
394
 
399
395
  extra_headers = options.pop('extra_headers', None)
400
396
  if extra_headers is not None:
@@ -499,23 +495,26 @@ class RequestsWrapper(object):
499
495
  # https://tools.ietf.org/html/rfc3280#section-4.2.2.1
500
496
  # https://tools.ietf.org/html/rfc5280#section-5.2.7
501
497
  try:
502
- cert = load_der_x509_certificate(der_cert)
498
+ cert = _http_utils.cryptography_x509_load_certificate(der_cert)
503
499
  except Exception as e:
504
500
  self.logger.error('Error while deserializing peer certificate to discover intermediate certificates: %s', e)
505
501
  return
506
502
 
507
503
  try:
508
504
  authority_information_access = cert.extensions.get_extension_for_oid(
509
- ExtensionOID.AUTHORITY_INFORMATION_ACCESS
505
+ _http_utils.cryptography_x509_ExtensionOID.AUTHORITY_INFORMATION_ACCESS
510
506
  )
511
- except ExtensionNotFound:
507
+ except _http_utils.cryptography_x509_ExtensionNotFound:
512
508
  self.logger.debug(
513
509
  'No Authority Information Access extension found, skipping discovery of intermediate certificates'
514
510
  )
515
511
  return
516
512
 
517
513
  for access_description in authority_information_access.value:
518
- if access_description.access_method != AuthorityInformationAccessOID.CA_ISSUERS:
514
+ if (
515
+ access_description.access_method
516
+ != _http_utils.cryptography_x509_AuthorityInformationAccessOID.CA_ISSUERS
517
+ ):
519
518
  continue
520
519
 
521
520
  uri = access_description.access_location.value
@@ -541,7 +540,7 @@ class RequestsWrapper(object):
541
540
  # Enables HostHeaderSSLAdapter
542
541
  # https://toolbelt.readthedocs.io/en/latest/adapters.html#hostheaderssladapter
543
542
  if self.tls_use_host_header:
544
- self._session.mount('https://', host_header_ssl.HostHeaderSSLAdapter())
543
+ self._session.mount('https://', _http_utils.HostHeaderSSLAdapter())
545
544
  # Enable Unix Domain Socket (UDS) support.
546
545
  # See: https://github.com/msabramo/requests-unixsocket
547
546
  self._session.mount('{}://'.format(UDS_SCHEME), requests_unixsocket.UnixAdapter())
@@ -619,9 +618,9 @@ def should_bypass_proxy(url, no_proxy_uris):
619
618
  try:
620
619
  # If no_proxy_uri is an IP or IP CIDR.
621
620
  # A ValueError is raised if address does not represent a valid IPv4 or IPv6 address.
622
- ipnetwork = ip_network(ensure_unicode(no_proxy_uri))
623
- ipaddress = ip_address(ensure_unicode(parsed_uri))
624
- if ipaddress in ipnetwork:
621
+ ip_network = ipaddress.ip_network(ensure_unicode(no_proxy_uri))
622
+ ip_address = ipaddress.ip_address(ensure_unicode(parsed_uri))
623
+ if ip_address in ip_network:
625
624
  return True
626
625
  except ValueError:
627
626
  # Treat no_proxy_uri as a domain name
@@ -655,21 +654,13 @@ def create_digest_auth(config):
655
654
 
656
655
 
657
656
  def create_ntlm_auth(config):
658
- global requests_ntlm
659
- if requests_ntlm is None:
660
- import requests_ntlm
661
-
662
657
  return requests_ntlm.HttpNtlmAuth(config['ntlm_domain'], config['password'])
663
658
 
664
659
 
665
660
  def create_kerberos_auth(config):
666
- global requests_kerberos
667
- if requests_kerberos is None:
668
- import requests_kerberos
669
-
670
- KERBEROS_STRATEGIES['required'] = requests_kerberos.REQUIRED
671
- KERBEROS_STRATEGIES['optional'] = requests_kerberos.OPTIONAL
672
- KERBEROS_STRATEGIES['disabled'] = requests_kerberos.DISABLED
661
+ KERBEROS_STRATEGIES['required'] = requests_kerberos.REQUIRED
662
+ KERBEROS_STRATEGIES['optional'] = requests_kerberos.OPTIONAL
663
+ KERBEROS_STRATEGIES['disabled'] = requests_kerberos.DISABLED
673
664
 
674
665
  # For convenience
675
666
  if config['kerberos_auth'] is None or is_affirmative(config['kerberos_auth']):
@@ -692,15 +683,11 @@ def create_kerberos_auth(config):
692
683
 
693
684
 
694
685
  def create_aws_auth(config):
695
- global requests_aws
696
- if requests_aws is None:
697
- from aws_requests_auth import boto_utils as requests_aws
698
-
699
686
  for setting in ('aws_host', 'aws_region', 'aws_service'):
700
687
  if not config[setting]:
701
688
  raise ConfigurationError('AWS auth requires the setting `{}`'.format(setting))
702
689
 
703
- return requests_aws.BotoAWSRequestsAuth(
690
+ return _http_utils.BotoAWSRequestsAuth(
704
691
  aws_host=config['aws_host'], aws_region=config['aws_region'], aws_service=config['aws_service']
705
692
  )
706
693
 
@@ -851,15 +838,7 @@ class AuthTokenOAuthReader(object):
851
838
 
852
839
  def read(self, **request):
853
840
  if self._token is None or get_timestamp() >= self._expiration or 'error' in request:
854
- global oauth2
855
- if oauth2 is None:
856
- from oauthlib import oauth2
857
-
858
- global requests_oauthlib
859
- if requests_oauthlib is None:
860
- import requests_oauthlib
861
-
862
- client = oauth2.BackendApplicationClient(client_id=self._client_id)
841
+ client = _http_utils.oauth2.BackendApplicationClient(client_id=self._client_id)
863
842
  oauth = requests_oauthlib.OAuth2Session(client=client)
864
843
  response = oauth.fetch_token(**self._fetch_options)
865
844
 
@@ -911,20 +890,12 @@ class DCOSAuthTokenReader(object):
911
890
  def read(self, **request):
912
891
  if self._token is None or 'error' in request:
913
892
  with open(self._private_key_path, 'rb') as f:
914
- global serialization
915
- if serialization is None:
916
- from cryptography.hazmat.primitives import serialization
917
-
918
- global jwt
919
- if jwt is None:
920
- import jwt
921
-
922
- private_key = serialization.load_pem_private_key(f.read(), password=None)
893
+ private_key = _http_utils.cryptography_serialization.load_pem_private_key(f.read(), password=None)
923
894
 
924
895
  serialized_private = private_key.private_bytes(
925
- encoding=serialization.Encoding.PEM,
926
- format=serialization.PrivateFormat.PKCS8,
927
- encryption_algorithm=serialization.NoEncryption(),
896
+ encoding=_http_utils.cryptography_serialization.Encoding.PEM,
897
+ format=_http_utils.cryptography_serialization.PrivateFormat.PKCS8,
898
+ encryption_algorithm=_http_utils.cryptography_serialization.NoEncryption(),
928
899
  )
929
900
 
930
901
  exp = int(get_timestamp() + self._expiration)
@@ -1,4 +1,6 @@
1
1
  # (C) Datadog, Inc. 2019-present
2
2
  # All rights reserved
3
3
  # Licensed under a 3-clause BSD style license (see LICENSE)
4
- from .core import MetadataManager
4
+ import lazy_loader
5
+
6
+ __getattr__, __dir__, __all__ = lazy_loader.attach_stub(__name__, __file__)
@@ -0,0 +1,6 @@
1
+ # (C) Datadog, Inc. 2025-present
2
+ # All rights reserved
3
+ # Licensed under a 3-clause BSD style license (see LICENSE)
4
+ from .core import MetadataManager
5
+
6
+ __all__ = ['MetadataManager']
@@ -1,5 +1,6 @@
1
1
  # (C) Datadog, Inc. 2016-present
2
2
  # All rights reserved
3
3
  # Licensed under Simplified BSD License (see LICENSE)
4
+ import lazy_loader
4
5
 
5
- from .functions import parse_metric_family # noqa: F401
6
+ __getattr__, __dir__, __all__ = lazy_loader.attach_stub(__name__, __file__)
@@ -0,0 +1,6 @@
1
+ # (C) Datadog, Inc. 2025-present
2
+ # All rights reserved
3
+ # Licensed under a 3-clause BSD style license (see LICENSE)
4
+ from .functions import parse_metric_family
5
+
6
+ __all__ = ['parse_metric_family']
@@ -5,9 +5,10 @@ import os
5
5
  import subprocess
6
6
  import sys
7
7
 
8
+ from datadog_checks.base.utils.format import json
9
+
8
10
  from ..common import ensure_bytes, to_native_string
9
11
  from ..platform import Platform
10
- from ..serialization import json
11
12
  from .constants import KNOWN_DATADOG_AGENT_SETTER_METHODS, EnvVars
12
13
 
13
14
 
@@ -24,8 +25,8 @@ def run_with_isolation(check, aggregator, datadog_agent):
24
25
  env_vars[EnvVars.MESSAGE_INDICATOR] = message_indicator
25
26
  env_vars[EnvVars.CHECK_NAME] = check.name
26
27
  env_vars[EnvVars.CHECK_ID] = check.check_id
27
- env_vars[EnvVars.INIT_CONFIG] = to_native_string(json.dumps(init_config))
28
- env_vars[EnvVars.INSTANCE] = to_native_string(json.dumps(instance))
28
+ env_vars[EnvVars.INIT_CONFIG] = to_native_string(json.encode(init_config))
29
+ env_vars[EnvVars.INSTANCE] = to_native_string(json.encode(instance))
29
30
 
30
31
  if Platform.is_windows():
31
32
  env_vars[EnvVars.DDTRACE] = "false"
@@ -60,7 +61,7 @@ def run_with_isolation(check, aggregator, datadog_agent):
60
61
  check.log.trace(line)
61
62
 
62
63
  message_type, _, message = procedure.partition(':')
63
- message = json.loads(message)
64
+ message = json.decode(message)
64
65
  if message_type == 'aggregator':
65
66
  getattr(aggregator, message['method'])(check, *message['args'], **message['kwargs'])
66
67
  elif message_type == 'log':
@@ -69,7 +70,7 @@ def run_with_isolation(check, aggregator, datadog_agent):
69
70
  method = message['method']
70
71
  value = getattr(datadog_agent, method)(*message['args'], **message['kwargs'])
71
72
  if method not in KNOWN_DATADOG_AGENT_SETTER_METHODS:
72
- process.stdin.write(b'%s\n' % ensure_bytes(json.dumps({'value': value})))
73
+ process.stdin.write(b'%s\n' % ensure_bytes(json.encode({'value': value})))
73
74
  process.stdin.flush()
74
75
  elif message_type == 'error':
75
76
  check.log.error(message[0]['traceback'])
@@ -5,12 +5,13 @@ import logging
5
5
  import os
6
6
  import sys
7
7
 
8
+ from datadog_checks.base.utils.format import json
9
+
8
10
  from ...checks import base
9
11
  from ...log import LOG_LEVEL_MAP, TRACE_LEVEL, _get_py_loglevel
10
12
  from ...utils.common import to_native_string
11
13
  from ...utils.metadata import core
12
14
  from ...utils.replay.constants import KNOWN_DATADOG_AGENT_SETTER_METHODS, EnvVars
13
- from ...utils.serialization import json
14
15
 
15
16
  MESSAGE_INDICATOR = os.environ[EnvVars.MESSAGE_INDICATOR]
16
17
  LOG_METHODS = {log_level: log_method.lower() for log_method, log_level in LOG_LEVEL_MAP.items()}
@@ -30,7 +31,7 @@ class ReplayAggregator(object):
30
31
  print(
31
32
  '{}:aggregator:{}'.format(
32
33
  MESSAGE_INDICATOR,
33
- to_native_string(json.dumps({'method': method_name, 'args': list(args)[1:], 'kwargs': kwargs})),
34
+ to_native_string(json.encode({'method': method_name, 'args': list(args)[1:], 'kwargs': kwargs})),
34
35
  )
35
36
  )
36
37
 
@@ -49,11 +50,11 @@ class ReplayDatadogAgent(object):
49
50
  print(
50
51
  '{}:datadog_agent:{}'.format(
51
52
  MESSAGE_INDICATOR,
52
- to_native_string(json.dumps({'method': method_name, 'args': list(args), 'kwargs': kwargs})),
53
+ to_native_string(json.encode({'method': method_name, 'args': list(args), 'kwargs': kwargs})),
53
54
  )
54
55
  )
55
56
  if read:
56
- return json.loads(sys.stdin.readline())['value']
57
+ return json.decode(sys.stdin.readline())['value']
57
58
 
58
59
  return method
59
60
 
@@ -63,7 +64,7 @@ class ReplayLogger(logging.Logger):
63
64
  print(
64
65
  '{}:log:{}'.format(
65
66
  MESSAGE_INDICATOR,
66
- to_native_string(json.dumps({'method': LOG_METHODS[level], 'args': [str(a) for a in args]})),
67
+ to_native_string(json.encode({'method': LOG_METHODS[level], 'args': [str(a) for a in args]})),
67
68
  )
68
69
  )
69
70
 
@@ -80,8 +81,8 @@ logging.getLogger().setLevel(_get_py_loglevel(base.datadog_agent.get_config('log
80
81
  def run_check(check_class):
81
82
  check = check_class(
82
83
  os.environ[EnvVars.CHECK_NAME],
83
- json.loads(os.environ[EnvVars.INIT_CONFIG]),
84
- [json.loads(os.environ[EnvVars.INSTANCE])],
84
+ json.decode(os.environ[EnvVars.INIT_CONFIG]),
85
+ [json.decode(os.environ[EnvVars.INSTANCE])],
85
86
  )
86
87
  check.check_id = os.environ[EnvVars.CHECK_ID]
87
88
 
@@ -1,3 +1,8 @@
1
+ """
2
+ This module is deprecated and will begin emitting deprecation warnings after all official
3
+ integrations have migrated to the new `datadog_checks.base.utils.format.json` module.
4
+ """
5
+
1
6
  # (C) Datadog, Inc. 2020-present
2
7
  # All rights reserved
3
8
  # Licensed under a 3-clause BSD style license (see LICENSE)
@@ -1,15 +1,24 @@
1
1
  # (C) Datadog, Inc. 2018-present
2
2
  # All rights reserved
3
3
  # Licensed under Simplified BSD License (see LICENSE)
4
+ from __future__ import annotations
5
+
4
6
  import functools
5
- import inspect
6
7
  import os
8
+ from typing import TYPE_CHECKING
9
+
10
+ import lazy_loader
7
11
 
8
12
  from datadog_checks.base.agent import datadog_agent
9
13
 
10
14
  from ..config import is_affirmative
11
15
  from ..utils.common import to_native_string
12
16
 
17
+ if TYPE_CHECKING:
18
+ import inspect as _module_inspect
19
+
20
+ inspect: _module_inspect = lazy_loader.load('inspect')
21
+
13
22
  EXCLUDED_MODULES = ['threading']
14
23
 
15
24
  # During regular continuous tracing we trace only the check's top-level 'run' and
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datadog-checks-base
3
- Version: 37.7.0
3
+ Version: 37.9.0
4
4
  Summary: The Datadog Check Toolkit
5
5
  Project-URL: Source, https://github.com/DataDog/integrations-core
6
6
  Author-email: Datadog <packages@datadoghq.com>
@@ -16,10 +16,11 @@ Provides-Extra: db
16
16
  Requires-Dist: mmh3==5.1.0; extra == 'db'
17
17
  Provides-Extra: deps
18
18
  Requires-Dist: binary==1.0.1; extra == 'deps'
19
- Requires-Dist: cachetools==5.5.1; extra == 'deps'
20
- Requires-Dist: cryptography==43.0.1; extra == 'deps'
19
+ Requires-Dist: cachetools==5.5.2; extra == 'deps'
20
+ Requires-Dist: cryptography==44.0.1; extra == 'deps'
21
21
  Requires-Dist: ddtrace==2.10.6; extra == 'deps'
22
22
  Requires-Dist: jellyfish==1.1.3; extra == 'deps'
23
+ Requires-Dist: lazy-loader==0.4; extra == 'deps'
23
24
  Requires-Dist: prometheus-client==0.21.1; extra == 'deps'
24
25
  Requires-Dist: protobuf==5.29.3; extra == 'deps'
25
26
  Requires-Dist: pydantic==2.10.6; extra == 'deps'
@@ -29,15 +30,14 @@ Requires-Dist: pyyaml==6.0.2; extra == 'deps'
29
30
  Requires-Dist: requests-toolbelt==1.0.0; extra == 'deps'
30
31
  Requires-Dist: requests-unixsocket2==0.4.2; extra == 'deps'
31
32
  Requires-Dist: requests==2.32.3; extra == 'deps'
32
- Requires-Dist: simplejson==3.19.3; extra == 'deps'
33
- Requires-Dist: uptime==3.0.1; extra == 'deps'
33
+ Requires-Dist: simplejson==3.20.1; extra == 'deps'
34
34
  Requires-Dist: wrapt==1.17.2; extra == 'deps'
35
35
  Provides-Extra: http
36
36
  Requires-Dist: aws-requests-auth==0.4.3; extra == 'http'
37
- Requires-Dist: botocore==1.36.16; extra == 'http'
37
+ Requires-Dist: botocore==1.36.26; extra == 'http'
38
38
  Requires-Dist: oauthlib==3.2.2; extra == 'http'
39
39
  Requires-Dist: pyjwt==2.10.1; extra == 'http'
40
- Requires-Dist: pyopenssl==24.2.1; extra == 'http'
40
+ Requires-Dist: pyopenssl==24.3.0; extra == 'http'
41
41
  Requires-Dist: pysocks==1.7.1; extra == 'http'
42
42
  Requires-Dist: requests-kerberos==0.15.0; extra == 'http'
43
43
  Requires-Dist: requests-ntlm==1.3.0; extra == 'http'
@@ -45,7 +45,7 @@ Requires-Dist: requests-oauthlib==2.0.0; extra == 'http'
45
45
  Provides-Extra: json
46
46
  Requires-Dist: orjson==3.10.15; extra == 'json'
47
47
  Provides-Extra: kube
48
- Requires-Dist: kubernetes==32.0.0; extra == 'kube'
48
+ Requires-Dist: kubernetes==32.0.1; extra == 'kube'
49
49
  Requires-Dist: requests-oauthlib==2.0.0; extra == 'kube'
50
50
  Description-Content-Type: text/markdown
51
51
 
@@ -80,6 +80,15 @@ install the toolkit locally and play with it:
80
80
  pip install datadog-checks-base
81
81
  ```
82
82
 
83
+ ## Performance Optimizations
84
+
85
+ We strive to balance lean resource usage with a "batteries included" user experience.
86
+ We employ a few tricks to achieve this.
87
+
88
+ One of them is the [lazy-loader][9] library that allows us to expose a nice API (simple, short imports) without the baseline memory overhead of importing everything all the time.
89
+
90
+ Another trick is to import some of our dependencies inside functions that use them instead of the more conventional import section at the top of the file. We rely on this the most in the `AgentCheck` base class.
91
+
83
92
  ## Troubleshooting
84
93
 
85
94
  Need help? Contact [Datadog support][8].
@@ -91,3 +100,4 @@ Need help? Contact [Datadog support][8].
91
100
  [6]: https://github.com/DataDog/integrations-core
92
101
  [7]: https://pypi.org/project/datadog-checks-base/
93
102
  [8]: https://docs.datadoghq.com/help/
103
+ [9]: https://github.com/scientific-python/lazy-loader