diff --git a/benchmarks/bm/utils.py b/benchmarks/bm/utils.py index dd7b4991c57..13e99e8be74 100644 --- a/benchmarks/bm/utils.py +++ b/benchmarks/bm/utils.py @@ -65,7 +65,7 @@ def process_trace(self, trace): def drop_traces(tracer): - tracer.configure(settings={"FILTERS": [_DropTraces()]}) + tracer.configure(trace_processors=[_DropTraces()]) def drop_telemetry_events(): diff --git a/benchmarks/rate_limiter/scenario.py b/benchmarks/rate_limiter/scenario.py index 5210647ef89..3388af1cfb8 100644 --- a/benchmarks/rate_limiter/scenario.py +++ b/benchmarks/rate_limiter/scenario.py @@ -23,8 +23,8 @@ def _(loops): windows = [start + (i * self.time_window) for i in range(self.num_windows)] per_window = math.floor(loops / self.num_windows) - for window in windows: + for _ in windows: for _ in range(per_window): - rate_limiter.is_allowed(window) + rate_limiter.is_allowed() yield _ diff --git a/benchmarks/sampling_rule_matches/scenario.py b/benchmarks/sampling_rule_matches/scenario.py index 70ee5111bf8..d77926f5d65 100644 --- a/benchmarks/sampling_rule_matches/scenario.py +++ b/benchmarks/sampling_rule_matches/scenario.py @@ -4,8 +4,8 @@ import bm +from ddtrace._trace.sampling_rule import SamplingRule from ddtrace._trace.span import Span -from ddtrace.sampling_rule import SamplingRule def rands(size=6, chars=string.ascii_uppercase + string.digits): diff --git a/ddtrace/__init__.py b/ddtrace/__init__.py index e480851926f..008e931a482 100644 --- a/ddtrace/__init__.py +++ b/ddtrace/__init__.py @@ -27,9 +27,11 @@ from ._monkey import patch_all # noqa: E402 from .internal.compat import PYTHON_VERSION_INFO # noqa: E402 from .internal.utils.deprecations import DDTraceDeprecationWarning # noqa: E402 -from ddtrace._trace.pin import Pin # noqa: E402 -from ddtrace._trace.span import Span # noqa: E402 -from ddtrace._trace.tracer import Tracer # noqa: E402 + +# TODO(munir): Remove the imports below in v3.0 +from ddtrace._trace import pin as _p # noqa: E402, F401 +from ddtrace._trace import span as _s # noqa: E402, F401 +from ddtrace._trace import tracer as _t # noqa: E402, F401 from ddtrace.vendor import debtcollector from .version import get_version # noqa: E402 @@ -39,15 +41,6 @@ _start_mini_agent() -# DEV: Import deprecated tracer module in order to retain side-effect of package -# initialization, which added this module to sys.modules. We catch deprecation -# warnings as this is only to retain a side effect of the package -# initialization. -# TODO: Remove this in v3.0 when the ddtrace/tracer.py module is removed -with warnings.catch_warnings(): - warnings.simplefilter("ignore") - from .tracer import Tracer as _ - __version__ = get_version() # TODO: Deprecate accessing tracer from ddtrace.__init__ module in v4.0 @@ -57,36 +50,11 @@ __all__ = [ "patch", "patch_all", - "Pin", - "Span", - "Tracer", "config", "DDTraceDeprecationWarning", ] -_DEPRECATED_TRACE_ATTRIBUTES = [ - "Span", - "Tracer", - "Pin", -] - - -def __getattr__(name): - if name in _DEPRECATED_TRACE_ATTRIBUTES: - debtcollector.deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Import from ddtrace.trace instead.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - - raise AttributeError("%s has no attribute %s", __name__, name) - - def check_supported_python_version(): if PYTHON_VERSION_INFO < (3, 8): deprecation_message = ( diff --git a/ddtrace/_trace/sampling_rule.py b/ddtrace/_trace/sampling_rule.py index 532a0b71f51..482a95d403a 100644 --- a/ddtrace/_trace/sampling_rule.py +++ b/ddtrace/_trace/sampling_rule.py @@ -8,8 +8,6 @@ from ddtrace.internal.glob_matching import GlobMatcher from ddtrace.internal.logger import get_logger from ddtrace.internal.utils.cache import cachedmethod -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate if TYPE_CHECKING: # pragma: no cover @@ -210,14 +208,12 @@ def choose_matcher(self, prop): # We currently support the ability to pass in a function, a regular expression, or a string # If a string is passed in we create a GlobMatcher to handle the matching if callable(prop) or isinstance(prop, pattern_type): - # deprecated: passing a function or a regular expression' - deprecate( - "Using methods or regular expressions for SamplingRule matching is deprecated. ", - message="Please move to passing in a string for Glob matching.", - removal_version="3.0.0", - category=DDTraceDeprecationWarning, + log.error( + "Using methods or regular expressions for SamplingRule matching is not supported: %s ." + "Please move to passing in a string for Glob matching.", + str(prop), ) - return prop + return "None" # Name and Resource will never be None, but service can be, since we str() # whatever we pass into the GlobMatcher, we can just use its matching elif prop is None: diff --git a/ddtrace/_trace/span.py b/ddtrace/_trace/span.py index 446239a8091..c6eb4d4b72a 100644 --- a/ddtrace/_trace/span.py +++ b/ddtrace/_trace/span.py @@ -52,8 +52,6 @@ from ddtrace.internal.logger import get_logger from ddtrace.internal.sampling import SamplingMechanism from ddtrace.internal.sampling import set_sampling_decision_maker -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate _NUMERIC_TAGS = (_ANALYTICS_SAMPLE_RATE_KEY,) @@ -279,29 +277,6 @@ def duration(self) -> Optional[float]: def duration(self, value: float) -> None: self.duration_ns = int(value * 1e9) - @property - def sampled(self) -> Optional[bool]: - deprecate( - "span.sampled is deprecated and will be removed in a future version of the tracer.", - message="""span.sampled references the state of span.context.sampling_priority. - Please use span.context.sampling_priority instead to check if a span is sampled.""", - category=DDTraceDeprecationWarning, - ) - if self.context.sampling_priority is None: - # this maintains original span.sampled behavior, where all spans would start - # with span.sampled = True until sampling runs - return True - return self.context.sampling_priority > 0 - - @sampled.setter - def sampled(self, value: bool) -> None: - deprecate( - "span.sampled is deprecated and will be removed in a future version of the tracer.", - message="""span.sampled has a no-op setter. - Please use span.set_tag('manual.keep'/'manual.drop') to keep or drop spans.""", - category=DDTraceDeprecationWarning, - ) - def finish(self, finish_time: Optional[float] = None) -> None: """Mark the end time of the span and submit it to the tracer. If the span has already been finished don't do anything. diff --git a/ddtrace/_trace/tracer.py b/ddtrace/_trace/tracer.py index 87f312bb18c..7030ec823d6 100644 --- a/ddtrace/_trace/tracer.py +++ b/ddtrace/_trace/tracer.py @@ -24,6 +24,7 @@ from ddtrace._trace.processor import TraceProcessor from ddtrace._trace.processor import TraceSamplingProcessor from ddtrace._trace.processor import TraceTagsProcessor +from ddtrace._trace.provider import BaseContextProvider from ddtrace._trace.provider import DefaultContextProvider from ddtrace._trace.sampler import BasePrioritySampler from ddtrace._trace.sampler import BaseSampler @@ -200,7 +201,7 @@ def __init__( self, url: Optional[str] = None, dogstatsd_url: Optional[str] = None, - context_provider: Optional[DefaultContextProvider] = None, + context_provider: Optional[BaseContextProvider] = None, ) -> None: """ Create a new ``Tracer`` instance. A global tracer is already initialized @@ -328,28 +329,6 @@ def sample(self, span): else: log.error("No sampler available to sample span") - @property - def sampler(self): - deprecate( - "tracer.sampler is deprecated and will be removed.", - message="To manually sample call tracer.sample(span) instead.", - category=DDTraceDeprecationWarning, - ) - return self._sampler - - @sampler.setter - def sampler(self, value): - deprecate( - "Setting a custom sampler is deprecated and will be removed.", - message="""Please use DD_TRACE_SAMPLING_RULES to configure the sampler instead: - https://ddtrace.readthedocs.io/en/stable/configuration.html#DD_TRACE_SAMPLING_RULES""", - category=DDTraceDeprecationWarning, - ) - if asm_config._apm_opt_out: - log.warning("Cannot set a custom sampler with Standalone ASM mode") - return - self._sampler = value - def on_start_span(self, func: Callable) -> Callable: """Register a function to execute when a span start. @@ -441,21 +420,7 @@ def get_log_correlation_context(self, active: Optional[Union[Context, Span]] = N def configure( self, - enabled: Optional[bool] = None, - hostname: Optional[str] = None, - port: Optional[int] = None, - uds_path: Optional[str] = None, - https: Optional[bool] = None, - sampler: Optional[BaseSampler] = None, - context_provider: Optional[DefaultContextProvider] = None, - wrap_executor: Optional[Callable] = None, - priority_sampling: Optional[bool] = None, - settings: Optional[Dict[str, Any]] = None, - dogstatsd_url: Optional[str] = None, - writer: Optional[TraceWriter] = None, - partial_flush_enabled: Optional[bool] = None, - partial_flush_min_spans: Optional[int] = None, - api_version: Optional[str] = None, + context_provider: Optional[BaseContextProvider] = None, compute_stats_enabled: Optional[bool] = None, appsec_enabled: Optional[bool] = None, iast_enabled: Optional[bool] = None, @@ -472,58 +437,14 @@ def configure( :param bool appsec_standalone_enabled: When tracing is disabled ensures ASM support is still enabled. :param List[TraceProcessor] trace_processors: This parameter sets TraceProcessor (ex: TraceFilters). Trace processors are used to modify and filter traces based on certain criteria. - - :param bool enabled: If True, finished traces will be submitted to the API, else they'll be dropped. - This parameter is deprecated and will be removed. - :param str hostname: Hostname running the Trace Agent. This parameter is deprecated and will be removed. - :param int port: Port of the Trace Agent. This parameter is deprecated and will be removed. - :param str uds_path: The Unix Domain Socket path of the agent. This parameter is deprecated and will be removed. - :param bool https: Whether to use HTTPS or HTTP. This parameter is deprecated and will be removed. - :param object sampler: A custom Sampler instance, locally deciding to totally drop the trace or not. - This parameter is deprecated and will be removed. - :param object wrap_executor: callable that is used when a function is decorated with - ``Tracer.wrap()``. This is an advanced option that usually doesn't need to be changed - from the default value. This parameter is deprecated and will be removed. - :param priority_sampling: This parameter is deprecated and will be removed in a future version. - :param bool settings: This parameter is deprecated and will be removed. - :param str dogstatsd_url: URL for UDP or Unix socket connection to DogStatsD - This parameter is deprecated and will be removed. - :param TraceWriter writer: This parameter is deprecated and will be removed. - :param bool partial_flush_enabled: This parameter is deprecated and will be removed. - :param bool partial_flush_min_spans: This parameter is deprecated and will be removed. - :param str api_version: This parameter is deprecated and will be removed. - :param bool compute_stats_enabled: This parameter is deprecated and will be removed. """ - if settings is not None: - deprecate( - "Support for ``tracer.configure(...)`` with the settings parameter is deprecated", - message="Please use the trace_processors parameter instead of settings['FILTERS'].", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) - trace_processors = (trace_processors or []) + (settings.get("FILTERS") or []) - return self._configure( - enabled, - hostname, - port, - uds_path, - https, - sampler, - context_provider, - wrap_executor, - priority_sampling, - trace_processors, - dogstatsd_url, - writer, - partial_flush_enabled, - partial_flush_min_spans, - api_version, - compute_stats_enabled, - appsec_enabled, - iast_enabled, - appsec_standalone_enabled, - True, + context_provider=context_provider, + trace_processors=trace_processors, + compute_stats_enabled=compute_stats_enabled, + appsec_enabled=appsec_enabled, + iast_enabled=iast_enabled, + appsec_standalone_enabled=appsec_standalone_enabled, ) def _configure( @@ -534,7 +455,7 @@ def _configure( uds_path: Optional[str] = None, https: Optional[bool] = None, sampler: Optional[BaseSampler] = None, - context_provider: Optional[DefaultContextProvider] = None, + context_provider: Optional[BaseContextProvider] = None, wrap_executor: Optional[Callable] = None, priority_sampling: Optional[bool] = None, trace_processors: Optional[List[TraceProcessor]] = None, @@ -547,48 +468,18 @@ def _configure( appsec_enabled: Optional[bool] = None, iast_enabled: Optional[bool] = None, appsec_standalone_enabled: Optional[bool] = None, - log_deprecations: bool = False, ) -> None: if enabled is not None: self.enabled = enabled - if log_deprecations: - deprecate( - "Enabling/Disabling tracing after application start is deprecated", - message="Please use DD_TRACE_ENABLED instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) - - if priority_sampling is not None and log_deprecations: - deprecate( - "Disabling priority sampling is deprecated", - message="Calling `tracer.configure(priority_sampling=....) has no effect", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) if trace_processors is not None: self._user_trace_processors = trace_processors if partial_flush_enabled is not None: self._partial_flush_enabled = partial_flush_enabled - if log_deprecations: - deprecate( - "Configuring partial flushing after application start is deprecated", - message="Please use DD_TRACE_PARTIAL_FLUSH_ENABLED to enable/disable the partial flushing instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) if partial_flush_min_spans is not None: self._partial_flush_min_spans = partial_flush_min_spans - if log_deprecations: - deprecate( - "Configuring partial flushing after application start is deprecated", - message="Please use DD_TRACE_PARTIAL_FLUSH_MIN_SPANS to set the flushing threshold instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) if appsec_enabled is not None: asm_config._asm_enabled = appsec_enabled @@ -620,33 +511,11 @@ def _configure( if sampler is not None: self._sampler = sampler self._user_sampler = self._sampler - if log_deprecations: - deprecate( - "Configuring custom samplers is deprecated", - message="Please use DD_TRACE_SAMPLING_RULES to configure the sample rates instead", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) if dogstatsd_url is not None: - if log_deprecations: - deprecate( - "Configuring dogstatsd_url after application start is deprecated", - message="Please use DD_DOGSTATSD_URL instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) self._dogstatsd_url = dogstatsd_url if any(x is not None for x in [hostname, port, uds_path, https]): - if log_deprecations: - deprecate( - "Configuring tracer agent connection after application start is deprecated", - message="Please use DD_TRACE_AGENT_URL instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) - # If any of the parts of the URL have updated, merge them with # the previous writer values. prev_url_parsed = compat.parse.urlparse(self._agent_url) @@ -670,13 +539,6 @@ def _configure( new_url = None if compute_stats_enabled is not None: - if log_deprecations: - deprecate( - "Configuring tracer stats computation after application start is deprecated", - message="Please use DD_TRACE_STATS_COMPUTATION_ENABLED instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) self._compute_stats = compute_stats_enabled try: @@ -685,14 +547,6 @@ def _configure( # It's possible the writer never got started pass - if api_version is not None and log_deprecations: - deprecate( - "Configuring Tracer API version after application start is deprecated", - message="Please use DD_TRACE_API_VERSION instead.", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) - if writer is not None: self._writer = writer elif any(x is not None for x in [new_url, api_version, sampler, dogstatsd_url, appsec_enabled]): @@ -754,12 +608,6 @@ def _configure( if wrap_executor is not None: self._wrap_executor = wrap_executor - if log_deprecations: - deprecate( - "Support for tracer.configure(...) with the wrap_executor parameter is deprecated", - version="3.0.0", - category=DDTraceDeprecationWarning, - ) self._generate_diagnostic_logs() @@ -1344,7 +1192,7 @@ def _handle_sampler_update(self, cfg: Config) -> None: and self._user_sampler ): # if we get empty configs from rc for both sample rate and rules, we should revert to the user sampler - self.sampler = self._user_sampler + self._sampler = self._user_sampler return if cfg._get_source("_trace_sample_rate") != "remote_config" and self._user_sampler: diff --git a/ddtrace/appsec/_common_module_patches.py b/ddtrace/appsec/_common_module_patches.py index 0b455dbba6b..8c834b80e6f 100644 --- a/ddtrace/appsec/_common_module_patches.py +++ b/ddtrace/appsec/_common_module_patches.py @@ -1,5 +1,4 @@ -# This module must not import other modules inconditionnaly that -# require iast, ddwaf or any native optional module. +# This module must not import other modules unconditionally that require iast import ctypes import os @@ -17,9 +16,6 @@ from ddtrace.appsec._asm_request_context import get_blocked from ddtrace.appsec._constants import EXPLOIT_PREVENTION from ddtrace.appsec._constants import WAF_ACTIONS -from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled -from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_sink -from ddtrace.appsec._iast.constants import VULN_PATH_TRAVERSAL import ddtrace.contrib.internal.subprocess.patch as subprocess_patch from ddtrace.internal import core from ddtrace.internal._exceptions import BlockingException @@ -29,6 +25,14 @@ from ddtrace.settings.asm import config as asm_config +if asm_config._iast_enabled: + from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled +else: + + def is_iast_request_enabled() -> bool: + return False + + log = get_logger(__name__) _DD_ORIGINAL_ATTRIBUTES: Dict[Any, Any] = {} @@ -42,6 +46,16 @@ def patch_common_modules(): global _is_patched if _is_patched: return + # for testing purposes, we need to update is_iast_request_enabled + if asm_config._iast_enabled: + global is_iast_request_enabled + from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled + else: + global is_iast_request_enabled + + def is_iast_request_enabled() -> bool: + return False + try_wrap_function_wrapper("builtins", "open", wrapped_open_CFDDB7ABBA9081B6) try_wrap_function_wrapper("urllib.request", "OpenerDirector.open", wrapped_open_ED4CF71136E15EBF) try_wrap_function_wrapper("_io", "BytesIO.read", wrapped_read_F3E51D71B4EC16EF) @@ -52,6 +66,9 @@ def patch_common_modules(): subprocess_patch.add_lst_callback(_RASP_POPEN, popen_FD233052260D8B4D) core.on("asm.block.dbapi.execute", execute_4C9BAC8E228EB347) if asm_config._iast_enabled: + from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_sink + from ddtrace.appsec._iast.constants import VULN_PATH_TRAVERSAL + _set_metric_iast_instrumented_sink(VULN_PATH_TRAVERSAL) _is_patched = True diff --git a/ddtrace/appsec/_iast/_evidence_redaction/_sensitive_handler.py b/ddtrace/appsec/_iast/_evidence_redaction/_sensitive_handler.py index a10455dee42..dccc18a39b6 100644 --- a/ddtrace/appsec/_iast/_evidence_redaction/_sensitive_handler.py +++ b/ddtrace/appsec/_iast/_evidence_redaction/_sensitive_handler.py @@ -10,6 +10,7 @@ from ..constants import VULN_HEADER_INJECTION from ..constants import VULN_SQL_INJECTION from ..constants import VULN_SSRF +from ..constants import VULN_XSS from .command_injection_sensitive_analyzer import command_injection_sensitive_analyzer from .default_sensitive_analyzer import default_sensitive_analyzer from .header_injection_sensitive_analyzer import header_injection_sensitive_analyzer @@ -45,6 +46,7 @@ def __init__(self): VULN_SQL_INJECTION: sql_sensitive_analyzer, VULN_SSRF: url_sensitive_analyzer, VULN_HEADER_INJECTION: header_injection_sensitive_analyzer, + VULN_XSS: default_sensitive_analyzer, VULN_CODE_INJECTION: default_sensitive_analyzer, } diff --git a/ddtrace/appsec/_iast/_iast_request_context.py b/ddtrace/appsec/_iast/_iast_request_context.py index 30a3471b595..ce3417d9594 100644 --- a/ddtrace/appsec/_iast/_iast_request_context.py +++ b/ddtrace/appsec/_iast/_iast_request_context.py @@ -118,7 +118,7 @@ def set_iast_request_enabled(request_enabled) -> None: log.debug("[IAST] Trying to set IAST reporter but no context is present") -def is_iast_request_enabled(): +def is_iast_request_enabled() -> bool: env = _get_iast_context() if env: return env.request_enabled diff --git a/ddtrace/appsec/_iast/_patch_modules.py b/ddtrace/appsec/_iast/_patch_modules.py index e91438ebd49..634cd6399c5 100644 --- a/ddtrace/appsec/_iast/_patch_modules.py +++ b/ddtrace/appsec/_iast/_patch_modules.py @@ -7,6 +7,7 @@ "header_injection": True, "weak_cipher": True, "weak_hash": True, + "xss": True, } diff --git a/ddtrace/appsec/_iast/constants.py b/ddtrace/appsec/_iast/constants.py index 9ac6edb0ab1..3d0edc31b83 100644 --- a/ddtrace/appsec/_iast/constants.py +++ b/ddtrace/appsec/_iast/constants.py @@ -14,6 +14,7 @@ VULN_CMDI = "COMMAND_INJECTION" VULN_HEADER_INJECTION = "HEADER_INJECTION" VULN_CODE_INJECTION = "CODE_INJECTION" +VULN_XSS = "XSS" VULN_SSRF = "SSRF" VULN_STACKTRACE_LEAK = "STACKTRACE_LEAK" diff --git a/ddtrace/appsec/_iast/taint_sinks/xss.py b/ddtrace/appsec/_iast/taint_sinks/xss.py new file mode 100644 index 00000000000..425affac77a --- /dev/null +++ b/ddtrace/appsec/_iast/taint_sinks/xss.py @@ -0,0 +1,78 @@ +from typing import Text + +from ddtrace.appsec._common_module_patches import try_unwrap +from ddtrace.appsec._constants import IAST_SPAN_TAGS +from ddtrace.appsec._iast import oce +from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled +from ddtrace.appsec._iast._metrics import _set_metric_iast_executed_sink +from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_sink +from ddtrace.appsec._iast._metrics import increment_iast_span_metric +from ddtrace.appsec._iast._patch import set_and_check_module_is_patched +from ddtrace.appsec._iast._patch import set_module_unpatched +from ddtrace.appsec._iast._patch import try_wrap_function_wrapper +from ddtrace.appsec._iast._taint_tracking._taint_objects import is_pyobject_tainted +from ddtrace.appsec._iast.constants import VULN_XSS +from ddtrace.appsec._iast.taint_sinks._base import VulnerabilityBase +from ddtrace.internal.logger import get_logger +from ddtrace.settings.asm import config as asm_config + + +log = get_logger(__name__) + + +@oce.register +class XSS(VulnerabilityBase): + vulnerability_type = VULN_XSS + + +def get_version() -> Text: + return "" + + +def patch(): + if not asm_config._iast_enabled: + return + + if not set_and_check_module_is_patched("flask", default_attr="_datadog_xss_patch"): + return + if not set_and_check_module_is_patched("django", default_attr="_datadog_xss_patch"): + return + if not set_and_check_module_is_patched("fastapi", default_attr="_datadog_xss_patch"): + return + + try_wrap_function_wrapper( + "django.utils.safestring", + "mark_safe", + _iast_django_xss, + ) + + try_wrap_function_wrapper( + "django.template.defaultfilters", + "mark_safe", + _iast_django_xss, + ) + + _set_metric_iast_instrumented_sink(VULN_XSS) + + +def unpatch(): + try_unwrap("django.utils.safestring", "mark_safe") + try_unwrap("django.template.defaultfilters", "mark_safe") + + set_module_unpatched("flask", default_attr="_datadog_xss_patch") + set_module_unpatched("django", default_attr="_datadog_xss_patch") + set_module_unpatched("fastapi", default_attr="_datadog_xss_patch") + + +def _iast_django_xss(wrapped, instance, args, kwargs): + if args and len(args) >= 1: + _iast_report_xss(args[0]) + return wrapped(*args, **kwargs) + + +def _iast_report_xss(code_string: Text): + increment_iast_span_metric(IAST_SPAN_TAGS.TELEMETRY_EXECUTED_SINK, XSS.vulnerability_type) + _set_metric_iast_executed_sink(XSS.vulnerability_type) + if is_iast_request_enabled(): + if is_pyobject_tainted(code_string): + XSS.report(evidence_value=code_string) diff --git a/ddtrace/constants.py b/ddtrace/constants.py index b4694e24345..829a57a45a7 100644 --- a/ddtrace/constants.py +++ b/ddtrace/constants.py @@ -1,39 +1,37 @@ -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning as _DDTraceDeprecationWarning -from ddtrace.vendor import debtcollector as _debtcollector - - -# TODO: Deprecate and remove the SAMPLE_RATE_METRIC_KEY constant. -# This key enables legacy trace sampling support in the Datadog agent. -_SAMPLE_RATE_METRIC_KEY = SAMPLE_RATE_METRIC_KEY = "_sample_rate" -_SAMPLING_PRIORITY_KEY = SAMPLING_PRIORITY_KEY = "_sampling_priority_v1" -_ANALYTICS_SAMPLE_RATE_KEY = ANALYTICS_SAMPLE_RATE_KEY = "_dd1.sr.eausr" -_SAMPLING_AGENT_DECISION = SAMPLING_AGENT_DECISION = "_dd.agent_psr" -_SAMPLING_RULE_DECISION = SAMPLING_RULE_DECISION = "_dd.rule_psr" -_SAMPLING_LIMIT_DECISION = SAMPLING_LIMIT_DECISION = "_dd.limit_psr" +""" +This module contains constants used across ddtrace products. + +Constants that should NOT be referenced by ddtrace users are marked with a leading underscore. +""" +_SAMPLING_PRIORITY_KEY = "_sampling_priority_v1" +_ANALYTICS_SAMPLE_RATE_KEY = "_dd1.sr.eausr" +_SAMPLING_AGENT_DECISION = "_dd.agent_psr" +_SAMPLING_RULE_DECISION = "_dd.rule_psr" +_SAMPLING_LIMIT_DECISION = "_dd.limit_psr" _SINGLE_SPAN_SAMPLING_MECHANISM = "_dd.span_sampling.mechanism" _SINGLE_SPAN_SAMPLING_RATE = "_dd.span_sampling.rule_rate" _SINGLE_SPAN_SAMPLING_MAX_PER_SEC = "_dd.span_sampling.max_per_second" _SINGLE_SPAN_SAMPLING_MAX_PER_SEC_NO_LIMIT = -1 _APM_ENABLED_METRIC_KEY = "_dd.apm.enabled" -_ORIGIN_KEY = ORIGIN_KEY = "_dd.origin" -_USER_ID_KEY = USER_ID_KEY = "_dd.p.usr.id" -_HOSTNAME_KEY = HOSTNAME_KEY = "_dd.hostname" -_RUNTIME_FAMILY = RUNTIME_FAMILY = "_dd.runtime_family" +_ORIGIN_KEY = "_dd.origin" +_USER_ID_KEY = "_dd.p.usr.id" +_HOSTNAME_KEY = "_dd.hostname" +_RUNTIME_FAMILY = "_dd.runtime_family" ENV_KEY = "env" VERSION_KEY = "version" SERVICE_KEY = "service.name" -_BASE_SERVICE_KEY = BASE_SERVICE_KEY = "_dd.base_service" +_BASE_SERVICE_KEY = "_dd.base_service" SERVICE_VERSION_KEY = "service.version" SPAN_KIND = "span.kind" -_SPAN_MEASURED_KEY = SPAN_MEASURED_KEY = "_dd.measured" -_KEEP_SPANS_RATE_KEY = KEEP_SPANS_RATE_KEY = "_dd.tracer_kr" -_MULTIPLE_IP_HEADERS = MULTIPLE_IP_HEADERS = "_dd.multiple-ip-headers" +_SPAN_MEASURED_KEY = "_dd.measured" +_KEEP_SPANS_RATE_KEY = "_dd.tracer_kr" +_MULTIPLE_IP_HEADERS = "_dd.multiple-ip-headers" APPSEC_ENV = "DD_APPSEC_ENABLED" -_CONFIG_ENDPOINT_ENV = CONFIG_ENDPOINT_ENV = "_DD_CONFIG_ENDPOINT" -_CONFIG_ENDPOINT_RETRIES_ENV = CONFIG_ENDPOINT_RETRIES_ENV = "_DD_CONFIG_ENDPOINT_RETRIES" -_CONFIG_ENDPOINT_TIMEOUT_ENV = CONFIG_ENDPOINT_TIMEOUT_ENV = "_DD_CONFIG_ENDPOINT_TIMEOUT" +_CONFIG_ENDPOINT_ENV = "_DD_CONFIG_ENDPOINT" +_CONFIG_ENDPOINT_RETRIES_ENV = "_DD_CONFIG_ENDPOINT_RETRIES" +_CONFIG_ENDPOINT_TIMEOUT_ENV = "_DD_CONFIG_ENDPOINT_TIMEOUT" IAST_ENV = "DD_IAST_ENABLED" MANUAL_DROP_KEY = "manual.drop" @@ -53,38 +51,3 @@ AUTO_KEEP = 1 # Use this to explicitly inform the backend that a trace should be kept and stored. USER_KEEP = 2 - - -_DEPRECATED_MODULE_ATTRIBUTES = [ - "ANALYTICS_SAMPLE_RATE_KEY", - "SAMPLE_RATE_METRIC_KEY", - "SAMPLING_PRIORITY_KEY", - "SAMPLING_AGENT_DECISION", - "SAMPLING_RULE_DECISION", - "SAMPLING_LIMIT_DECISION", - "USER_ID_KEY", - "ORIGIN_KEY", - "HOSTNAME_KEY", - "RUNTIME_FAMILY", - "BASE_SERVICE_KEY", - "SPAN_MEASURED_KEY", - "KEEP_SPANS_RATE_KEY", - "MULTIPLE_IP_HEADERS", - "CONFIG_ENDPOINT_ENV", - "CONFIG_ENDPOINT_RETRIES_ENV", - "CONFIG_ENDPOINT_TIMEOUT_ENV", -] - - -def __getattr__(name): - if name in _DEPRECATED_MODULE_ATTRIBUTES: - _debtcollector.deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=_DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/context.py b/ddtrace/context.py deleted file mode 100644 index 843ef510c38..00000000000 --- a/ddtrace/context.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.trace import Context # noqa: F401 -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The ddtrace.context module is deprecated and will be removed from the public API.", - message="Context should be imported from the ddtrace.trace package", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/contrib/__init__.py b/ddtrace/contrib/__init__.py index cb5b2c1de09..668b87214c6 100644 --- a/ddtrace/contrib/__init__.py +++ b/ddtrace/contrib/__init__.py @@ -1,73 +1,3 @@ -from ddtrace._trace import trace_handlers # noqa:F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.internal.utils.importlib import func_name # noqa:F401 -from ddtrace.internal.utils.importlib import module_name # noqa:F401 -from ddtrace.internal.utils.importlib import require_modules # noqa:F401 -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ( - "aiohttp", - "asgi", - "bottle", - "celery", - "cherrypy", - "falcon", - "flask_cache", - "pylibmc", - "pyramid", - "requests", - "sqlalchemy", - "wsgi", - "trace_utils", - "internal", - ): - # following packages/modules are not deprecated and will not be removed in 3.0 - pass - elif name in ("trace_handlers", "func_name", "module_name", "require_modules"): - # the following attributes are exposed in ddtrace.contrib.__init__ and should be - # removed in v3.0 - deprecate( - ("ddtrace.contrib.%s is deprecated" % name), - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - elif name in ("aiobotocore", "httplib", "kombu", "snowflake", "sqlalchemy", "tornado", "urllib3"): - # following integrations are not enabled by default and require a unique deprecation message - deprecate( - f"ddtrace.contrib.{name} is deprecated", - message="Avoid using this package directly. " - f"Set DD_TRACE_{name.upper()}_ENABLED=true and use ``ddtrace.auto`` or the " - "``ddtrace-run`` command to enable and configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - elif name in ("redis_utils", "trace_utils_redis", "trace_utils_async"): - deprecate( - f"The ddtrace.contrib.{name} module is deprecated", - message="Import from ``ddtrace.contrib.trace_utils`` instead.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - elif name == "flask_login": - deprecate( - """The flask_login integration is deprecated and will be deleted. - We recommend customers to switch to manual instrumentation. - https://docs.datadoghq.com/security/application_security/threats/add-user-info/?tab=loginsuccess&code-lang=python#adding-business-logic-information-login-success-login-failure-any-business-logic-to-traces - """, - message="", - category=DDTraceDeprecationWarning, - ) - else: - deprecate( - f"ddtrace.contrib.{name} is deprecated", - message="Avoid using this package directly. " - f"Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to enable and configure {name}.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) +# Importing trace handlers has the side effect of registering integration level +# handlers. This is necessary to use the Core API in integrations. +from ddtrace._trace import trace_handlers as _ # noqa: F401 diff --git a/ddtrace/contrib/aiobotocore/__init__.py b/ddtrace/contrib/_aiobotocore.py similarity index 64% rename from ddtrace/contrib/aiobotocore/__init__.py rename to ddtrace/contrib/_aiobotocore.py index 5c4527d11f3..7439a24e443 100644 --- a/ddtrace/contrib/aiobotocore/__init__.py +++ b/ddtrace/contrib/_aiobotocore.py @@ -25,16 +25,3 @@ Default: ``False`` """ - - -# Required to allow users to import from `ddtrace.contrib.aiobotocore.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.aiobotocore.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aiobotocore.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/_aiohttp_jinja2.py b/ddtrace/contrib/_aiohttp_jinja2.py new file mode 100644 index 00000000000..6d6db50674e --- /dev/null +++ b/ddtrace/contrib/_aiohttp_jinja2.py @@ -0,0 +1,15 @@ +""" +The ``aiohttp_jinja2`` integration adds tracing of template rendering. + + +Enabling +~~~~~~~~ + +The integration is enabled automatically when using +:ref:`ddtrace-run` or :ref:`import ddtrace.auto`. + +Or use :func:`patch()` to manually enable the integration:: + + from ddtrace import patch + patch(aiohttp_jinja2=True) +""" diff --git a/ddtrace/contrib/aiomysql/__init__.py b/ddtrace/contrib/_aiomysql.py similarity index 68% rename from ddtrace/contrib/aiomysql/__init__.py rename to ddtrace/contrib/_aiomysql.py index 49926545da7..5b060571309 100644 --- a/ddtrace/contrib/aiomysql/__init__.py +++ b/ddtrace/contrib/_aiomysql.py @@ -35,16 +35,3 @@ cur = await conn.cursor() await cur.execute("SELECT 6*7 AS the_answer;") """ - - -# Required to allow users to import from `ddtrace.contrib.aiohttp.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.aiomysql.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aiomysql.patch import patch # noqa: F401 -from ddtrace.contrib.internal.aiomysql.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/aiopg/__init__.py b/ddtrace/contrib/_aiopg.py similarity index 59% rename from ddtrace/contrib/aiopg/__init__.py rename to ddtrace/contrib/_aiopg.py index de5dcf490e2..a419df5dbbf 100644 --- a/ddtrace/contrib/aiopg/__init__.py +++ b/ddtrace/contrib/_aiopg.py @@ -16,15 +16,3 @@ # Use a pin to specify metadata related to this connection Pin.override(db, service='postgres-users') """ - - -# Required to allow users to import from `ddtrace.contrib.aiohttp.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.aiopg.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aiopg.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/aioredis/__init__.py b/ddtrace/contrib/_aioredis.py similarity index 76% rename from ddtrace/contrib/aioredis/__init__.py rename to ddtrace/contrib/_aioredis.py index 3dd70747723..7abbd826a3c 100644 --- a/ddtrace/contrib/aioredis/__init__.py +++ b/ddtrace/contrib/_aioredis.py @@ -60,14 +60,3 @@ myaioredis = aioredis.Aioredis() Pin.override(myaioredis, service="myaioredis") """ -import warnings as _w # noqa: E402 - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - # Required to allow users to import from `ddtrace.contrib.aioredis.patch` directly - from . import patch as _ # noqa: I001,F401 - -from ddtrace.contrib.internal.aioredis.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aioredis.patch import patch # noqa: F401 -from ddtrace.contrib.internal.aioredis.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/algoliasearch/__init__.py b/ddtrace/contrib/_algoliasearch.py similarity index 55% rename from ddtrace/contrib/algoliasearch/__init__.py rename to ddtrace/contrib/_algoliasearch.py index 8c1034951e8..ebb95a7e504 100644 --- a/ddtrace/contrib/algoliasearch/__init__.py +++ b/ddtrace/contrib/_algoliasearch.py @@ -21,16 +21,3 @@ .. __: https://www.algolia.com """ - - -# Required to allow users to import from `ddtrace.contrib.algoliasearch.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.algoliasearch.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.algoliasearch.patch import patch # noqa: F401 -from ddtrace.contrib.internal.algoliasearch.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/anthropic/__init__.py b/ddtrace/contrib/_anthropic.py similarity index 85% rename from ddtrace/contrib/anthropic/__init__.py rename to ddtrace/contrib/_anthropic.py index 333123c2ac8..81e62a6083b 100644 --- a/ddtrace/contrib/anthropic/__init__.py +++ b/ddtrace/contrib/_anthropic.py @@ -81,16 +81,3 @@ Pin.override(anthropic, service="my-anthropic-service") """ # noqa: E501 - - -# Required to allow users to import from `ddtrace.contrib.anthropic.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.anthropic.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.anthropic.patch import patch # noqa: F401 -from ddtrace.contrib.internal.anthropic.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/aredis/__init__.py b/ddtrace/contrib/_aredis.py similarity index 82% rename from ddtrace/contrib/aredis/__init__.py rename to ddtrace/contrib/_aredis.py index 460734a13f9..1ffac72fa36 100644 --- a/ddtrace/contrib/aredis/__init__.py +++ b/ddtrace/contrib/_aredis.py @@ -65,15 +65,3 @@ async def example(): await client.get("my-key") """ - - -# Required to allow users to import from `ddtrace.contrib.aredis.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.aredis.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aredis.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/_asyncio.py b/ddtrace/contrib/_asyncio.py new file mode 100644 index 00000000000..ae2b608dc67 --- /dev/null +++ b/ddtrace/contrib/_asyncio.py @@ -0,0 +1,4 @@ +""" +This integration provides context management for tracing the execution flow +of concurrent execution of ``asyncio.Task``. +""" diff --git a/ddtrace/contrib/asyncpg/__init__.py b/ddtrace/contrib/_asyncpg.py similarity index 68% rename from ddtrace/contrib/asyncpg/__init__.py rename to ddtrace/contrib/_asyncpg.py index 9cd624678e8..233cde9f51c 100644 --- a/ddtrace/contrib/asyncpg/__init__.py +++ b/ddtrace/contrib/_asyncpg.py @@ -43,16 +43,3 @@ conn = asyncpg.connect("postgres://localhost:5432") Pin.override(conn, service="custom-service") """ - - -# Required to allow users to import from `ddtrace.contrib.asyncpg.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.asyncpg.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.asyncpg.patch import patch # noqa: F401 -from ddtrace.contrib.internal.asyncpg.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/avro/__init__.py b/ddtrace/contrib/_avro.py similarity index 75% rename from ddtrace/contrib/avro/__init__.py rename to ddtrace/contrib/_avro.py index 5e84b184f77..6c4927e8aaf 100644 --- a/ddtrace/contrib/avro/__init__.py +++ b/ddtrace/contrib/_avro.py @@ -15,6 +15,3 @@ ~~~~~~~~~~~~~ """ - -from ..internal.avro.patch import get_version # noqa: F401 -from ..internal.avro.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/aws_lambda/__init__.py b/ddtrace/contrib/_aws_lambda.py similarity index 84% rename from ddtrace/contrib/aws_lambda/__init__.py rename to ddtrace/contrib/_aws_lambda.py index 6cd9b97da39..76ade43c1a9 100644 --- a/ddtrace/contrib/aws_lambda/__init__.py +++ b/ddtrace/contrib/_aws_lambda.py @@ -38,7 +38,3 @@ For additional configuration refer to `Instrumenting Python Serverless Applications by Datadog `_. """ - -from ddtrace.contrib.internal.aws_lambda.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aws_lambda.patch import patch # noqa: F401 -from ddtrace.contrib.internal.aws_lambda.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/_azure_functions.py b/ddtrace/contrib/_azure_functions.py new file mode 100644 index 00000000000..8a8e5df796e --- /dev/null +++ b/ddtrace/contrib/_azure_functions.py @@ -0,0 +1,25 @@ +""" +The azure_functions integration traces all http requests to your Azure Function app. + +Enabling +~~~~~~~~ + +Use :func:`patch()` to manually enable the integration:: + + from ddtrace import patch + patch(azure_functions=True) + + +Global Configuration +~~~~~~~~~~~~~~~~~~~~ + +.. py:data:: ddtrace.config.azure_functions["service"] + + The service name reported by default for azure_functions instances. + + This option can also be set with the ``DD_SERVICE`` environment + variable. + + Default: ``"azure_functions"`` + +""" diff --git a/ddtrace/contrib/boto/__init__.py b/ddtrace/contrib/_boto.py similarity index 65% rename from ddtrace/contrib/boto/__init__.py rename to ddtrace/contrib/_boto.py index 955c1bd0f2a..21965c2e161 100644 --- a/ddtrace/contrib/boto/__init__.py +++ b/ddtrace/contrib/_boto.py @@ -27,15 +27,3 @@ Default: ``False`` """ - - -# Required to allow users to import from `ddtrace.contrib.boto.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.boto.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.boto.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/botocore/__init__.py b/ddtrace/contrib/_botocore.py similarity index 91% rename from ddtrace/contrib/botocore/__init__.py rename to ddtrace/contrib/_botocore.py index 6662b43e599..2c1afc2c47a 100644 --- a/ddtrace/contrib/botocore/__init__.py +++ b/ddtrace/contrib/_botocore.py @@ -151,16 +151,3 @@ Default: ``True`` """ - - -# Required to allow users to import from `ddtrace.contrib.botocore.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.botocore.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.botocore.patch import patch # noqa: F401 -from ddtrace.contrib.internal.botocore.patch import patch_submodules # noqa: F401 diff --git a/ddtrace/contrib/cassandra/__init__.py b/ddtrace/contrib/_cassandra.py similarity index 69% rename from ddtrace/contrib/cassandra/__init__.py rename to ddtrace/contrib/_cassandra.py index 5b2247156d6..d0de07f8f16 100644 --- a/ddtrace/contrib/cassandra/__init__.py +++ b/ddtrace/contrib/_cassandra.py @@ -22,16 +22,3 @@ session = cluster.connect("my_keyspace") session.execute("select id from my_table limit 10;") """ - - -# Required to allow users to import from `ddtrace.contrib.cassandra.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.cassandra.patch import patch # noqa: F401 -from ddtrace.contrib.internal.cassandra.session import get_version # noqa: F401 diff --git a/ddtrace/contrib/consul/__init__.py b/ddtrace/contrib/_consul.py similarity index 56% rename from ddtrace/contrib/consul/__init__.py rename to ddtrace/contrib/_consul.py index d0a6a064683..fa159309411 100644 --- a/ddtrace/contrib/consul/__init__.py +++ b/ddtrace/contrib/_consul.py @@ -19,17 +19,3 @@ # Use a pin to specify metadata related to this client Pin.override(client, service='consul-kv') """ - - -# Required to allow users to import from `ddtrace.contrib.consul.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.consul.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.consul.patch import patch # noqa: F401 -from ddtrace.contrib.internal.consul.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/_coverage.py b/ddtrace/contrib/_coverage.py new file mode 100644 index 00000000000..c597acab1da --- /dev/null +++ b/ddtrace/contrib/_coverage.py @@ -0,0 +1,17 @@ +""" +The Coverage.py integration traces test code coverage when using `pytest` or `unittest`. + + +Enabling +~~~~~~~~ + +The Coverage.py integration is enabled automatically when using +:ref:`ddtrace-run` or :ref:`import ddtrace.auto`. + +Alternately, use :func:`patch()` to manually enable the integration:: + + from ddtrace import patch + patch(coverage=True) + +Note: Coverage.py instrumentation is only enabled if `pytest` or `unittest` instrumentation is enabled. +""" diff --git a/ddtrace/contrib/django/__init__.py b/ddtrace/contrib/_django.py similarity index 91% rename from ddtrace/contrib/django/__init__.py rename to ddtrace/contrib/_django.py index c1ab65d494d..afde135c47c 100644 --- a/ddtrace/contrib/django/__init__.py +++ b/ddtrace/contrib/_django.py @@ -200,18 +200,3 @@ .. __: https://www.djangoproject.com/ """ # noqa: E501 - - -# Required to allow users to import from `ddtrace.contrib.django.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.django.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.django.patch import patch # noqa: F401 -from ddtrace.contrib.internal.django.patch import patch as _patch # noqa: F401 -from ddtrace.contrib.internal.django.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/dogpile_cache/__init__.py b/ddtrace/contrib/_dogpile_cache.py similarity index 73% rename from ddtrace/contrib/dogpile_cache/__init__.py rename to ddtrace/contrib/_dogpile_cache.py index c1b4f1b58ed..166a00a4aef 100644 --- a/ddtrace/contrib/dogpile_cache/__init__.py +++ b/ddtrace/contrib/_dogpile_cache.py @@ -36,17 +36,3 @@ def hello(name): .. __: https://dogpilecache.sqlalchemy.org/ """ - - -# Required to allow users to import from `ddtrace.contrib.dogpile_cache.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.dogpile_cache.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.dogpile_cache.patch import patch # noqa: F401 -from ddtrace.contrib.internal.dogpile_cache.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/dramatiq/__init__.py b/ddtrace/contrib/_dramatiq.py similarity index 61% rename from ddtrace/contrib/dramatiq/__init__.py rename to ddtrace/contrib/_dramatiq.py index 2d135ba2966..e6a0f82e5b3 100644 --- a/ddtrace/contrib/dramatiq/__init__.py +++ b/ddtrace/contrib/_dramatiq.py @@ -28,17 +28,3 @@ def my_other_task(content): ddtrace-run python app.py """ - - -# Required to allow users to import from `ddtrace.contrib.dramatiq.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.dramatiq.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.dramatiq.patch import patch # noqa: F401 -from ddtrace.contrib.internal.dramatiq.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/elasticsearch/__init__.py b/ddtrace/contrib/_elasticsearch.py similarity index 85% rename from ddtrace/contrib/elasticsearch/__init__.py rename to ddtrace/contrib/_elasticsearch.py index b0be91a11da..8462195af81 100644 --- a/ddtrace/contrib/elasticsearch/__init__.py +++ b/ddtrace/contrib/_elasticsearch.py @@ -49,6 +49,3 @@ # Override service name config.elasticsearch['service'] = 'custom-service-name' """ -from ddtrace.contrib.internal.elasticsearch.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.elasticsearch.patch import get_versions # noqa: F401 -from ddtrace.contrib.internal.elasticsearch.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/fastapi/__init__.py b/ddtrace/contrib/_fastapi.py similarity index 74% rename from ddtrace/contrib/fastapi/__init__.py rename to ddtrace/contrib/_fastapi.py index 726a308f14d..4af18192044 100644 --- a/ddtrace/contrib/fastapi/__init__.py +++ b/ddtrace/contrib/_fastapi.py @@ -50,17 +50,3 @@ config.fastapi['request_span_name'] = 'custom-request-span-name' """ - - -# Required to allow users to import from `ddtrace.contrib.fastapi.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.fastapi.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.fastapi.patch import patch # noqa: F401 -from ddtrace.contrib.internal.fastapi.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/flask/__init__.py b/ddtrace/contrib/_flask.py similarity index 83% rename from ddtrace/contrib/flask/__init__.py rename to ddtrace/contrib/_flask.py index 4b3c1afbf16..85233fbba08 100644 --- a/ddtrace/contrib/flask/__init__.py +++ b/ddtrace/contrib/_flask.py @@ -92,15 +92,3 @@ def index(): :ref:`All HTTP tags ` are supported for this integration. """ - - -# DEV: We do this so we can `@mock.patch('ddtrace.contrib.flask._patch.')` in tests -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 -from ddtrace.contrib.internal.flask.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.flask.patch import patch # noqa: F401 -from ddtrace.contrib.internal.flask.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/freezegun/__init__.py b/ddtrace/contrib/_freezegun.py similarity index 69% rename from ddtrace/contrib/freezegun/__init__.py rename to ddtrace/contrib/_freezegun.py index 2b643662c1d..d9f48ded072 100644 --- a/ddtrace/contrib/freezegun/__init__.py +++ b/ddtrace/contrib/_freezegun.py @@ -12,8 +12,3 @@ ~~~~~~~~~~~~~ The freezegun integration is not configurable, but may be disabled using DD_PATCH_MODULES=freezegun:false . """ - - -from ..internal.freezegun.patch import get_version # noqa: F401 -from ..internal.freezegun.patch import patch # noqa: F401 -from ..internal.freezegun.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/futures/__init__.py b/ddtrace/contrib/_futures.py similarity index 56% rename from ddtrace/contrib/futures/__init__.py rename to ddtrace/contrib/_futures.py index 3ac420b2263..1005423acad 100644 --- a/ddtrace/contrib/futures/__init__.py +++ b/ddtrace/contrib/_futures.py @@ -16,17 +16,3 @@ from ddtrace import patch patch(futures=True) """ - - -# Required to allow users to import from `ddtrace.contrib.futures.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.futures.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.futures.patch import patch # noqa: F401 -from ddtrace.contrib.internal.futures.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/gevent/__init__.py b/ddtrace/contrib/_gevent.py similarity index 63% rename from ddtrace/contrib/gevent/__init__.py rename to ddtrace/contrib/_gevent.py index d02588efad9..9fa3ed4add1 100644 --- a/ddtrace/contrib/gevent/__init__.py +++ b/ddtrace/contrib/_gevent.py @@ -36,23 +36,3 @@ def worker_function(): with tracer.trace("greenlet.child_call") as child: ... """ - -# Required to allow users to import from `ddtrace.contrib.gevent.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace._trace.provider import DefaultContextProvider as _DefaultContextProvider -from ddtrace.contrib.internal.gevent.patch import get_version #noqa: F401 -from ddtrace.contrib.internal.gevent.patch import patch #noqa: F401 -from ddtrace.contrib.internal.gevent.patch import unpatch #noqa: F401 - - -context_provider = _DefaultContextProvider() - - - diff --git a/ddtrace/contrib/google_generativeai/__init__.py b/ddtrace/contrib/_google_generativeai.py similarity index 92% rename from ddtrace/contrib/google_generativeai/__init__.py rename to ddtrace/contrib/_google_generativeai.py index 45333c58173..963b80e7494 100644 --- a/ddtrace/contrib/google_generativeai/__init__.py +++ b/ddtrace/contrib/_google_generativeai.py @@ -78,7 +78,3 @@ Pin.override(genai, service="my-gemini-service") """ # noqa: E501 - -from ..internal.google_generativeai.patch import get_version # noqa: F401 -from ..internal.google_generativeai.patch import patch # noqa: F401 -from ..internal.google_generativeai.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/graphql/__init__.py b/ddtrace/contrib/_graphql.py similarity index 71% rename from ddtrace/contrib/graphql/__init__.py rename to ddtrace/contrib/_graphql.py index f12880efda1..d4d8d769d61 100644 --- a/ddtrace/contrib/graphql/__init__.py +++ b/ddtrace/contrib/_graphql.py @@ -44,17 +44,3 @@ Pin.override(graphql, service="mygraphql") """ - - -# Required to allow users to import from `ddtrace.contrib.graphql.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.graphql.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.graphql.patch import patch # noqa: F401 -from ddtrace.contrib.internal.graphql.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/grpc/__init__.py b/ddtrace/contrib/_grpc.py similarity index 80% rename from ddtrace/contrib/grpc/__init__.py rename to ddtrace/contrib/_grpc.py index ea2db0b4ac3..5713b6779ad 100644 --- a/ddtrace/contrib/grpc/__init__.py +++ b/ddtrace/contrib/_grpc.py @@ -74,17 +74,3 @@ add_MyServicer_to_server(MyServicer(), server) server.start() """ - - -# Required to allow users to import from `ddtrace.contrib.grpc.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.grpc.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.grpc.patch import patch # noqa: F401 -from ddtrace.contrib.internal.grpc.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/gunicorn/__init__.py b/ddtrace/contrib/_gunicorn.py similarity index 74% rename from ddtrace/contrib/gunicorn/__init__.py rename to ddtrace/contrib/_gunicorn.py index d098a3fe1bc..7fd31fd296f 100644 --- a/ddtrace/contrib/gunicorn/__init__.py +++ b/ddtrace/contrib/_gunicorn.py @@ -7,16 +7,3 @@ possible in your application's lifecycle. Do not use ``ddtrace-run`` with ``import ddtrace.auto``. """ - - -def get_version(): - # type: () -> str - return "" - - -def patch(): - pass - - -def unpatch(): - pass diff --git a/ddtrace/contrib/httplib/__init__.py b/ddtrace/contrib/_httplib.py similarity index 76% rename from ddtrace/contrib/httplib/__init__.py rename to ddtrace/contrib/_httplib.py index 7c5247422a1..30b170000e2 100644 --- a/ddtrace/contrib/httplib/__init__.py +++ b/ddtrace/contrib/_httplib.py @@ -46,15 +46,3 @@ :ref:`Headers tracing ` is supported for this integration. """ - - -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: I001,F401 - -from ddtrace.contrib.internal.httplib.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.httplib.patch import patch # noqa: F401 -from ddtrace.contrib.internal.httplib.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/httpx/__init__.py b/ddtrace/contrib/_httpx.py similarity index 83% rename from ddtrace/contrib/httpx/__init__.py rename to ddtrace/contrib/_httpx.py index 39b191ad139..3d8087fbba1 100644 --- a/ddtrace/contrib/httpx/__init__.py +++ b/ddtrace/contrib/_httpx.py @@ -77,17 +77,3 @@ .. __: https://www.python-httpx.org/ """ - - -# Required to allow users to import from `ddtrace.contrib.httpx.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.httpx.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.httpx.patch import patch # noqa: F401 -from ddtrace.contrib.internal.httpx.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/jinja2/__init__.py b/ddtrace/contrib/_jinja2.py similarity index 67% rename from ddtrace/contrib/jinja2/__init__.py rename to ddtrace/contrib/_jinja2.py index 8437a51d9de..94683ebe5c3 100644 --- a/ddtrace/contrib/jinja2/__init__.py +++ b/ddtrace/contrib/_jinja2.py @@ -27,16 +27,3 @@ By default, the service name is set to None, so it is inherited from the parent span. If there is no parent span and the service name is not overridden the agent will drop the traces. """ - -# Required to allow users to import from `ddtrace.contrib.jinja2.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.jinja2.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.jinja2.patch import patch # noqa: F401 -from ddtrace.contrib.internal.jinja2.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/kafka/__init__.py b/ddtrace/contrib/_kafka.py similarity index 69% rename from ddtrace/contrib/kafka/__init__.py rename to ddtrace/contrib/_kafka.py index de857bcb040..fa7d280ea6c 100644 --- a/ddtrace/contrib/kafka/__init__.py +++ b/ddtrace/contrib/_kafka.py @@ -41,17 +41,3 @@ Pin.override(confluent_kafka, service="custom-service-name") """ - - -# Required to allow users to import from `ddtrace.contrib.kafka.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.kafka.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.kafka.patch import patch # noqa: F401 -from ddtrace.contrib.internal.kafka.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/kombu/__init__.py b/ddtrace/contrib/_kombu.py similarity index 68% rename from ddtrace/contrib/kombu/__init__.py rename to ddtrace/contrib/_kombu.py index 1c853adbd3f..85afbe827e4 100644 --- a/ddtrace/contrib/kombu/__init__.py +++ b/ddtrace/contrib/_kombu.py @@ -32,19 +32,3 @@ # Use a pin to specify metadata related to this client Pin.override(producer, service='kombu-consumer') """ -from ddtrace.internal.utils.importlib import require_modules - - -required_modules = ["kombu", "kombu.messaging"] - -with require_modules(required_modules) as missing_modules: - if not missing_modules: - # Required to allow users to import from `ddtrace.contrib.kombu.patch` directly - import warnings as _w - - with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - from ddtrace.contrib.internal.kombu.patch import get_version # noqa: F401 - from ddtrace.contrib.internal.kombu.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/langchain/__init__.py b/ddtrace/contrib/_langchain.py similarity index 93% rename from ddtrace/contrib/langchain/__init__.py rename to ddtrace/contrib/_langchain.py index 1aa04d7a516..d36cd76f3f1 100644 --- a/ddtrace/contrib/langchain/__init__.py +++ b/ddtrace/contrib/_langchain.py @@ -206,16 +206,3 @@ Default: ``0.1`` """ # noqa: E501 - -# Required to allow users to import from `ddtrace.contrib.langchain.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.langchain.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.langchain.patch import patch # noqa: F401 -from ddtrace.contrib.internal.langchain.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/_langgraph.py b/ddtrace/contrib/_langgraph.py new file mode 100644 index 00000000000..d5e62d952ce --- /dev/null +++ b/ddtrace/contrib/_langgraph.py @@ -0,0 +1,4 @@ +""" +The LangGraph integration instruments the LangGraph Python library to emit metrics, +traces, and logs. +""" diff --git a/ddtrace/contrib/logbook/__init__.py b/ddtrace/contrib/_logbook.py similarity index 83% rename from ddtrace/contrib/logbook/__init__.py rename to ddtrace/contrib/_logbook.py index e2a8f244820..dafe8873372 100644 --- a/ddtrace/contrib/logbook/__init__.py +++ b/ddtrace/contrib/_logbook.py @@ -47,17 +47,3 @@ For more information, please see the attached guide for the Datadog Logging Product: https://docs.datadoghq.com/logs/log_collection/python/ """ - - -# Required to allow users to import from `ddtrace.contrib.logbook.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.logbook.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.logbook.patch import patch # noqa: F401 -from ddtrace.contrib.internal.logbook.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/logging/__init__.py b/ddtrace/contrib/_logging.py similarity index 79% rename from ddtrace/contrib/logging/__init__.py rename to ddtrace/contrib/_logging.py index 9dcb3befe8c..f2997f362f7 100644 --- a/ddtrace/contrib/logging/__init__.py +++ b/ddtrace/contrib/_logging.py @@ -60,17 +60,3 @@ def hello(): For more information, please see the attached guide on common timestamp issues: https://docs.datadoghq.com/logs/guide/logs-not-showing-expected-timestamp/ """ - - -# Required to allow users to import from `ddtrace.contrib.logging.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.logging.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.logging.patch import patch # noqa: F401 -from ddtrace.contrib.internal.logging.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/loguru/__init__.py b/ddtrace/contrib/_loguru.py similarity index 83% rename from ddtrace/contrib/loguru/__init__.py rename to ddtrace/contrib/_loguru.py index 9501fadd703..f0ad96f77fc 100644 --- a/ddtrace/contrib/loguru/__init__.py +++ b/ddtrace/contrib/_loguru.py @@ -62,17 +62,3 @@ def log_format(record): For more information, please see the attached guide for the Datadog Logging Product: https://docs.datadoghq.com/logs/log_collection/python/ """ - - -# Required to allow users to import from `ddtrace.contrib.loguru.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.loguru.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.loguru.patch import patch # noqa: F401 -from ddtrace.contrib.internal.loguru.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/mako/__init__.py b/ddtrace/contrib/_mako.py similarity index 53% rename from ddtrace/contrib/mako/__init__.py rename to ddtrace/contrib/_mako.py index 5de3f87f6c5..d16b74c4d66 100644 --- a/ddtrace/contrib/mako/__init__.py +++ b/ddtrace/contrib/_mako.py @@ -9,12 +9,3 @@ t = Template(filename="index.html") """ - - -# Required to allow users to import from `ddtrace.contrib.mako.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 diff --git a/ddtrace/contrib/mariadb/__init__.py b/ddtrace/contrib/_mariadb.py similarity index 75% rename from ddtrace/contrib/mariadb/__init__.py rename to ddtrace/contrib/_mariadb.py index 8329fca2b63..1ef08422a00 100644 --- a/ddtrace/contrib/mariadb/__init__.py +++ b/ddtrace/contrib/_mariadb.py @@ -52,17 +52,3 @@ cursor.execute("SELECT 6*7 AS the_answer;") """ - - -# Required to allow users to import from `ddtrace.contrib.mariadb.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.mariadb.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.mariadb.patch import patch # noqa: F401 -from ddtrace.contrib.internal.mariadb.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/molten/__init__.py b/ddtrace/contrib/_molten.py similarity index 66% rename from ddtrace/contrib/molten/__init__.py rename to ddtrace/contrib/_molten.py index 44ef08de9bb..67a616142b8 100644 --- a/ddtrace/contrib/molten/__init__.py +++ b/ddtrace/contrib/_molten.py @@ -34,17 +34,3 @@ def hello(name: str, age: int) -> str: :ref:`All HTTP tags ` are supported for this integration. """ - - -# Required to allow users to import from `ddtrace.contrib.molten.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.molten.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.molten.patch import patch # noqa: F401 -from ddtrace.contrib.internal.molten.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/mongoengine/__init__.py b/ddtrace/contrib/_mongoengine.py similarity index 61% rename from ddtrace/contrib/mongoengine/__init__.py rename to ddtrace/contrib/_mongoengine.py index 793d9cf4322..a72c861f4b7 100644 --- a/ddtrace/contrib/mongoengine/__init__.py +++ b/ddtrace/contrib/_mongoengine.py @@ -17,16 +17,3 @@ client = mongoengine.connect('db', alias='master') Pin.override(client, service="mongo-master") """ - - -# Required to allow users to import from `ddtrace.contrib.mongoengine.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.mongoengine.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.mongoengine.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/mysql/__init__.py b/ddtrace/contrib/_mysql.py similarity index 80% rename from ddtrace/contrib/mysql/__init__.py rename to ddtrace/contrib/_mysql.py index 60a4d638f78..3336839bcf5 100644 --- a/ddtrace/contrib/mysql/__init__.py +++ b/ddtrace/contrib/_mysql.py @@ -62,19 +62,3 @@ Help on mysql.connector can be found on: https://dev.mysql.com/doc/connector-python/en/ """ - - -# check `mysql-connector` availability - - -# Required to allow users to import from `ddtrace.contrib.mysql.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.mysql.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.mysql.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/mysqldb/__init__.py b/ddtrace/contrib/_mysqldb.py similarity index 84% rename from ddtrace/contrib/mysqldb/__init__.py rename to ddtrace/contrib/_mysqldb.py index 7649807e623..46a5e27de7b 100644 --- a/ddtrace/contrib/mysqldb/__init__.py +++ b/ddtrace/contrib/_mysqldb.py @@ -75,15 +75,3 @@ https://mysqlclient.readthedocs.io/ """ - - -# Required to allow users to import from `ddtrace.contrib.mysqldb.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.mysqldb.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.mysqldb.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/openai/__init__.py b/ddtrace/contrib/_openai.py similarity index 94% rename from ddtrace/contrib/openai/__init__.py rename to ddtrace/contrib/_openai.py index da94047c2e8..8e2eb87aeb5 100644 --- a/ddtrace/contrib/openai/__init__.py +++ b/ddtrace/contrib/_openai.py @@ -247,16 +247,3 @@ Pin.override(openai, service="my-openai-service") """ # noqa: E501 - -# Required to allow users to import from `ddtrace.contrib.openai.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.openai.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.openai.patch import patch # noqa: F401 -from ddtrace.contrib.internal.openai.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/protobuf/__init__.py b/ddtrace/contrib/_protobuf.py similarity index 67% rename from ddtrace/contrib/protobuf/__init__.py rename to ddtrace/contrib/_protobuf.py index 41f0c76d101..8dfe99461d2 100644 --- a/ddtrace/contrib/protobuf/__init__.py +++ b/ddtrace/contrib/_protobuf.py @@ -15,6 +15,3 @@ ~~~~~~~~~~~~~ """ -from ..internal.protobuf.patch import get_version # noqa: F401 -from ..internal.protobuf.patch import patch # noqa: F401 -from ..internal.protobuf.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/psycopg/__init__.py b/ddtrace/contrib/_psycopg.py similarity index 79% rename from ddtrace/contrib/psycopg/__init__.py rename to ddtrace/contrib/_psycopg.py index 22baf6ef522..0c1e134bb15 100644 --- a/ddtrace/contrib/psycopg/__init__.py +++ b/ddtrace/contrib/_psycopg.py @@ -60,14 +60,3 @@ cursor = db.cursor() cursor.execute("select * from users where id = 1") """ -# Required to allow users to import from `ddtrace.contrib.psycopg.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.psycopg.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.psycopg.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/pymemcache/__init__.py b/ddtrace/contrib/_pymemcache.py similarity index 70% rename from ddtrace/contrib/pymemcache/__init__.py rename to ddtrace/contrib/_pymemcache.py index ef2e7b3ee82..066bb5653e6 100644 --- a/ddtrace/contrib/pymemcache/__init__.py +++ b/ddtrace/contrib/_pymemcache.py @@ -31,16 +31,3 @@ Pymemcache ``HashClient`` will also be indirectly patched as it uses ``Client`` under the hood. """ - - -# Required to allow users to import from `ddtrace.contrib.pymemcache.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.pymemcache.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pymemcache.patch import patch # noqa: F401 -from ddtrace.contrib.internal.pymemcache.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/pymongo/__init__.py b/ddtrace/contrib/_pymongo.py similarity index 76% rename from ddtrace/contrib/pymongo/__init__.py rename to ddtrace/contrib/_pymongo.py index 9f030de942b..f1210f0047d 100644 --- a/ddtrace/contrib/pymongo/__init__.py +++ b/ddtrace/contrib/_pymongo.py @@ -36,16 +36,3 @@ Default: ``"pymongo"`` """ - - -# Required to allow users to import from `ddtrace.contrib.pymongo.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.pymongo.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pymongo.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/pymysql/__init__.py b/ddtrace/contrib/_pymysql.py similarity index 78% rename from ddtrace/contrib/pymysql/__init__.py rename to ddtrace/contrib/_pymysql.py index b999934f285..d219e46eccd 100644 --- a/ddtrace/contrib/pymysql/__init__.py +++ b/ddtrace/contrib/_pymysql.py @@ -54,16 +54,3 @@ cursor = conn.cursor() cursor.execute("SELECT 6*7 AS the_answer;") """ - - -# Required to allow users to import from `ddtrace.contrib.pymysql.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.pymysql.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pymysql.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/pynamodb/__init__.py b/ddtrace/contrib/_pynamodb.py similarity index 64% rename from ddtrace/contrib/pynamodb/__init__.py rename to ddtrace/contrib/_pynamodb.py index 1362429219f..9ac94a291b6 100644 --- a/ddtrace/contrib/pynamodb/__init__.py +++ b/ddtrace/contrib/_pynamodb.py @@ -27,16 +27,3 @@ Default: ``"pynamodb"`` """ - - -# Required to allow users to import from `ddtrace.contrib.pynamodb.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.pynamodb.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pynamodb.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/pyodbc/__init__.py b/ddtrace/contrib/_pyodbc.py similarity index 77% rename from ddtrace/contrib/pyodbc/__init__.py rename to ddtrace/contrib/_pyodbc.py index 0a9bfa60fab..0a2d46d5e70 100644 --- a/ddtrace/contrib/pyodbc/__init__.py +++ b/ddtrace/contrib/_pyodbc.py @@ -53,16 +53,3 @@ cursor = db.cursor() cursor.execute("select * from users where id = 1") """ - - -# Required to allow users to import from `ddtrace.contrib.pyodbc.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.pyodbc.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pyodbc.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/pytest/__init__.py b/ddtrace/contrib/_pytest.py similarity index 95% rename from ddtrace/contrib/pytest/__init__.py rename to ddtrace/contrib/_pytest.py index 31533b05e2b..322685b0a6e 100644 --- a/ddtrace/contrib/pytest/__init__.py +++ b/ddtrace/contrib/_pytest.py @@ -60,4 +60,3 @@ Default: ``"pytest.test"`` """ -from ddtrace.contrib.internal.pytest.patch import get_version # noqa: F401 diff --git a/ddtrace/contrib/pytest_bdd/__init__.py b/ddtrace/contrib/_pytest_bdd.py similarity index 89% rename from ddtrace/contrib/pytest_bdd/__init__.py rename to ddtrace/contrib/_pytest_bdd.py index 62846aea395..5c1ff0be9ae 100644 --- a/ddtrace/contrib/pytest_bdd/__init__.py +++ b/ddtrace/contrib/_pytest_bdd.py @@ -21,4 +21,3 @@ for more details. """ -from ddtrace.contrib.internal.pytest_bdd.patch import get_version # noqa: F401 diff --git a/ddtrace/contrib/_pytest_benchmark.py b/ddtrace/contrib/_pytest_benchmark.py new file mode 100644 index 00000000000..6f7df090942 --- /dev/null +++ b/ddtrace/contrib/_pytest_benchmark.py @@ -0,0 +1,3 @@ +""" +The pytest-benchmark integration traces executions of pytest benchmarks. +""" diff --git a/ddtrace/contrib/redis/__init__.py b/ddtrace/contrib/_redis.py similarity index 81% rename from ddtrace/contrib/redis/__init__.py rename to ddtrace/contrib/_redis.py index 28280510b0c..3204fade8df 100644 --- a/ddtrace/contrib/redis/__init__.py +++ b/ddtrace/contrib/_redis.py @@ -66,16 +66,3 @@ # as the service name. client.get("my-key") """ - - -# Required to allow users to import from `ddtrace.contrib.redis.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.redis.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.redis.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/rediscluster/__init__.py b/ddtrace/contrib/_rediscluster.py similarity index 79% rename from ddtrace/contrib/rediscluster/__init__.py rename to ddtrace/contrib/_rediscluster.py index d7b0e320fac..05975277291 100644 --- a/ddtrace/contrib/rediscluster/__init__.py +++ b/ddtrace/contrib/_rediscluster.py @@ -48,16 +48,3 @@ Default: ``True`` """ - - -# Required to allow users to import from `ddtrace.contrib.rediscluster.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.rediscluster.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.rediscluster.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/rq/__init__.py b/ddtrace/contrib/_rq.py similarity index 96% rename from ddtrace/contrib/rq/__init__.py rename to ddtrace/contrib/_rq.py index 0a4d83983eb..596c0c420f6 100644 --- a/ddtrace/contrib/rq/__init__.py +++ b/ddtrace/contrib/_rq.py @@ -76,4 +76,3 @@ .. __: https://python-rq.org/ """ -from ddtrace.contrib.internal.rq.patch import * # noqa: F403 diff --git a/ddtrace/contrib/sanic/__init__.py b/ddtrace/contrib/_sanic.py similarity index 72% rename from ddtrace/contrib/sanic/__init__.py rename to ddtrace/contrib/_sanic.py index 7fab620b8fd..ad97e5af6f3 100644 --- a/ddtrace/contrib/sanic/__init__.py +++ b/ddtrace/contrib/_sanic.py @@ -55,17 +55,3 @@ def index(request): .. __: https://sanic.readthedocs.io/en/latest/ """ - - -# Required to allow users to import from `ddtrace.contrib.sanic.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.sanic.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.sanic.patch import patch # noqa: F401 -from ddtrace.contrib.internal.sanic.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/selenium/__init__.py b/ddtrace/contrib/_selenium.py similarity index 78% rename from ddtrace/contrib/selenium/__init__.py rename to ddtrace/contrib/_selenium.py index 411fd47f7ee..83252ef39fa 100644 --- a/ddtrace/contrib/selenium/__init__.py +++ b/ddtrace/contrib/_selenium.py @@ -22,7 +22,3 @@ DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS: The time in milliseconds to wait after flushing the RUM session. """ - -from ..internal.selenium.patch import get_version # noqa: F401 -from ..internal.selenium.patch import patch # noqa: F401 -from ..internal.selenium.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/snowflake/__init__.py b/ddtrace/contrib/_snowflake.py similarity index 78% rename from ddtrace/contrib/snowflake/__init__.py rename to ddtrace/contrib/_snowflake.py index 3bf4e42d5a5..ea582b9208f 100644 --- a/ddtrace/contrib/snowflake/__init__.py +++ b/ddtrace/contrib/_snowflake.py @@ -64,17 +64,3 @@ cursor = conn.cursor() cursor.execute("SELECT current_version()") """ - - -# Required to allow users to import from `ddtrace.contrib.snowflake.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.snowflake.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.snowflake.patch import patch # noqa: F401 -from ddtrace.contrib.internal.snowflake.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/sqlite3/__init__.py b/ddtrace/contrib/_sqlite3.py similarity index 77% rename from ddtrace/contrib/sqlite3/__init__.py rename to ddtrace/contrib/_sqlite3.py index 3be49e96642..351d639b182 100644 --- a/ddtrace/contrib/sqlite3/__init__.py +++ b/ddtrace/contrib/_sqlite3.py @@ -53,16 +53,3 @@ cursor = db.cursor() cursor.execute("select * from users where id = 1") """ - - -# Required to allow users to import from `ddtrace.contrib.sqlite3.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.sqlite3.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.sqlite3.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/starlette/__init__.py b/ddtrace/contrib/_starlette.py similarity index 75% rename from ddtrace/contrib/starlette/__init__.py rename to ddtrace/contrib/_starlette.py index 2fe121ef976..a99997698e7 100644 --- a/ddtrace/contrib/starlette/__init__.py +++ b/ddtrace/contrib/_starlette.py @@ -57,17 +57,3 @@ config.starlette['request_span_name'] = 'custom-request-span-name' """ - - -# Required to allow users to import from `ddtrace.contrib.starlette.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.starlette.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.starlette.patch import patch # noqa: F401 -from ddtrace.contrib.internal.starlette.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/structlog/__init__.py b/ddtrace/contrib/_structlog.py similarity index 74% rename from ddtrace/contrib/structlog/__init__.py rename to ddtrace/contrib/_structlog.py index 77770bb3da5..362052eae3f 100644 --- a/ddtrace/contrib/structlog/__init__.py +++ b/ddtrace/contrib/_structlog.py @@ -37,17 +37,3 @@ For more information, please see the attached guide for the Datadog Logging Product: https://docs.datadoghq.com/logs/log_collection/python/ """ - - -# Required to allow users to import from `ddtrace.contrib.structlog.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.structlog.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.structlog.patch import patch # noqa: F401 -from ddtrace.contrib.internal.structlog.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/subprocess/__init__.py b/ddtrace/contrib/_subprocess.py similarity index 58% rename from ddtrace/contrib/subprocess/__init__.py rename to ddtrace/contrib/_subprocess.py index 8e95b25b646..b73c72167bf 100644 --- a/ddtrace/contrib/subprocess/__init__.py +++ b/ddtrace/contrib/_subprocess.py @@ -18,17 +18,3 @@ enabled in this integration that you can check on ```ddtrace.contrib.subprocess.constants.SENSITIVE_WORDS_WILDCARDS```. """ - - -# Required to allow users to import from `ddtrace.contrib.subprocess.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.subprocess.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.subprocess.patch import patch # noqa: F401 -from ddtrace.contrib.internal.subprocess.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/unittest/__init__.py b/ddtrace/contrib/_unittest.py similarity index 83% rename from ddtrace/contrib/unittest/__init__.py rename to ddtrace/contrib/_unittest.py index 173d22cac50..67afb7d5166 100644 --- a/ddtrace/contrib/unittest/__init__.py +++ b/ddtrace/contrib/_unittest.py @@ -34,6 +34,3 @@ Default: ``True`` """ -from ..internal.unittest.patch import get_version # noqa: F401 -from ..internal.unittest.patch import patch # noqa: F401 -from ..internal.unittest.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/_urllib.py b/ddtrace/contrib/_urllib.py new file mode 100644 index 00000000000..76fd2662d80 --- /dev/null +++ b/ddtrace/contrib/_urllib.py @@ -0,0 +1,6 @@ +""" +Trace the standard library ``urllib.request`` library to trace +HTTP requests and detect SSRF vulnerabilities. It is enabled by default +if ``DD_IAST_ENABLED`` is set to ``True`` (for detecting sink points) and/or +``DD_ASM_ENABLED`` is set to ``True`` (for exploit prevention). +""" diff --git a/ddtrace/contrib/urllib3/__init__.py b/ddtrace/contrib/_urllib3.py similarity index 73% rename from ddtrace/contrib/urllib3/__init__.py rename to ddtrace/contrib/_urllib3.py index e0cec320abd..6813ccde8ce 100644 --- a/ddtrace/contrib/urllib3/__init__.py +++ b/ddtrace/contrib/_urllib3.py @@ -50,17 +50,3 @@ Default: ``False`` """ - - -# Required to allow users to import from `ddtrace.contrib.urllib3.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.urllib3.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.urllib3.patch import patch # noqa: F401 -from ddtrace.contrib.internal.urllib3.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/vertexai/__init__.py b/ddtrace/contrib/_vertexai.py similarity index 92% rename from ddtrace/contrib/vertexai/__init__.py rename to ddtrace/contrib/_vertexai.py index 5a372a9bd52..25e5fdc081b 100644 --- a/ddtrace/contrib/vertexai/__init__.py +++ b/ddtrace/contrib/_vertexai.py @@ -82,8 +82,3 @@ Pin.override(vertexai, service="my-vertexai-service") """ # noqa: E501 - - -from ddtrace.contrib.internal.vertexai.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.vertexai.patch import patch # noqa: F401 -from ddtrace.contrib.internal.vertexai.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/vertica/__init__.py b/ddtrace/contrib/_vertica.py similarity index 69% rename from ddtrace/contrib/vertica/__init__.py rename to ddtrace/contrib/_vertica.py index 2bcc2c3d987..df997f5946b 100644 --- a/ddtrace/contrib/vertica/__init__.py +++ b/ddtrace/contrib/_vertica.py @@ -38,17 +38,3 @@ # override the service Pin.override(conn, service='myverticaservice') """ - - -# Required to allow users to import from `ddtrace.contrib.vertica.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.vertica.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.vertica.patch import patch # noqa: F401 -from ddtrace.contrib.internal.vertica.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/_webbrowser.py b/ddtrace/contrib/_webbrowser.py new file mode 100644 index 00000000000..107d0bd7179 --- /dev/null +++ b/ddtrace/contrib/_webbrowser.py @@ -0,0 +1,6 @@ +""" +Trace the standard library ``webbrowser`` library to trace +HTTP requests and detect SSRF vulnerabilities. It is enabled by default +if ``DD_IAST_ENABLED`` is set to ``True`` (for detecting sink points) and/or +``DD_ASM_ENABLED`` is set to ``True`` (for exploit prevention). +""" diff --git a/ddtrace/contrib/yaaredis/__init__.py b/ddtrace/contrib/_yaaredis.py similarity index 81% rename from ddtrace/contrib/yaaredis/__init__.py rename to ddtrace/contrib/_yaaredis.py index 66aa7cc5e6e..65917b03c29 100644 --- a/ddtrace/contrib/yaaredis/__init__.py +++ b/ddtrace/contrib/_yaaredis.py @@ -65,16 +65,3 @@ async def example(): await client.get("my-key") """ - - -# Required to allow users to import from `ddtrace.contrib.yaaredis.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.yaaredis.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.yaaredis.patch import patch # noqa: F401 diff --git a/ddtrace/contrib/aiobotocore/patch.py b/ddtrace/contrib/aiobotocore/patch.py deleted file mode 100644 index 720b5b837de..00000000000 --- a/ddtrace/contrib/aiobotocore/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiobotocore.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aiohttp/__init__.py b/ddtrace/contrib/aiohttp.py similarity index 72% rename from ddtrace/contrib/aiohttp/__init__.py rename to ddtrace/contrib/aiohttp.py index 2bb498bdf9c..dbb5def90d1 100644 --- a/ddtrace/contrib/aiohttp/__init__.py +++ b/ddtrace/contrib/aiohttp.py @@ -84,35 +84,7 @@ async def home_handler(request): :ref:`All HTTP tags ` are supported for this integration. """ - - -# Required to allow users to import from `ddtrace.contrib.aiohttp.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 from ddtrace.contrib.internal.aiohttp.middlewares import trace_app -from ddtrace.contrib.internal.aiohttp.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aiohttp.patch import patch # noqa: F401 -from ddtrace.contrib.internal.aiohttp.patch import unpatch # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "get_version", "unpatch"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["trace_app"] diff --git a/ddtrace/contrib/aiohttp/middlewares.py b/ddtrace/contrib/aiohttp/middlewares.py deleted file mode 100644 index 0a9dfcc746a..00000000000 --- a/ddtrace/contrib/aiohttp/middlewares.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiohttp.middlewares import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aiohttp/patch.py b/ddtrace/contrib/aiohttp/patch.py deleted file mode 100644 index 39550fbea4a..00000000000 --- a/ddtrace/contrib/aiohttp/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiohttp.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aiohttp_jinja2/__init__.py b/ddtrace/contrib/aiohttp_jinja2/__init__.py deleted file mode 100644 index 90833b19484..00000000000 --- a/ddtrace/contrib/aiohttp_jinja2/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -The ``aiohttp_jinja2`` integration adds tracing of template rendering. - - -Enabling -~~~~~~~~ - -The integration is enabled automatically when using -:ref:`ddtrace-run` or :ref:`import ddtrace.auto`. - -Or use :func:`patch()` to manually enable the integration:: - - from ddtrace import patch - patch(aiohttp_jinja2=True) -""" - - -# Required to allow users to import from `ddtrace.contrib.aiohttp.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.aiohttp_jinja2.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.aiohttp_jinja2.patch import patch # noqa: F401 -from ddtrace.contrib.internal.aiohttp_jinja2.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/aiohttp_jinja2/patch.py b/ddtrace/contrib/aiohttp_jinja2/patch.py deleted file mode 100644 index a70a181f778..00000000000 --- a/ddtrace/contrib/aiohttp_jinja2/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiohttp_jinja2.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aiomysql/patch.py b/ddtrace/contrib/aiomysql/patch.py deleted file mode 100644 index e6c44c89591..00000000000 --- a/ddtrace/contrib/aiomysql/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiomysql.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aiopg/connection.py b/ddtrace/contrib/aiopg/connection.py deleted file mode 100644 index f6dac65ab66..00000000000 --- a/ddtrace/contrib/aiopg/connection.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiopg.connection import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aiopg/patch.py b/ddtrace/contrib/aiopg/patch.py deleted file mode 100644 index 2f5be810c1b..00000000000 --- a/ddtrace/contrib/aiopg/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aiopg.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aioredis/patch.py b/ddtrace/contrib/aioredis/patch.py deleted file mode 100644 index 7cc8e527a28..00000000000 --- a/ddtrace/contrib/aioredis/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aioredis.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/algoliasearch/patch.py b/ddtrace/contrib/algoliasearch/patch.py deleted file mode 100644 index 03f6abd7174..00000000000 --- a/ddtrace/contrib/algoliasearch/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.algoliasearch.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/anthropic/_streaming.py b/ddtrace/contrib/anthropic/_streaming.py deleted file mode 100644 index 80b695cefb3..00000000000 --- a/ddtrace/contrib/anthropic/_streaming.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.anthropic._streaming import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/anthropic/patch.py b/ddtrace/contrib/anthropic/patch.py deleted file mode 100644 index c672f12f6a0..00000000000 --- a/ddtrace/contrib/anthropic/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.anthropic.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/anthropic/utils.py b/ddtrace/contrib/anthropic/utils.py deleted file mode 100644 index a4c68c038f1..00000000000 --- a/ddtrace/contrib/anthropic/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.anthropic.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aredis/patch.py b/ddtrace/contrib/aredis/patch.py deleted file mode 100644 index 87bb5f21386..00000000000 --- a/ddtrace/contrib/aredis/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aredis.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asgi/__init__.py b/ddtrace/contrib/asgi.py similarity index 70% rename from ddtrace/contrib/asgi/__init__.py rename to ddtrace/contrib/asgi.py index 36c67f1f4d0..6635e0f1b18 100644 --- a/ddtrace/contrib/asgi/__init__.py +++ b/ddtrace/contrib/asgi.py @@ -57,24 +57,7 @@ def handle_request(scope, send): from ddtrace.contrib.internal.asgi.middleware import TraceMiddleware -from ddtrace.contrib.internal.asgi.middleware import get_version # noqa: F401 from ddtrace.contrib.internal.asgi.middleware import span_from_scope -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("get_version",): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["TraceMiddleware", "span_from_scope"] diff --git a/ddtrace/contrib/asgi/middleware.py b/ddtrace/contrib/asgi/middleware.py deleted file mode 100644 index 33ef2c6a363..00000000000 --- a/ddtrace/contrib/asgi/middleware.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asgi.middleware import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asgi/utils.py b/ddtrace/contrib/asgi/utils.py deleted file mode 100644 index 26853a14c93..00000000000 --- a/ddtrace/contrib/asgi/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asgi.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asyncio/__init__.py b/ddtrace/contrib/asyncio/__init__.py deleted file mode 100644 index a52166389c7..00000000000 --- a/ddtrace/contrib/asyncio/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -""" -This integration provides context management for tracing the execution flow -of concurrent execution of ``asyncio.Task``. -""" -# Required to allow users to import from `ddtrace.contrib.asyncio.patch` directly - -import warnings as _w # noqa:E402 - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 -from ddtrace._trace.provider import DefaultContextProvider -from ddtrace.contrib.internal.asyncio.helpers import ensure_future # noqa: F401 -from ddtrace.contrib.internal.asyncio.helpers import run_in_executor # noqa: F401 -from ddtrace.contrib.internal.asyncio.helpers import set_call_context # noqa: F401 -from ddtrace.contrib.internal.asyncio.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.asyncio.patch import patch # noqa: F401 -from ddtrace.contrib.internal.asyncio.patch import unpatch # noqa: F401 - - -context_provider = DefaultContextProvider() diff --git a/ddtrace/contrib/asyncio/compat.py b/ddtrace/contrib/asyncio/compat.py deleted file mode 100644 index 90c38a995fa..00000000000 --- a/ddtrace/contrib/asyncio/compat.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asyncio.compat import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asyncio/helpers.py b/ddtrace/contrib/asyncio/helpers.py deleted file mode 100644 index c6c4396fe63..00000000000 --- a/ddtrace/contrib/asyncio/helpers.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asyncio.helpers import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asyncio/patch.py b/ddtrace/contrib/asyncio/patch.py deleted file mode 100644 index 25fef661cf3..00000000000 --- a/ddtrace/contrib/asyncio/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asyncio.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asyncio/provider.py b/ddtrace/contrib/asyncio/provider.py deleted file mode 100644 index b6dcf71a553..00000000000 --- a/ddtrace/contrib/asyncio/provider.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asyncio.provider import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asyncio/wrappers.py b/ddtrace/contrib/asyncio/wrappers.py deleted file mode 100644 index d61be8a4fbb..00000000000 --- a/ddtrace/contrib/asyncio/wrappers.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asyncio.wrappers import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/asyncpg/patch.py b/ddtrace/contrib/asyncpg/patch.py deleted file mode 100644 index 4044b5168cc..00000000000 --- a/ddtrace/contrib/asyncpg/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.asyncpg.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aws_lambda/_cold_start.py b/ddtrace/contrib/aws_lambda/_cold_start.py deleted file mode 100644 index 5a96e2cc861..00000000000 --- a/ddtrace/contrib/aws_lambda/_cold_start.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aws_lambda._cold_start import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/aws_lambda/patch.py b/ddtrace/contrib/aws_lambda/patch.py deleted file mode 100644 index be2e9fb97a7..00000000000 --- a/ddtrace/contrib/aws_lambda/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.aws_lambda.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/azure_functions/__init__.py b/ddtrace/contrib/azure_functions/__init__.py deleted file mode 100644 index 9fb5a7a27b4..00000000000 --- a/ddtrace/contrib/azure_functions/__init__.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -The azure_functions integration traces all http requests to your Azure Function app. - -Enabling -~~~~~~~~ - -Use :func:`patch()` to manually enable the integration:: - - from ddtrace import patch - patch(azure_functions=True) - - -Global Configuration -~~~~~~~~~~~~~~~~~~~~ - -.. py:data:: ddtrace.config.azure_functions["service"] - - The service name reported by default for azure_functions instances. - - This option can also be set with the ``DD_SERVICE`` environment - variable. - - Default: ``"azure_functions"`` - -""" -from ddtrace.internal.utils.importlib import require_modules - - -required_modules = ["azure.functions"] - -with require_modules(required_modules) as missing_modules: - if not missing_modules: - # Required to allow users to import from `ddtrace.contrib.azure_functions.patch` directly - import warnings as _w - - with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - from ddtrace.contrib.internal.azure_functions.patch import get_version # noqa: F401 - from ddtrace.contrib.internal.azure_functions.patch import patch # noqa: F401 - from ddtrace.contrib.internal.azure_functions.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/azure_functions/patch.py b/ddtrace/contrib/azure_functions/patch.py deleted file mode 100644 index 1a23613972d..00000000000 --- a/ddtrace/contrib/azure_functions/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.azure_functions.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/boto/patch.py b/ddtrace/contrib/boto/patch.py deleted file mode 100644 index b82fbc2beb1..00000000000 --- a/ddtrace/contrib/boto/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.boto.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/botocore/patch.py b/ddtrace/contrib/botocore/patch.py deleted file mode 100644 index b514ebe22fa..00000000000 --- a/ddtrace/contrib/botocore/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.botocore.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/botocore/services/bedrock.py b/ddtrace/contrib/botocore/services/bedrock.py deleted file mode 100644 index 54f01451bd0..00000000000 --- a/ddtrace/contrib/botocore/services/bedrock.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.botocore.services.bedrock import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/botocore/services/kinesis.py b/ddtrace/contrib/botocore/services/kinesis.py deleted file mode 100644 index 71e574042b7..00000000000 --- a/ddtrace/contrib/botocore/services/kinesis.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.botocore.services.kinesis import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/botocore/services/sqs.py b/ddtrace/contrib/botocore/services/sqs.py deleted file mode 100644 index 0cc9e2b3f63..00000000000 --- a/ddtrace/contrib/botocore/services/sqs.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.botocore.services.sqs import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/botocore/services/stepfunctions.py b/ddtrace/contrib/botocore/services/stepfunctions.py deleted file mode 100644 index bb7b3e65e3f..00000000000 --- a/ddtrace/contrib/botocore/services/stepfunctions.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.botocore.services.stepfunctions import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/botocore/utils.py b/ddtrace/contrib/botocore/utils.py deleted file mode 100644 index 916ba6e733a..00000000000 --- a/ddtrace/contrib/botocore/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.botocore.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/bottle.py b/ddtrace/contrib/bottle.py new file mode 100644 index 00000000000..84f7c3a7d7d --- /dev/null +++ b/ddtrace/contrib/bottle.py @@ -0,0 +1,38 @@ +""" +The bottle integration traces the Bottle web framework. Add the following +plugin to your app:: + + import bottle + from ddtrace import tracer + from ddtrace.contrib.bottle import TracePlugin + + app = bottle.Bottle() + plugin = TracePlugin(service="my-web-app") + app.install(plugin) + +:ref:`All HTTP tags ` are supported for this integration. + +Configuration +~~~~~~~~~~~~~ + +.. py:data:: ddtrace.config.bottle['distributed_tracing'] + + Whether to parse distributed tracing headers from requests received by your bottle app. + + Can also be enabled with the ``DD_BOTTLE_DISTRIBUTED_TRACING`` environment variable. + + Default: ``True`` + + +Example:: + + from ddtrace import config + + # Enable distributed tracing + config.bottle['distributed_tracing'] = True + +""" +from ddtrace.contrib.internal.bottle.trace import TracePlugin + + +__all__ = ["TracePlugin"] diff --git a/ddtrace/contrib/bottle/__init__.py b/ddtrace/contrib/bottle/__init__.py deleted file mode 100644 index 5ee1de17f3d..00000000000 --- a/ddtrace/contrib/bottle/__init__.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -The bottle integration traces the Bottle web framework. Add the following -plugin to your app:: - - import bottle - from ddtrace.trace import tracer - from ddtrace.contrib.bottle import TracePlugin - - app = bottle.Bottle() - plugin = TracePlugin(service="my-web-app") - app.install(plugin) - -:ref:`All HTTP tags ` are supported for this integration. - -Configuration -~~~~~~~~~~~~~ - -.. py:data:: ddtrace.config.bottle['distributed_tracing'] - - Whether to parse distributed tracing headers from requests received by your bottle app. - - Can also be enabled with the ``DD_BOTTLE_DISTRIBUTED_TRACING`` environment variable. - - Default: ``True`` - - -Example:: - - from ddtrace import config - - # Enable distributed tracing - config.bottle['distributed_tracing'] = True - -""" - - -# Required to allow users to import from `ddtrace.contrib.bottle.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.bottle.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.bottle.patch import patch # noqa: F401 -from ddtrace.contrib.internal.bottle.trace import TracePlugin -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("get_version", "patch"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) - - -__all__ = ["TracePlugin"] diff --git a/ddtrace/contrib/bottle/patch.py b/ddtrace/contrib/bottle/patch.py deleted file mode 100644 index 7c12c12e7f8..00000000000 --- a/ddtrace/contrib/bottle/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.bottle.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/bottle/trace.py b/ddtrace/contrib/bottle/trace.py deleted file mode 100644 index 3602e3d6a9a..00000000000 --- a/ddtrace/contrib/bottle/trace.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.bottle.trace import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/cassandra/patch.py b/ddtrace/contrib/cassandra/patch.py deleted file mode 100644 index afcce0abf2e..00000000000 --- a/ddtrace/contrib/cassandra/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.cassandra.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/cassandra/session.py b/ddtrace/contrib/cassandra/session.py deleted file mode 100644 index 52721dbf7c2..00000000000 --- a/ddtrace/contrib/cassandra/session.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.cassandra.session import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/celery/__init__.py b/ddtrace/contrib/celery.py similarity index 62% rename from ddtrace/contrib/celery/__init__.py rename to ddtrace/contrib/celery.py index 514d0100388..f727e53c0e3 100644 --- a/ddtrace/contrib/celery/__init__.py +++ b/ddtrace/contrib/celery.py @@ -51,38 +51,8 @@ def run(self): Default: ``'celery-worker'`` """ - - -# Required to allow users to import from `ddtrace.contrib.celery.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - from ddtrace.contrib.internal.celery.app import patch_app from ddtrace.contrib.internal.celery.app import unpatch_app -from ddtrace.contrib.internal.celery.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.celery.patch import patch # noqa: F401 -from ddtrace.contrib.internal.celery.patch import unpatch # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "unpatch", "get_version"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["patch_app", "unpatch_app"] diff --git a/ddtrace/contrib/celery/app.py b/ddtrace/contrib/celery/app.py deleted file mode 100644 index 968580efc2f..00000000000 --- a/ddtrace/contrib/celery/app.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.celery.app import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/celery/constants.py b/ddtrace/contrib/celery/constants.py deleted file mode 100644 index c344daf4150..00000000000 --- a/ddtrace/contrib/celery/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.celery.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/celery/patch.py b/ddtrace/contrib/celery/patch.py deleted file mode 100644 index 2f0b9f8fa89..00000000000 --- a/ddtrace/contrib/celery/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.celery.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/celery/signals.py b/ddtrace/contrib/celery/signals.py deleted file mode 100644 index 8a7aa2ecec0..00000000000 --- a/ddtrace/contrib/celery/signals.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.celery.signals import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/celery/utils.py b/ddtrace/contrib/celery/utils.py deleted file mode 100644 index cd642ce01da..00000000000 --- a/ddtrace/contrib/celery/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.celery.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/cherrypy/__init__.py b/ddtrace/contrib/cherrypy.py similarity index 68% rename from ddtrace/contrib/cherrypy/__init__.py rename to ddtrace/contrib/cherrypy.py index 9a78ef7b47e..b217d16b440 100644 --- a/ddtrace/contrib/cherrypy/__init__.py +++ b/ddtrace/contrib/cherrypy.py @@ -52,26 +52,7 @@ def index(self): cherrypy.quickstart(HelloWorld()) """ - - from ddtrace.contrib.internal.cherrypy.patch import TraceMiddleware -from ddtrace.contrib.internal.cherrypy.patch import get_version # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("get_version",): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["TraceMiddleware"] diff --git a/ddtrace/contrib/cherrypy/middleware.py b/ddtrace/contrib/cherrypy/middleware.py deleted file mode 100644 index 25101947c50..00000000000 --- a/ddtrace/contrib/cherrypy/middleware.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.cherrypy.middleware import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/consul/patch.py b/ddtrace/contrib/consul/patch.py deleted file mode 100644 index 1936124c21e..00000000000 --- a/ddtrace/contrib/consul/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.consul.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/coverage/__init__.py b/ddtrace/contrib/coverage/__init__.py deleted file mode 100644 index 9932f73acfe..00000000000 --- a/ddtrace/contrib/coverage/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -The Coverage.py integration traces test code coverage when using `pytest` or `unittest`. - - -Enabling -~~~~~~~~ - -The Coverage.py integration is enabled automatically when using -:ref:`ddtrace-run` or :ref:`import ddtrace.auto`. - -Alternately, use :func:`patch()` to manually enable the integration:: - - from ddtrace import patch - patch(coverage=True) - -Note: Coverage.py instrumentation is only enabled if `pytest` or `unittest` instrumentation is enabled. -""" -# Required to allow users to import from `ddtrace.contrib.internal.coverage.patch` directly -import warnings as _w # noqa:E402 - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.coverage.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.coverage.patch import patch # noqa: F401 -from ddtrace.contrib.internal.coverage.patch import unpatch # noqa: F401 -from ddtrace.internal.logger import get_logger - - -log = get_logger(__name__) diff --git a/ddtrace/contrib/coverage/constants.py b/ddtrace/contrib/coverage/constants.py deleted file mode 100644 index 0ab516c8dad..00000000000 --- a/ddtrace/contrib/coverage/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.coverage.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/coverage/data.py b/ddtrace/contrib/coverage/data.py deleted file mode 100644 index 13ed64a3d4b..00000000000 --- a/ddtrace/contrib/coverage/data.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.coverage.data import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/coverage/patch.py b/ddtrace/contrib/coverage/patch.py deleted file mode 100644 index a1e35a16412..00000000000 --- a/ddtrace/contrib/coverage/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.coverage.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/coverage/utils.py b/ddtrace/contrib/coverage/utils.py deleted file mode 100644 index edfa8b1772e..00000000000 --- a/ddtrace/contrib/coverage/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.coverage.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/dbapi/__init__.py b/ddtrace/contrib/dbapi.py similarity index 97% rename from ddtrace/contrib/dbapi/__init__.py rename to ddtrace/contrib/dbapi.py index 0ecbbd804fa..d9a46da5033 100644 --- a/ddtrace/contrib/dbapi/__init__.py +++ b/ddtrace/contrib/dbapi.py @@ -12,16 +12,16 @@ from ddtrace.internal.utils import get_argument_value from ddtrace.settings.asm import config as asm_config -from ...constants import _ANALYTICS_SAMPLE_RATE_KEY -from ...constants import _SPAN_MEASURED_KEY -from ...constants import SPAN_KIND -from ...ext import SpanKind -from ...ext import SpanTypes -from ...ext import db -from ...ext import sql -from ...trace import Pin -from ..internal.trace_utils import ext_service -from ..internal.trace_utils import iswrapped +from ..constants import _ANALYTICS_SAMPLE_RATE_KEY +from ..constants import _SPAN_MEASURED_KEY +from ..constants import SPAN_KIND +from ..ext import SpanKind +from ..ext import SpanTypes +from ..ext import db +from ..ext import sql +from ..trace import Pin +from .internal.trace_utils import ext_service +from .internal.trace_utils import iswrapped log = get_logger(__name__) diff --git a/ddtrace/contrib/dbapi_async/__init__.py b/ddtrace/contrib/dbapi_async.py similarity index 96% rename from ddtrace/contrib/dbapi_async/__init__.py rename to ddtrace/contrib/dbapi_async.py index 153e8a2c33e..ae84972aaf6 100644 --- a/ddtrace/contrib/dbapi_async/__init__.py +++ b/ddtrace/contrib/dbapi_async.py @@ -7,16 +7,16 @@ from ddtrace.internal.utils import get_argument_value from ddtrace.settings.asm import config as asm_config -from ...constants import _ANALYTICS_SAMPLE_RATE_KEY -from ...constants import _SPAN_MEASURED_KEY -from ...constants import SPAN_KIND -from ...ext import SpanKind -from ...ext import SpanTypes -from ...trace import Pin -from ..dbapi import TracedConnection -from ..dbapi import TracedCursor -from ..internal.trace_utils import ext_service -from ..internal.trace_utils import iswrapped +from ..constants import _ANALYTICS_SAMPLE_RATE_KEY +from ..constants import _SPAN_MEASURED_KEY +from ..constants import SPAN_KIND +from ..ext import SpanKind +from ..ext import SpanTypes +from ..trace import Pin +from .dbapi import TracedConnection +from .dbapi import TracedCursor +from .internal.trace_utils import ext_service +from .internal.trace_utils import iswrapped log = get_logger(__name__) diff --git a/ddtrace/contrib/django/_asgi.py b/ddtrace/contrib/django/_asgi.py deleted file mode 100644 index 74a6e1e0f2b..00000000000 --- a/ddtrace/contrib/django/_asgi.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.django._asgi import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/django/compat.py b/ddtrace/contrib/django/compat.py deleted file mode 100644 index f5d00fe18a9..00000000000 --- a/ddtrace/contrib/django/compat.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.django.compat import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/django/patch.py b/ddtrace/contrib/django/patch.py deleted file mode 100644 index 06013f436f2..00000000000 --- a/ddtrace/contrib/django/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.django.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/django/restframework.py b/ddtrace/contrib/django/restframework.py deleted file mode 100644 index bd6cdc68031..00000000000 --- a/ddtrace/contrib/django/restframework.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.django.restframework import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/django/utils.py b/ddtrace/contrib/django/utils.py deleted file mode 100644 index e95da9ccc65..00000000000 --- a/ddtrace/contrib/django/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.django.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/dogpile_cache/lock.py b/ddtrace/contrib/dogpile_cache/lock.py deleted file mode 100644 index cff1db81eae..00000000000 --- a/ddtrace/contrib/dogpile_cache/lock.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.dogpile_cache.lock import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/dogpile_cache/patch.py b/ddtrace/contrib/dogpile_cache/patch.py deleted file mode 100644 index f2c26af5c7e..00000000000 --- a/ddtrace/contrib/dogpile_cache/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.dogpile_cache.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/dogpile_cache/region.py b/ddtrace/contrib/dogpile_cache/region.py deleted file mode 100644 index ef24b094065..00000000000 --- a/ddtrace/contrib/dogpile_cache/region.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.dogpile_cache.region import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/dramatiq/patch.py b/ddtrace/contrib/dramatiq/patch.py deleted file mode 100644 index e2ba0a37bf5..00000000000 --- a/ddtrace/contrib/dramatiq/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.dramatiq.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/elasticsearch/patch.py b/ddtrace/contrib/elasticsearch/patch.py deleted file mode 100644 index 71239650944..00000000000 --- a/ddtrace/contrib/elasticsearch/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.elasticsearch.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/elasticsearch/quantize.py b/ddtrace/contrib/elasticsearch/quantize.py deleted file mode 100644 index f2011326f02..00000000000 --- a/ddtrace/contrib/elasticsearch/quantize.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.elasticsearch.quantize import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/falcon/__init__.py b/ddtrace/contrib/falcon.py similarity index 56% rename from ddtrace/contrib/falcon/__init__.py rename to ddtrace/contrib/falcon.py index d86767b9d1d..a80d298d09b 100644 --- a/ddtrace/contrib/falcon/__init__.py +++ b/ddtrace/contrib/falcon.py @@ -44,34 +44,7 @@ def on_falcon_request(span, request, response): :ref:`Headers tracing ` is supported for this integration. """ - - -# Required to allow users to import from `ddtrace.contrib.falcon.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 from ddtrace.contrib.internal.falcon.middleware import TraceMiddleware -from ddtrace.contrib.internal.falcon.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.falcon.patch import patch # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "get_version"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["TraceMiddleware"] diff --git a/ddtrace/contrib/falcon/middleware.py b/ddtrace/contrib/falcon/middleware.py deleted file mode 100644 index 4650449cc89..00000000000 --- a/ddtrace/contrib/falcon/middleware.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.falcon.middleware import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/falcon/patch.py b/ddtrace/contrib/falcon/patch.py deleted file mode 100644 index 3b272cb9032..00000000000 --- a/ddtrace/contrib/falcon/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.falcon.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/fastapi/patch.py b/ddtrace/contrib/fastapi/patch.py deleted file mode 100644 index 5d8d072e147..00000000000 --- a/ddtrace/contrib/fastapi/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.fastapi.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/flask/patch.py b/ddtrace/contrib/flask/patch.py deleted file mode 100644 index 3b3c7e16639..00000000000 --- a/ddtrace/contrib/flask/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.flask.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/flask/wrappers.py b/ddtrace/contrib/flask/wrappers.py deleted file mode 100644 index dee0355abc4..00000000000 --- a/ddtrace/contrib/flask/wrappers.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.flask.wrappers import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/flask_cache/__init__.py b/ddtrace/contrib/flask_cache.py similarity index 68% rename from ddtrace/contrib/flask_cache/__init__.py rename to ddtrace/contrib/flask_cache.py index f35b73111fb..35cae2fb164 100644 --- a/ddtrace/contrib/flask_cache/__init__.py +++ b/ddtrace/contrib/flask_cache.py @@ -43,26 +43,7 @@ def counter(): Cache = get_traced_cache(tracer, service='my-flask-cache-app', cache_cls=Cache) """ - - from ddtrace.contrib.internal.flask_cache.patch import get_traced_cache -from ddtrace.contrib.internal.flask_cache.patch import get_version # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("get_version",): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["get_traced_cache"] diff --git a/ddtrace/contrib/flask_cache/tracers.py b/ddtrace/contrib/flask_cache/tracers.py deleted file mode 100644 index 06e2ce66f8b..00000000000 --- a/ddtrace/contrib/flask_cache/tracers.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.flask_cache.tracers import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/flask_cache/utils.py b/ddtrace/contrib/flask_cache/utils.py deleted file mode 100644 index 18aabdde802..00000000000 --- a/ddtrace/contrib/flask_cache/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.flask_cache.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/flask_login/__init__.py b/ddtrace/contrib/flask_login/__init__.py deleted file mode 100644 index 311eee7fa10..00000000000 --- a/ddtrace/contrib/flask_login/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -def get_version() -> str: - return "" - - -def patch(): - pass - - -def unpatch(): - pass diff --git a/ddtrace/contrib/futures/patch.py b/ddtrace/contrib/futures/patch.py deleted file mode 100644 index 3b8575d23df..00000000000 --- a/ddtrace/contrib/futures/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.futures.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/futures/threading.py b/ddtrace/contrib/futures/threading.py deleted file mode 100644 index d2e2f525869..00000000000 --- a/ddtrace/contrib/futures/threading.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.futures.threading import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/gevent/greenlet.py b/ddtrace/contrib/gevent/greenlet.py deleted file mode 100644 index 7eb6f357aff..00000000000 --- a/ddtrace/contrib/gevent/greenlet.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.gevent.greenlet import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/gevent/patch.py b/ddtrace/contrib/gevent/patch.py deleted file mode 100644 index 255f309a75e..00000000000 --- a/ddtrace/contrib/gevent/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.gevent.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/gevent/provider.py b/ddtrace/contrib/gevent/provider.py deleted file mode 100644 index f75fcf5ba5c..00000000000 --- a/ddtrace/contrib/gevent/provider.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.gevent.provider import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/graphql/patch.py b/ddtrace/contrib/graphql/patch.py deleted file mode 100644 index 642d5d5fbc1..00000000000 --- a/ddtrace/contrib/graphql/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.graphql.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/aio_client_interceptor.py b/ddtrace/contrib/grpc/aio_client_interceptor.py deleted file mode 100644 index 90e33ad393c..00000000000 --- a/ddtrace/contrib/grpc/aio_client_interceptor.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.aio_client_interceptor import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/aio_server_interceptor.py b/ddtrace/contrib/grpc/aio_server_interceptor.py deleted file mode 100644 index 16330f099e7..00000000000 --- a/ddtrace/contrib/grpc/aio_server_interceptor.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.aio_server_interceptor import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/client_interceptor.py b/ddtrace/contrib/grpc/client_interceptor.py deleted file mode 100644 index 43f2eb2a964..00000000000 --- a/ddtrace/contrib/grpc/client_interceptor.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.client_interceptor import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/constants.py b/ddtrace/contrib/grpc/constants.py deleted file mode 100644 index 05181842bb9..00000000000 --- a/ddtrace/contrib/grpc/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/patch.py b/ddtrace/contrib/grpc/patch.py deleted file mode 100644 index c903c7641c8..00000000000 --- a/ddtrace/contrib/grpc/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/server_interceptor.py b/ddtrace/contrib/grpc/server_interceptor.py deleted file mode 100644 index 2fb9882dcbd..00000000000 --- a/ddtrace/contrib/grpc/server_interceptor.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.server_interceptor import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/grpc/utils.py b/ddtrace/contrib/grpc/utils.py deleted file mode 100644 index 808d4219273..00000000000 --- a/ddtrace/contrib/grpc/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.grpc.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/httplib/patch.py b/ddtrace/contrib/httplib/patch.py deleted file mode 100644 index b74cc8965f5..00000000000 --- a/ddtrace/contrib/httplib/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.httplib.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/httpx/patch.py b/ddtrace/contrib/httpx/patch.py deleted file mode 100644 index 991317c8239..00000000000 --- a/ddtrace/contrib/httpx/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.httpx.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/internal/aiohttp/middlewares.py b/ddtrace/contrib/internal/aiohttp/middlewares.py index 63a60734d3b..b3dde240d44 100644 --- a/ddtrace/contrib/internal/aiohttp/middlewares.py +++ b/ddtrace/contrib/internal/aiohttp/middlewares.py @@ -2,7 +2,6 @@ from aiohttp.web_urldispatcher import SystemRoute from ddtrace import config -from ddtrace.contrib.asyncio import context_provider from ddtrace.ext import SpanTypes from ddtrace.ext import http from ddtrace.internal import core @@ -165,9 +164,6 @@ def trace_app(app, tracer, service="aiohttp-web"): "analytics_sample_rate": 1.0, } - # the tracer must work with asynchronous Context propagation - tracer._configure(context_provider=context_provider) - # add the async tracer middleware as a first middleware # and be sure that the on_prepare signal is the last one app.middlewares.insert(0, trace_middleware) diff --git a/ddtrace/contrib/internal/requests/patch.py b/ddtrace/contrib/internal/requests/patch.py index 6485bb7aed8..eab51c2c0a4 100644 --- a/ddtrace/contrib/internal/requests/patch.py +++ b/ddtrace/contrib/internal/requests/patch.py @@ -14,6 +14,7 @@ from ddtrace.trace import Pin from .connection import _wrap_send +from .session import TracedSession # requests default settings @@ -27,6 +28,10 @@ }, ) +# always patch our `TracedSession` when imported +_w(TracedSession, "send", _wrap_send) +Pin(_config=config.requests).onto(TracedSession) + def get_version(): # type: () -> str diff --git a/ddtrace/contrib/internal/requests/session.py b/ddtrace/contrib/internal/requests/session.py index 783dda4ff7a..eaa9c9e1be3 100644 --- a/ddtrace/contrib/internal/requests/session.py +++ b/ddtrace/contrib/internal/requests/session.py @@ -1,10 +1,4 @@ import requests -from wrapt import wrap_function_wrapper as _w - -from ddtrace import config -from ddtrace.trace import Pin - -from .connection import _wrap_send class TracedSession(requests.Session): @@ -14,8 +8,3 @@ class TracedSession(requests.Session): """ pass - - -# always patch our `TracedSession` when imported -_w(TracedSession, "send", _wrap_send) -Pin(_config=config.requests).onto(TracedSession) diff --git a/ddtrace/contrib/jinja2/constants.py b/ddtrace/contrib/jinja2/constants.py deleted file mode 100644 index 95f62db4948..00000000000 --- a/ddtrace/contrib/jinja2/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.jinja2.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/jinja2/patch.py b/ddtrace/contrib/jinja2/patch.py deleted file mode 100644 index 0571ce76584..00000000000 --- a/ddtrace/contrib/jinja2/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.jinja2.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/kafka/patch.py b/ddtrace/contrib/kafka/patch.py deleted file mode 100644 index 4d8f147b136..00000000000 --- a/ddtrace/contrib/kafka/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.kafka.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/kombu/constants.py b/ddtrace/contrib/kombu/constants.py deleted file mode 100644 index ee90cc3280e..00000000000 --- a/ddtrace/contrib/kombu/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.kombu.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/kombu/patch.py b/ddtrace/contrib/kombu/patch.py deleted file mode 100644 index f071da4a099..00000000000 --- a/ddtrace/contrib/kombu/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.kombu.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/kombu/utils.py b/ddtrace/contrib/kombu/utils.py deleted file mode 100644 index 3a36504d113..00000000000 --- a/ddtrace/contrib/kombu/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.kombu.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/langchain/constants.py b/ddtrace/contrib/langchain/constants.py deleted file mode 100644 index 278aec37d09..00000000000 --- a/ddtrace/contrib/langchain/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.langchain.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/langchain/patch.py b/ddtrace/contrib/langchain/patch.py deleted file mode 100644 index 8e5dea45caa..00000000000 --- a/ddtrace/contrib/langchain/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.langchain.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/langgraph/__init__.py b/ddtrace/contrib/langgraph/__init__.py deleted file mode 100644 index 4b3696ad803..00000000000 --- a/ddtrace/contrib/langgraph/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -from ddtrace.internal.utils.importlib import require_modules - - -required_modules = ["langgraph"] - -with require_modules(required_modules) as missing_modules: - if not missing_modules: - from ddtrace.contrib.internal.langgraph.patch import get_version - from ddtrace.contrib.internal.langgraph.patch import patch - from ddtrace.contrib.internal.langgraph.patch import unpatch - - __all__ = ["patch", "unpatch", "get_version"] diff --git a/ddtrace/contrib/logbook/patch.py b/ddtrace/contrib/logbook/patch.py deleted file mode 100644 index 1974fe67c3d..00000000000 --- a/ddtrace/contrib/logbook/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.logbook.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/logging/constants.py b/ddtrace/contrib/logging/constants.py deleted file mode 100644 index 7a05621eacc..00000000000 --- a/ddtrace/contrib/logging/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.logging.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/logging/patch.py b/ddtrace/contrib/logging/patch.py deleted file mode 100644 index 9615ee75ecb..00000000000 --- a/ddtrace/contrib/logging/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.logging.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/loguru/patch.py b/ddtrace/contrib/loguru/patch.py deleted file mode 100644 index 55e9d26c596..00000000000 --- a/ddtrace/contrib/loguru/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.loguru.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mako/constants.py b/ddtrace/contrib/mako/constants.py deleted file mode 100644 index 6ad269ab24e..00000000000 --- a/ddtrace/contrib/mako/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mako.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mako/patch.py b/ddtrace/contrib/mako/patch.py deleted file mode 100644 index 4bc20f9599b..00000000000 --- a/ddtrace/contrib/mako/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mako.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mariadb/patch.py b/ddtrace/contrib/mariadb/patch.py deleted file mode 100644 index 5ba40f90428..00000000000 --- a/ddtrace/contrib/mariadb/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mariadb.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/molten/patch.py b/ddtrace/contrib/molten/patch.py deleted file mode 100644 index f629af73de9..00000000000 --- a/ddtrace/contrib/molten/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.molten.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/molten/wrappers.py b/ddtrace/contrib/molten/wrappers.py deleted file mode 100644 index e2b406b12e7..00000000000 --- a/ddtrace/contrib/molten/wrappers.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.molten.wrappers import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mongoengine/patch.py b/ddtrace/contrib/mongoengine/patch.py deleted file mode 100644 index 13366feaf22..00000000000 --- a/ddtrace/contrib/mongoengine/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mongoengine.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mongoengine/trace.py b/ddtrace/contrib/mongoengine/trace.py deleted file mode 100644 index ad4da294cb3..00000000000 --- a/ddtrace/contrib/mongoengine/trace.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mongoengine.trace import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mysql/patch.py b/ddtrace/contrib/mysql/patch.py deleted file mode 100644 index cb347d404ec..00000000000 --- a/ddtrace/contrib/mysql/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mysql.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/mysqldb/patch.py b/ddtrace/contrib/mysqldb/patch.py deleted file mode 100644 index 2c1c69ab8c2..00000000000 --- a/ddtrace/contrib/mysqldb/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.mysqldb.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/openai/_endpoint_hooks.py b/ddtrace/contrib/openai/_endpoint_hooks.py deleted file mode 100644 index daf356a9c7a..00000000000 --- a/ddtrace/contrib/openai/_endpoint_hooks.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.openai._endpoint_hooks import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/openai/patch.py b/ddtrace/contrib/openai/patch.py deleted file mode 100644 index 049313de0d0..00000000000 --- a/ddtrace/contrib/openai/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.openai.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/openai/utils.py b/ddtrace/contrib/openai/utils.py deleted file mode 100644 index 0e7e5f4ba87..00000000000 --- a/ddtrace/contrib/openai/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.openai.utils import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/psycopg/async_connection.py b/ddtrace/contrib/psycopg/async_connection.py deleted file mode 100644 index a9524778749..00000000000 --- a/ddtrace/contrib/psycopg/async_connection.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.psycopg.async_connection import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/psycopg/async_cursor.py b/ddtrace/contrib/psycopg/async_cursor.py deleted file mode 100644 index 937eac7c586..00000000000 --- a/ddtrace/contrib/psycopg/async_cursor.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.psycopg.async_cursor import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/psycopg/connection.py b/ddtrace/contrib/psycopg/connection.py deleted file mode 100644 index 5662cf5d854..00000000000 --- a/ddtrace/contrib/psycopg/connection.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.psycopg.connection import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/psycopg/cursor.py b/ddtrace/contrib/psycopg/cursor.py deleted file mode 100644 index f9140697015..00000000000 --- a/ddtrace/contrib/psycopg/cursor.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.psycopg.cursor import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/psycopg/extensions.py b/ddtrace/contrib/psycopg/extensions.py deleted file mode 100644 index b70af814b24..00000000000 --- a/ddtrace/contrib/psycopg/extensions.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.psycopg.extensions import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/psycopg/patch.py b/ddtrace/contrib/psycopg/patch.py deleted file mode 100644 index 0b37107fa50..00000000000 --- a/ddtrace/contrib/psycopg/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.psycopg.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pylibmc.py b/ddtrace/contrib/pylibmc.py new file mode 100644 index 00000000000..c894b1fa5e2 --- /dev/null +++ b/ddtrace/contrib/pylibmc.py @@ -0,0 +1,26 @@ +"""Instrument pylibmc to report Memcached queries. + +``import ddtrace.auto`` will automatically patch your pylibmc client to make it work. +:: + + # Be sure to import pylibmc and not pylibmc.Client directly, + # otherwise you won't have access to the patched version + from ddtrace import patch + from ddtrace.trace import Pin + import pylibmc + + # If not patched yet, you can patch pylibmc specifically + patch(pylibmc=True) + + # One client instrumented with default configuration + client = pylibmc.Client(["localhost:11211"] + client.set("key1", "value1") + + # Use a pin to specify metadata related to this client + Pin.override(client, service="memcached-sessions") +""" + +from ddtrace.contrib.internal.pylibmc.client import TracedClient + + +__all__ = ["TracedClient"] diff --git a/ddtrace/contrib/pylibmc/__init__.py b/ddtrace/contrib/pylibmc/__init__.py deleted file mode 100644 index 6c21eab770e..00000000000 --- a/ddtrace/contrib/pylibmc/__init__.py +++ /dev/null @@ -1,53 +0,0 @@ -"""Instrument pylibmc to report Memcached queries. - -``import ddtrace.auto`` will automatically patch your pylibmc client to make it work. -:: - - # Be sure to import pylibmc and not pylibmc.Client directly, - # otherwise you won't have access to the patched version - from ddtrace import patch - from ddtrace.trace import Pin - import pylibmc - - # If not patched yet, you can patch pylibmc specifically - patch(pylibmc=True) - - # One client instrumented with default configuration - client = pylibmc.Client(["localhost:11211"] - client.set("key1", "value1") - - # Use a pin to specify metadata related to this client - Pin.override(client, service="memcached-sessions") -""" - - -# Required to allow users to import from `ddtrace.contrib.pylibmc.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - -from ddtrace.contrib.internal.pylibmc.client import TracedClient -from ddtrace.contrib.internal.pylibmc.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pylibmc.patch import patch # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "get_version"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) - - -__all__ = ["TracedClient"] diff --git a/ddtrace/contrib/pylibmc/addrs.py b/ddtrace/contrib/pylibmc/addrs.py deleted file mode 100644 index cec17ea0032..00000000000 --- a/ddtrace/contrib/pylibmc/addrs.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pylibmc.addrs import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pylibmc/client.py b/ddtrace/contrib/pylibmc/client.py deleted file mode 100644 index a29cf27f2fc..00000000000 --- a/ddtrace/contrib/pylibmc/client.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pylibmc.client import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pylibmc/patch.py b/ddtrace/contrib/pylibmc/patch.py deleted file mode 100644 index b0f74bd2222..00000000000 --- a/ddtrace/contrib/pylibmc/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pylibmc.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pymemcache/client.py b/ddtrace/contrib/pymemcache/client.py deleted file mode 100644 index afe650a2295..00000000000 --- a/ddtrace/contrib/pymemcache/client.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pymemcache.client import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pymemcache/patch.py b/ddtrace/contrib/pymemcache/patch.py deleted file mode 100644 index 1242a1ae15a..00000000000 --- a/ddtrace/contrib/pymemcache/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pymemcache.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pymongo/client.py b/ddtrace/contrib/pymongo/client.py deleted file mode 100644 index 40b3738baaa..00000000000 --- a/ddtrace/contrib/pymongo/client.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pymongo.client import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pymongo/parse.py b/ddtrace/contrib/pymongo/parse.py deleted file mode 100644 index bba810a9eba..00000000000 --- a/ddtrace/contrib/pymongo/parse.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pymongo.parse import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pymongo/patch.py b/ddtrace/contrib/pymongo/patch.py deleted file mode 100644 index 004c33d96b7..00000000000 --- a/ddtrace/contrib/pymongo/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pymongo.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pymysql/patch.py b/ddtrace/contrib/pymysql/patch.py deleted file mode 100644 index 2c2ac5358ca..00000000000 --- a/ddtrace/contrib/pymysql/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pymysql.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pynamodb/patch.py b/ddtrace/contrib/pynamodb/patch.py deleted file mode 100644 index d31d5b39bbb..00000000000 --- a/ddtrace/contrib/pynamodb/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pynamodb.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pyodbc/patch.py b/ddtrace/contrib/pyodbc/patch.py deleted file mode 100644 index 8609aeb12c9..00000000000 --- a/ddtrace/contrib/pyodbc/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pyodbc.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pyramid/__init__.py b/ddtrace/contrib/pyramid.py similarity index 60% rename from ddtrace/contrib/pyramid/__init__.py rename to ddtrace/contrib/pyramid.py index 87aab191815..d608a83fc3e 100644 --- a/ddtrace/contrib/pyramid/__init__.py +++ b/ddtrace/contrib/pyramid.py @@ -39,38 +39,9 @@ :ref:`All HTTP tags ` are supported for this integration. """ - - -# Required to allow users to import from `ddtrace.contrib.pyramid.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.pyramid.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.pyramid.patch import patch # noqa: F401 from ddtrace.contrib.internal.pyramid.trace import includeme from ddtrace.contrib.internal.pyramid.trace import trace_pyramid from ddtrace.contrib.internal.pyramid.trace import trace_tween_factory -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "get_version"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["trace_pyramid", "trace_tween_factory", "includeme"] diff --git a/ddtrace/contrib/pyramid/constants.py b/ddtrace/contrib/pyramid/constants.py deleted file mode 100644 index f1ec8ea0480..00000000000 --- a/ddtrace/contrib/pyramid/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pyramid.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pyramid/patch.py b/ddtrace/contrib/pyramid/patch.py deleted file mode 100644 index 993facea9a9..00000000000 --- a/ddtrace/contrib/pyramid/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pyramid.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pyramid/trace.py b/ddtrace/contrib/pyramid/trace.py deleted file mode 100644 index c58b572b0ee..00000000000 --- a/ddtrace/contrib/pyramid/trace.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pyramid.trace import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest/constants.py b/ddtrace/contrib/pytest/constants.py deleted file mode 100644 index 695c48e5b95..00000000000 --- a/ddtrace/contrib/pytest/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest/newhooks.py b/ddtrace/contrib/pytest/newhooks.py deleted file mode 100644 index b54e146fde9..00000000000 --- a/ddtrace/contrib/pytest/newhooks.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest.newhooks import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest/plugin.py b/ddtrace/contrib/pytest/plugin.py deleted file mode 100644 index 05002fc74d4..00000000000 --- a/ddtrace/contrib/pytest/plugin.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest.plugin import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest_bdd/constants.py b/ddtrace/contrib/pytest_bdd/constants.py deleted file mode 100644 index 9c2e907debd..00000000000 --- a/ddtrace/contrib/pytest_bdd/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest_bdd.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest_bdd/plugin.py b/ddtrace/contrib/pytest_bdd/plugin.py deleted file mode 100644 index 88645368d38..00000000000 --- a/ddtrace/contrib/pytest_bdd/plugin.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest_bdd.plugin import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest_benchmark/__init__.py b/ddtrace/contrib/pytest_benchmark/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ddtrace/contrib/pytest_benchmark/constants.py b/ddtrace/contrib/pytest_benchmark/constants.py deleted file mode 100644 index 522f664d4b8..00000000000 --- a/ddtrace/contrib/pytest_benchmark/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest_benchmark.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/pytest_benchmark/plugin.py b/ddtrace/contrib/pytest_benchmark/plugin.py deleted file mode 100644 index 7a33bbf838d..00000000000 --- a/ddtrace/contrib/pytest_benchmark/plugin.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.pytest_benchmark.plugin import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/redis/asyncio_patch.py b/ddtrace/contrib/redis/asyncio_patch.py deleted file mode 100644 index f46f432e205..00000000000 --- a/ddtrace/contrib/redis/asyncio_patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.redis.asyncio_patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/redis/patch.py b/ddtrace/contrib/redis/patch.py deleted file mode 100644 index 972c1a4320d..00000000000 --- a/ddtrace/contrib/redis/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.redis.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/redis_utils.py b/ddtrace/contrib/redis_utils.py deleted file mode 100644 index 08012fb2c65..00000000000 --- a/ddtrace/contrib/redis_utils.py +++ /dev/null @@ -1 +0,0 @@ -from ddtrace.contrib.internal.redis_utils import * # noqa: F403 diff --git a/ddtrace/contrib/rediscluster/patch.py b/ddtrace/contrib/rediscluster/patch.py deleted file mode 100644 index 88a20183ebd..00000000000 --- a/ddtrace/contrib/rediscluster/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.rediscluster.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/requests/__init__.py b/ddtrace/contrib/requests.py similarity index 62% rename from ddtrace/contrib/requests/__init__.py rename to ddtrace/contrib/requests.py index 7d034ce56bf..2f289a467e8 100644 --- a/ddtrace/contrib/requests/__init__.py +++ b/ddtrace/contrib/requests.py @@ -71,37 +71,7 @@ session = Session() Pin.override(session, service='auth-api') """ - - -# Required to allow users to import from `ddtrace.contrib.requests.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.requests.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.requests.patch import patch # noqa: F401 -from ddtrace.contrib.internal.requests.patch import unpatch # noqa: F401 -from ddtrace.contrib.internal.requests.session import TracedSession -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "unpatch", "get_version"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) +from ddtrace.contrib.internal.requests.patch import TracedSession __all__ = ["TracedSession"] diff --git a/ddtrace/contrib/requests/connection.py b/ddtrace/contrib/requests/connection.py deleted file mode 100644 index f1bbc7e1a84..00000000000 --- a/ddtrace/contrib/requests/connection.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.requests.connection import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/requests/constants.py b/ddtrace/contrib/requests/constants.py deleted file mode 100644 index ef871029e45..00000000000 --- a/ddtrace/contrib/requests/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.requests.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/requests/patch.py b/ddtrace/contrib/requests/patch.py deleted file mode 100644 index f16bf99900d..00000000000 --- a/ddtrace/contrib/requests/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.requests.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/requests/session.py b/ddtrace/contrib/requests/session.py deleted file mode 100644 index 866662a6c34..00000000000 --- a/ddtrace/contrib/requests/session.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.requests.session import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/sanic/patch.py b/ddtrace/contrib/sanic/patch.py deleted file mode 100644 index b6a2468f0d1..00000000000 --- a/ddtrace/contrib/sanic/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.sanic.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/snowflake/patch.py b/ddtrace/contrib/snowflake/patch.py deleted file mode 100644 index b18dc288250..00000000000 --- a/ddtrace/contrib/snowflake/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.snowflake.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/sqlalchemy.py b/ddtrace/contrib/sqlalchemy.py new file mode 100644 index 00000000000..04bffa87b85 --- /dev/null +++ b/ddtrace/contrib/sqlalchemy.py @@ -0,0 +1,26 @@ +""" +Enabling the SQLAlchemy integration is only necessary if there is no +instrumentation available or enabled for the underlying database engine (e.g. +pymysql, psycopg, mysql-connector, etc.). + +To trace sqlalchemy queries, add instrumentation to the engine class +using the patch method that **must be called before** importing sqlalchemy:: + + # patch before importing `create_engine` + from ddtrace import patch + from ddtrace.trace import Pin + patch(sqlalchemy=True) + + # use SQLAlchemy as usual + from sqlalchemy import create_engine + + engine = create_engine('sqlite:///:memory:') + engine.connect().execute("SELECT COUNT(*) FROM users") + + # Use a PIN to specify metadata related to this engine + Pin.override(engine, service='replica-db') +""" +from ddtrace.contrib.internal.sqlalchemy.engine import trace_engine + + +__all__ = ["trace_engine"] diff --git a/ddtrace/contrib/sqlalchemy/__init__.py b/ddtrace/contrib/sqlalchemy/__init__.py deleted file mode 100644 index c9b0f47715b..00000000000 --- a/ddtrace/contrib/sqlalchemy/__init__.py +++ /dev/null @@ -1,58 +0,0 @@ -""" -Enabling the SQLAlchemy integration is only necessary if there is no -instrumentation available or enabled for the underlying database engine (e.g. -pymysql, psycopg, mysql-connector, etc.). - -To trace sqlalchemy queries, add instrumentation to the engine class -using the patch method that **must be called before** importing sqlalchemy:: - - # patch before importing `create_engine` - from ddtrace import patch - from ddtrace.trace import Pin - patch(sqlalchemy=True) - - # use SQLAlchemy as usual - from sqlalchemy import create_engine - - engine = create_engine('sqlite:///:memory:') - engine.connect().execute("SELECT COUNT(*) FROM users") - - # Use a PIN to specify metadata related to this engine - Pin.override(engine, service='replica-db') -""" - - -# Required to allow users to import from `ddtrace.contrib.sqlalchemy.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.sqlalchemy.engine import trace_engine -from ddtrace.contrib.internal.sqlalchemy.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.sqlalchemy.patch import patch # noqa: F401 -from ddtrace.contrib.internal.sqlalchemy.patch import unpatch # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("patch", "unpatch", "get_version"): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Avoid using this package directly. " - "Set DD_TRACE_SQLALCHEMY_ENABLED=true and use ``import ddtrace.auto`` or the " - "``ddtrace-run`` command to enable and configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) - - -__all__ = ["trace_engine"] diff --git a/ddtrace/contrib/sqlalchemy/engine.py b/ddtrace/contrib/sqlalchemy/engine.py deleted file mode 100644 index 4496b74b479..00000000000 --- a/ddtrace/contrib/sqlalchemy/engine.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.sqlalchemy.engine import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/sqlalchemy/patch.py b/ddtrace/contrib/sqlalchemy/patch.py deleted file mode 100644 index 511637534e2..00000000000 --- a/ddtrace/contrib/sqlalchemy/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.sqlalchemy.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/sqlite3/patch.py b/ddtrace/contrib/sqlite3/patch.py deleted file mode 100644 index 1d1d3daf726..00000000000 --- a/ddtrace/contrib/sqlite3/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.sqlite3.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/starlette/patch.py b/ddtrace/contrib/starlette/patch.py deleted file mode 100644 index 0c85c3ff44a..00000000000 --- a/ddtrace/contrib/starlette/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.starlette.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/structlog/patch.py b/ddtrace/contrib/structlog/patch.py deleted file mode 100644 index 2f346e88f18..00000000000 --- a/ddtrace/contrib/structlog/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.structlog.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/subprocess/constants.py b/ddtrace/contrib/subprocess/constants.py deleted file mode 100644 index 29562e61200..00000000000 --- a/ddtrace/contrib/subprocess/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.subprocess.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/subprocess/patch.py b/ddtrace/contrib/subprocess/patch.py deleted file mode 100644 index 99510d5761c..00000000000 --- a/ddtrace/contrib/subprocess/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.subprocess.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/__init__.py b/ddtrace/contrib/tornado.py similarity index 89% rename from ddtrace/contrib/tornado/__init__.py rename to ddtrace/contrib/tornado.py index 1c0caf3366d..dc231fce60d 100644 --- a/ddtrace/contrib/tornado/__init__.py +++ b/ddtrace/contrib/tornado.py @@ -97,19 +97,6 @@ def log_exception(self, typ, value, tb): * ``agent_port`` (default: `8126`): define the port of the APM agent. * ``settings`` (default: ``{}``): Tracer extra settings used to change, for instance, the filtering behavior. """ - -# Required to allow users to import from `ddtrace.contrib.tornado.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.tornado.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.tornado.patch import patch # noqa: F401 -from ddtrace.contrib.internal.tornado.patch import unpatch # noqa: F401 from ddtrace.contrib.internal.tornado.stack_context import TracerStackContext from ddtrace.contrib.internal.tornado.stack_context import context_provider from ddtrace.contrib.internal.tornado.stack_context import run_with_trace_context diff --git a/ddtrace/contrib/tornado/application.py b/ddtrace/contrib/tornado/application.py deleted file mode 100644 index 4faf81a95cc..00000000000 --- a/ddtrace/contrib/tornado/application.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.application import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/constants.py b/ddtrace/contrib/tornado/constants.py deleted file mode 100644 index 861f9dd5b29..00000000000 --- a/ddtrace/contrib/tornado/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/decorators.py b/ddtrace/contrib/tornado/decorators.py deleted file mode 100644 index 4f3811ebfc8..00000000000 --- a/ddtrace/contrib/tornado/decorators.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.decorators import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/handlers.py b/ddtrace/contrib/tornado/handlers.py deleted file mode 100644 index 0256c401a7a..00000000000 --- a/ddtrace/contrib/tornado/handlers.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.handlers import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/patch.py b/ddtrace/contrib/tornado/patch.py deleted file mode 100644 index ff967a982d4..00000000000 --- a/ddtrace/contrib/tornado/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/stack_context.py b/ddtrace/contrib/tornado/stack_context.py deleted file mode 100644 index 9a1245b3afc..00000000000 --- a/ddtrace/contrib/tornado/stack_context.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.stack_context import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/tornado/template.py b/ddtrace/contrib/tornado/template.py deleted file mode 100644 index a4cdabd27b0..00000000000 --- a/ddtrace/contrib/tornado/template.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.tornado.template import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/trace_utils_async.py b/ddtrace/contrib/trace_utils_async.py deleted file mode 100644 index 46d4e8762a3..00000000000 --- a/ddtrace/contrib/trace_utils_async.py +++ /dev/null @@ -1 +0,0 @@ -from ddtrace.contrib.internal.trace_utils_async import * # noqa: F403 diff --git a/ddtrace/contrib/trace_utils_redis.py b/ddtrace/contrib/trace_utils_redis.py deleted file mode 100644 index b8aff5eef23..00000000000 --- a/ddtrace/contrib/trace_utils_redis.py +++ /dev/null @@ -1,9 +0,0 @@ -from ddtrace.contrib.internal.redis_utils import determine_row_count -from ddtrace.contrib.internal.redis_utils import stringify_cache_args - - -format_command_args = stringify_cache_args - - -def determine_row_count(redis_command, span, result): # noqa: F811 - determine_row_count(redis_command=redis_command, result=result) diff --git a/ddtrace/contrib/unittest/constants.py b/ddtrace/contrib/unittest/constants.py deleted file mode 100644 index fc8643d5e06..00000000000 --- a/ddtrace/contrib/unittest/constants.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.unittest.constants import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/unittest/patch.py b/ddtrace/contrib/unittest/patch.py deleted file mode 100644 index 277b3b421c6..00000000000 --- a/ddtrace/contrib/unittest/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.unittest.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/urllib/__init__.py b/ddtrace/contrib/urllib/__init__.py deleted file mode 100644 index bc9fae37949..00000000000 --- a/ddtrace/contrib/urllib/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -Trace the standard library ``urllib.request`` library to trace -HTTP requests and detect SSRF vulnerabilities. It is enabled by default -if ``DD_IAST_ENABLED`` is set to ``True`` (for detecting sink points) and/or -``DD_ASM_ENABLED`` is set to ``True`` (for exploit prevention). -""" - - -# Required to allow users to import from `ddtrace.contrib.urllib.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.urllib.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.urllib.patch import patch # noqa: F401 -from ddtrace.contrib.internal.urllib.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/urllib/patch.py b/ddtrace/contrib/urllib/patch.py deleted file mode 100644 index 033916e6e46..00000000000 --- a/ddtrace/contrib/urllib/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.urllib.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/urllib3/patch.py b/ddtrace/contrib/urllib3/patch.py deleted file mode 100644 index 01d775de390..00000000000 --- a/ddtrace/contrib/urllib3/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.urllib3.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/vertica/patch.py b/ddtrace/contrib/vertica/patch.py deleted file mode 100644 index 0cdbe6cd956..00000000000 --- a/ddtrace/contrib/vertica/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.vertica.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/webbrowser/__init__.py b/ddtrace/contrib/webbrowser/__init__.py deleted file mode 100644 index 74160b052e3..00000000000 --- a/ddtrace/contrib/webbrowser/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -Trace the standard library ``webbrowser`` library to trace -HTTP requests and detect SSRF vulnerabilities. It is enabled by default -if ``DD_IAST_ENABLED`` is set to ``True`` (for detecting sink points) and/or -``DD_ASM_ENABLED`` is set to ``True`` (for exploit prevention). -""" - - -# Required to allow users to import from `ddtrace.contrib.webbrowser.patch` directly -import warnings as _w - - -with _w.catch_warnings(): - _w.simplefilter("ignore", DeprecationWarning) - from . import patch as _ # noqa: F401, I001 - - -from ddtrace.contrib.internal.webbrowser.patch import get_version # noqa: F401 -from ddtrace.contrib.internal.webbrowser.patch import patch # noqa: F401 -from ddtrace.contrib.internal.webbrowser.patch import unpatch # noqa: F401 diff --git a/ddtrace/contrib/webbrowser/patch.py b/ddtrace/contrib/webbrowser/patch.py deleted file mode 100644 index 03dfb3b14cf..00000000000 --- a/ddtrace/contrib/webbrowser/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.webbrowser.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/wsgi/__init__.py b/ddtrace/contrib/wsgi.py similarity index 56% rename from ddtrace/contrib/wsgi/__init__.py rename to ddtrace/contrib/wsgi.py index 9e674993be3..94f44fbb9df 100644 --- a/ddtrace/contrib/wsgi/__init__.py +++ b/ddtrace/contrib/wsgi.py @@ -37,23 +37,6 @@ """ from ddtrace.contrib.internal.wsgi.wsgi import DDWSGIMiddleware -from ddtrace.contrib.internal.wsgi.wsgi import get_version # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - if name in ("get_version",): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - message="Use ``import ddtrace.auto`` or the ``ddtrace-run`` command to configure this integration.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) __all__ = ["DDWSGIMiddleware"] diff --git a/ddtrace/contrib/wsgi/wsgi.py b/ddtrace/contrib/wsgi/wsgi.py deleted file mode 100644 index e2f1f6bcea4..00000000000 --- a/ddtrace/contrib/wsgi/wsgi.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.wsgi.wsgi import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/contrib/yaaredis/patch.py b/ddtrace/contrib/yaaredis/patch.py deleted file mode 100644 index 83b8fe0a468..00000000000 --- a/ddtrace/contrib/yaaredis/patch.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace.contrib.internal.yaaredis.patch import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) diff --git a/ddtrace/filters.py b/ddtrace/filters.py deleted file mode 100644 index bd6367d5635..00000000000 --- a/ddtrace/filters.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace._trace.filters import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The ddtrace.filters module and the ``FilterRequestsOnUrl`` class is deprecated and will be removed.", - message="Import ``TraceFilter`` from the ddtrace.trace package.", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/internal/rate_limiter.py b/ddtrace/internal/rate_limiter.py index 0a97a6a7abc..9b514e5ff32 100644 --- a/ddtrace/internal/rate_limiter.py +++ b/ddtrace/internal/rate_limiter.py @@ -9,9 +9,6 @@ from typing import Callable # noqa:F401 from typing import Optional # noqa:F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - class RateLimiter(object): """ @@ -57,26 +54,18 @@ def __init__(self, rate_limit: int, time_window: float = 1e9): self._lock = threading.Lock() - def is_allowed(self, timestamp_ns: Optional[int] = None) -> bool: + def is_allowed(self) -> bool: """ Check whether the current request is allowed or not This method will also reduce the number of available tokens by 1 - :param int timestamp_ns: timestamp in nanoseconds for the current request. :returns: Whether the current request is allowed or not :rtype: :obj:`bool` """ - if timestamp_ns is not None: - deprecate( - "The `timestamp_ns` parameter is deprecated and will be removed in a future version." - "Ratelimiter will use the current time.", - category=DDTraceDeprecationWarning, - ) - # rate limits are tested and mocked in pytest so we need to compute the timestamp here # (or move the unit tests to rust) - timestamp_ns = timestamp_ns or time.monotonic_ns() + timestamp_ns = time.monotonic_ns() allowed = self._is_allowed(timestamp_ns) # Update counts used to determine effective rate self._update_rate_counts(allowed, timestamp_ns) diff --git a/ddtrace/internal/tracemethods.py b/ddtrace/internal/tracemethods.py index 5328797c09f..456cca597e1 100644 --- a/ddtrace/internal/tracemethods.py +++ b/ddtrace/internal/tracemethods.py @@ -4,8 +4,6 @@ import wrapt from ddtrace.internal.logger import get_logger -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate log = get_logger(__name__) @@ -65,102 +63,10 @@ def _parse_trace_methods(raw_dd_trace_methods: str) -> List[Tuple[str, str]]: return dd_trace_methods -def _parse_legacy_trace_methods(raw_dd_trace_methods: str) -> List[str]: - """ - Return a list of method names to trace based on the specification of - DD_TRACE_METHODS. - - Note that support for wildcard methods with [*] is not implemented. - - This square bracket notation will be deprecated in favor of the new ':' notation - TODO: This method can be deleted once the legacy syntax is officially deprecated - """ - if not raw_dd_trace_methods: - return [] - dd_trace_methods = [] - for qualified_methods in raw_dd_trace_methods.split(";"): - # Validate that methods are specified - if "[" not in qualified_methods or "]" not in qualified_methods: - log.warning( - ( - "Invalid DD_TRACE_METHODS: %s. " - "Methods must be specified in square brackets following the fully qualified module or class name." - ), - qualified_methods, - ) - return [] - - # Store the prefix of the qualified method name (eg. for "foo.bar.baz[qux,quux]", this is "foo.bar.baz") - qualified_method_prefix = qualified_methods.split("[")[0] - - if qualified_method_prefix == "__main__": - # __main__ cannot be used since the __main__ that exists now is not the same as the __main__ that the user - # application will have. __main__ when sitecustomize module is run is the builtin __main__. - log.warning( - "Invalid DD_TRACE_METHODS: %s. Methods cannot be traced on the __main__ module.", qualified_methods - ) - return [] - - # Get the class or module name of the method (eg. for "foo.bar.baz[qux,quux]", this is "baz[qux,quux]") - class_or_module_with_methods = qualified_methods.split(".")[-1] - - # Strip off the leading 'moduleOrClass[' and trailing ']' - methods = class_or_module_with_methods.split("[")[1] - methods = methods[:-1] - - # Add the methods to the list of methods to trace - for method in methods.split(","): - if not str.isidentifier(method): - log.warning( - "Invalid method name: %r. %s", - method, - ( - "You might have a trailing comma." - if method == "" - else "Method names must be valid Python identifiers." - ), - ) - return [] - dd_trace_methods.append("%s.%s" % (qualified_method_prefix, method)) - return dd_trace_methods - - def _install_trace_methods(raw_dd_trace_methods: str) -> None: """Install tracing on the given methods.""" - if "[" in raw_dd_trace_methods: - deprecate( - "Using DD_TRACE_METHODS with the '[]' notation is deprecated", - message="Please use DD_TRACE_METHODS with the new ':' notation instead", - removal_version="3.0.0", - category=DDTraceDeprecationWarning, - ) - # Using legacy syntax - for qualified_method in _parse_legacy_trace_methods(raw_dd_trace_methods): - # We don't know if the method is a class method or a module method, so we need to assume it's a module - # and if the import fails then go a level up and try again. - base_module_guess = ".".join(qualified_method.split(".")[:-1]) - method_name = qualified_method.split(".")[-1] - module = None - - while base_module_guess: - try: - module = __import__(base_module_guess) - except ImportError: - # Add the class to the method name - method_name = "%s.%s" % (base_module_guess.split(".")[-1], method_name) - base_module_guess = ".".join(base_module_guess.split(".")[:-1]) - else: - break - - if module is None: - log.warning("Could not import module for %r", qualified_method) - continue - - trace_method(base_module_guess, method_name) - else: - # Using updated syntax, no need to try to import - for module_name, method_name in _parse_trace_methods(raw_dd_trace_methods): - trace_method(module_name, method_name) + for module_name, method_name in _parse_trace_methods(raw_dd_trace_methods): + trace_method(module_name, method_name) def trace_method(module, method_name): diff --git a/ddtrace/opentracer/tracer.py b/ddtrace/opentracer/tracer.py index ca10cb8125a..65d1b95b314 100644 --- a/ddtrace/opentracer/tracer.py +++ b/ddtrace/opentracer/tracer.py @@ -18,7 +18,6 @@ from ddtrace.trace import Context as DatadogContext # noqa:F401 from ddtrace.trace import Span as DatadogSpan from ddtrace.trace import Tracer as DatadogTracer -from ddtrace.vendor.debtcollector import deprecate from ..internal.logger import get_logger from .propagation import HTTPPropagator @@ -55,7 +54,7 @@ def __init__( service_name: Optional[str] = None, config: Optional[Dict[str, Any]] = None, scope_manager: Optional[ScopeManager] = None, - dd_tracer: Optional[DatadogTracer] = None, + _dd_tracer: Optional[DatadogTracer] = None, ) -> None: """Initialize a new Datadog opentracer. @@ -70,9 +69,6 @@ def __init__( here: https://github.com/opentracing/opentracing-python#scope-managers. If ``None`` is provided, defaults to :class:`opentracing.scope_managers.ThreadLocalScopeManager`. - :param dd_tracer: (optional) the Datadog tracer for this tracer to use. This - parameter is deprecated and will be removed in v3.0.0. The - to the global tracer (``ddtrace.tracer``) should always be used. """ # Merge the given config with the default into a new dict self._config = DEFAULT_CONFIG.copy() @@ -100,14 +96,7 @@ def __init__( self._scope_manager = scope_manager or ThreadLocalScopeManager() dd_context_provider = get_context_provider_for_scope_manager(self._scope_manager) - if dd_tracer is not None: - deprecate( - "The ``dd_tracer`` parameter is deprecated", - message="The global tracer (``ddtrace.tracer``) will be used instead.", - removal_version="3.0.0", - ) - - self._dd_tracer = dd_tracer or ddtrace.tracer + self._dd_tracer = _dd_tracer or ddtrace.tracer self._dd_tracer.set_tags(self._config.get(keys.GLOBAL_TAGS)) # type: ignore[arg-type] trace_processors = None if keys.SETTINGS in self._config: @@ -121,7 +110,7 @@ def __init__( trace_processors=trace_processors, priority_sampling=self._config.get(keys.PRIORITY_SAMPLING), uds_path=self._config.get(keys.UDS_PATH), - context_provider=dd_context_provider, # type: ignore[arg-type] + context_provider=dd_context_provider, ) self._propagators = { Format.HTTP_HEADERS: HTTPPropagator, diff --git a/ddtrace/pin.py b/ddtrace/pin.py deleted file mode 100644 index 0e683b3b22e..00000000000 --- a/ddtrace/pin.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace._trace.pin import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The ddtrace.trace.Pin module is deprecated and will be removed.", - message="Import ``Pin`` from the ddtrace.trace package.", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/provider.py b/ddtrace/provider.py deleted file mode 100644 index 7b9867de01a..00000000000 --- a/ddtrace/provider.py +++ /dev/null @@ -1,14 +0,0 @@ -from ddtrace._trace.provider import BaseContextProvider # noqa: F401 -from ddtrace._trace.provider import DatadogContextMixin # noqa: F401 -from ddtrace._trace.provider import DefaultContextProvider # noqa: F401 -from ddtrace.internal.ci_visibility.context import CIContextProvider # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The context provider interface is deprecated", - message="Import BaseContextProvider from `ddtrace.trace` instead.", - category=DDTraceDeprecationWarning, - removal_version="3.0.0", -) diff --git a/ddtrace/sampler.py b/ddtrace/sampler.py deleted file mode 100644 index c7f4b9d499a..00000000000 --- a/ddtrace/sampler.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace._trace.sampler import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The ddtrace.sampler module is deprecated and will be removed.", - message="Use DD_TRACE_SAMPLING_RULES to configure sampling rates.", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/sampling_rule.py b/ddtrace/sampling_rule.py deleted file mode 100644 index 244cebddd31..00000000000 --- a/ddtrace/sampling_rule.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace._trace.sampling_rule import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The ddtrace.sample_rule module is deprecated and will be removed.", - message="Use DD_TRACE_SAMPLING_RULES to set sampling rules.", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/span.py b/ddtrace/span.py deleted file mode 100644 index 48f1835262c..00000000000 --- a/ddtrace/span.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.trace import Span # noqa: F401 -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The span module is deprecated and will be moved.", - message="A new span interface will be provided by the trace sub-package.", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/tracer.py b/ddtrace/tracer.py deleted file mode 100644 index afb4e05492d..00000000000 --- a/ddtrace/tracer.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace._trace.tracer import Tracer # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The ddtrace.tracer module is deprecated and will be removed.", - message="A new interface will be provided by the trace sub-package.", - category=DDTraceDeprecationWarning, -) diff --git a/ddtrace/tracing/__init__.py b/ddtrace/tracing/__init__.py deleted file mode 100644 index c66bb230093..00000000000 --- a/ddtrace/tracing/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from ddtrace._trace import trace_handlers # noqa: F401 -from ddtrace._trace._span_link import SpanLink # noqa: F401 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -deprecate( - "The tracing module is deprecated and will be moved.", - message="A new interface will be provided by the _trace sub-package.", - category=DDTraceDeprecationWarning, -) diff --git a/docker-compose.yml b/docker-compose.yml index 701b5a7d0f0..dfcee9a54ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -198,7 +198,6 @@ services: ports: - "127.0.0.1:8321:8321" environment: - - DD_APPSEC_ENABLED=true - DD_IAST_ENABLED=true - DD_IAST_REQUEST_SAMPLING=100 - DD_IAST_VULNERABILITIES_PER_REQUEST=100 diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index ca55d55e4ca..5fe21321680 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -371,7 +371,7 @@ the pipeline or ``None`` if the trace should be discarded:: Logs Injection -------------- -.. automodule:: ddtrace.contrib.logging +.. automodule:: ddtrace.contrib._logging .. _http-tagging: diff --git a/docs/integrations.rst b/docs/integrations.rst index 62e096aa668..0566ab7fa9c 100644 --- a/docs/integrations.rst +++ b/docs/integrations.rst @@ -7,27 +7,27 @@ Integrations aiobotocore ^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.aiobotocore +.. automodule:: ddtrace.contrib._aiobotocore .. _aiopg: aiopg ^^^^^ -.. automodule:: ddtrace.contrib.aiopg +.. automodule:: ddtrace.contrib._aiopg .. _algoliasearch: algoliasearch ^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.algoliasearch +.. automodule:: ddtrace.contrib._algoliasearch .. _aredis: aredis ^^^^^^ -.. automodule:: ddtrace.contrib.aredis +.. automodule:: ddtrace.contrib._aredis .. _asgi: @@ -45,49 +45,49 @@ aiohttp aiomysql ^^^^^^^^ -.. automodule:: ddtrace.contrib.aiomysql +.. automodule:: ddtrace.contrib._aiomysql .. _aiohttp_jinja2: aiohttp_jinja2 ^^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.aiohttp_jinja2 +.. automodule:: ddtrace.contrib._aiohttp_jinja2 .. _anthropic: anthropic ^^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.anthropic +.. automodule:: ddtrace.contrib._anthropic .. _asyncio: asyncio ^^^^^^^ -.. automodule:: ddtrace.contrib.asyncio +.. automodule:: ddtrace.contrib._asyncio .. _asyncpg: asyncpg ^^^^^^^ -.. automodule:: ddtrace.contrib.asyncpg +.. automodule:: ddtrace.contrib._asyncpg .. _botocore: botocore ^^^^^^^^ -.. automodule:: ddtrace.contrib.botocore +.. automodule:: ddtrace.contrib._botocore .. _boto2: boto2 ^^^^^ -.. automodule:: ddtrace.contrib.boto +.. automodule:: ddtrace.contrib._boto .. _bottle: @@ -101,7 +101,7 @@ Bottle Cassandra ^^^^^^^^^ -.. automodule:: ddtrace.contrib.cassandra +.. automodule:: ddtrace.contrib._cassandra .. _celery: @@ -122,14 +122,14 @@ CherryPy Consul ^^^^^^ -.. automodule:: ddtrace.contrib.consul +.. automodule:: ddtrace.contrib._consul .. _datadog_lambda: Datadog Lambda ^^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.aws_lambda +.. automodule:: ddtrace.contrib._aws_lambda .. _djangorestframework: @@ -137,21 +137,21 @@ Datadog Lambda Django ^^^^^^ -.. automodule:: ddtrace.contrib.django +.. automodule:: ddtrace.contrib._django .. _dogpile.cache: dogpile.cache ^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.dogpile_cache +.. automodule:: ddtrace.contrib._dogpile_cache .. _elasticsearch: Elasticsearch ^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.elasticsearch +.. automodule:: ddtrace.contrib._elasticsearch .. _falcon: @@ -165,14 +165,14 @@ Falcon Fastapi ^^^^^^^^^ -.. automodule:: ddtrace.contrib.fastapi +.. automodule:: ddtrace.contrib._fastapi .. _flask: Flask ^^^^^ -.. automodule:: ddtrace.contrib.flask +.. automodule:: ddtrace.contrib._flask .. _flask_cache: @@ -186,128 +186,128 @@ Flask Cache futures ^^^^^^^ -.. automodule:: ddtrace.contrib.futures +.. automodule:: ddtrace.contrib._futures .. _gevent: gevent ^^^^^^ -.. automodule:: ddtrace.contrib.gevent +.. automodule:: ddtrace.contrib._gevent .. _google_generativeai: google-generativeai ^^^^^^^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.google_generativeai +.. automodule:: ddtrace.contrib._google_generativeai .. _graphql: graphql ^^^^^^^ -.. automodule:: ddtrace.contrib.graphql +.. automodule:: ddtrace.contrib._graphql .. _grpc: Grpc ^^^^ -.. automodule:: ddtrace.contrib.grpc +.. automodule:: ddtrace.contrib._grpc .. _gunicorn: gunicorn ^^^^^^^^ -.. automodule:: ddtrace.contrib.gunicorn +.. automodule:: ddtrace.contrib._gunicorn .. _httplib: httplib ^^^^^^^ -.. automodule:: ddtrace.contrib.httplib +.. automodule:: ddtrace.contrib._httplib .. _httpx: httpx ^^^^^ -.. automodule:: ddtrace.contrib.httpx +.. automodule:: ddtrace.contrib._httpx .. _jinja2: Jinja2 ^^^^^^ -.. automodule:: ddtrace.contrib.jinja2 +.. automodule:: ddtrace.contrib._jinja2 .. _kafka: Kafka ^^^^^ -.. automodule:: ddtrace.contrib.kafka +.. automodule:: ddtrace.contrib._kafka .. _kombu: kombu ^^^^^ -.. automodule:: ddtrace.contrib.kombu +.. automodule:: ddtrace.contrib._kombu .. _langchain: LangChain ^^^^^^^^^ -.. automodule:: ddtrace.contrib.langchain +.. automodule:: ddtrace.contrib._langchain .. _logbook: Logbook ^^^^^^^^^ -.. automodule:: ddtrace.contrib.logbook +.. automodule:: ddtrace.contrib._logbook .. _loguru: Loguru ^^^^^^^^^ -.. automodule:: ddtrace.contrib.loguru +.. automodule:: ddtrace.contrib._loguru .. _mako: Mako ^^^^ -.. automodule:: ddtrace.contrib.mako +.. automodule:: ddtrace.contrib._mako .. _mariadb: MariaDB ^^^^^^^ -.. automodule:: ddtrace.contrib.mariadb +.. automodule:: ddtrace.contrib._mariadb .. _molten: Molten ^^^^^^ -.. automodule:: ddtrace.contrib.molten +.. automodule:: ddtrace.contrib._molten .. _mongoengine: Mongoengine ^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.mongoengine +.. automodule:: ddtrace.contrib._mongoengine .. _mysql-connector: mysql-connector ^^^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.mysql +.. automodule:: ddtrace.contrib._mysql .. _mysqlclient: @@ -315,14 +315,14 @@ mysql-connector mysqlclient ^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.mysqldb +.. automodule:: ddtrace.contrib._mysqldb .. _openai: OpenAI ^^^^^^ -.. automodule:: ddtrace.contrib.openai +.. automodule:: ddtrace.contrib._openai .. _pylibmc: @@ -336,35 +336,35 @@ pylibmc PynamoDB ^^^^^^^^ -.. automodule:: ddtrace.contrib.pynamodb +.. automodule:: ddtrace.contrib._pynamodb .. _pyodbc: PyODBC ^^^^^^^^ -.. automodule:: ddtrace.contrib.pyodbc +.. automodule:: ddtrace.contrib._pyodbc .. _pymemcache: pymemcache ^^^^^^^^^^ -.. automodule:: ddtrace.contrib.pymemcache +.. automodule:: ddtrace.contrib._pymemcache .. _pymongo: Pymongo ^^^^^^^ -.. automodule:: ddtrace.contrib.pymongo +.. automodule:: ddtrace.contrib._pymongo .. _pymysql: pymysql ^^^^^^^ -.. automodule:: ddtrace.contrib.pymysql +.. automodule:: ddtrace.contrib._pymysql .. _pyramid: @@ -378,34 +378,34 @@ Pyramid pytest ^^^^^^ -.. automodule:: ddtrace.contrib.pytest +.. automodule:: ddtrace.contrib._pytest .. _pytest_bdd: pytest-bdd ^^^^^^^^^^ -.. automodule:: ddtrace.contrib.pytest_bdd +.. automodule:: ddtrace.contrib._pytest_bdd .. _psycopg: psycopg ^^^^^^^ -.. automodule:: ddtrace.contrib.psycopg +.. automodule:: ddtrace.contrib._psycopg .. _redis: redis ^^^^^ -.. automodule:: ddtrace.contrib.redis +.. automodule:: ddtrace.contrib._redis .. _rediscluster: redis-py-cluster ^^^^^^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.rediscluster +.. automodule:: ddtrace.contrib._rediscluster .. _requests: @@ -419,35 +419,35 @@ Requests RQ ^^^^^^^^ -.. automodule:: ddtrace.contrib.rq +.. automodule:: ddtrace.contrib._rq .. _sanic: Sanic ^^^^^ -.. automodule:: ddtrace.contrib.sanic +.. automodule:: ddtrace.contrib._sanic .. _snowflake: Snowflake ^^^^^^^^^ -.. automodule:: ddtrace.contrib.snowflake +.. automodule:: ddtrace.contrib._snowflake .. _starlette: Starlette ^^^^^^^^^ -.. automodule:: ddtrace.contrib.starlette +.. automodule:: ddtrace.contrib._starlette .. _structlog: Structlog ^^^^^^^^^ -.. automodule:: ddtrace.contrib.structlog +.. automodule:: ddtrace.contrib._structlog .. _sqlalchemy: @@ -461,7 +461,7 @@ SQLAlchemy SQLite ^^^^^^ -.. automodule:: ddtrace.contrib.sqlite3 +.. automodule:: ddtrace.contrib._sqlite3 .. _tornado: @@ -475,34 +475,34 @@ Tornado unittest ^^^^^^^^ -.. automodule:: ddtrace.contrib.unittest +.. automodule:: ddtrace.contrib._unittest .. _urllib3: urllib3 ^^^^^^^ -.. automodule:: ddtrace.contrib.urllib3 +.. automodule:: ddtrace.contrib._urllib3 .. _vertexai: vertexai ^^^^^^^^ -.. automodule:: ddtrace.contrib.vertexai +.. automodule:: ddtrace.contrib._vertexai .. _vertica: Vertica ^^^^^^^ -.. automodule:: ddtrace.contrib.vertica +.. automodule:: ddtrace.contrib._vertica .. _yaaredis: yaaredis ^^^^^^^^ -.. automodule:: ddtrace.contrib.yaaredis +.. automodule:: ddtrace.contrib._yaaredis .. _wsgi: diff --git a/hatch.toml b/hatch.toml index 6dcd32e6794..3e80f24a5e7 100644 --- a/hatch.toml +++ b/hatch.toml @@ -400,6 +400,45 @@ python = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] flask = ["~=3.0"] +[envs.appsec_integrations_fastapi] +template = "appsec_integrations_fastapi" +dependencies = [ + "pytest", + "pytest-cov", + "requests", + "hypothesis", + "jinja2", + "httpx<0.28.0", + "anyio{matrix:anyio:}", + "fastapi{matrix:fastapi}" +] + +[envs.appsec_integrations_fastapi.env-vars] +CMAKE_BUILD_PARALLEL_LEVEL = "12" + +[envs.appsec_integrations_fastapi.scripts] +test = [ + "uname -a", + "pip freeze", + "DD_TRACE_AGENT_URL=\"http://testagent:9126\" DD_CIVISIBILITY_ITR_ENABLED=0 DD_IAST_REQUEST_SAMPLING=100 DD_IAST_DEDUPLICATION_ENABLED=false python -m pytest -vvv {args:tests/appsec/integrations/fastapi_tests/}", +] + + +# if you add or remove a version here, please also update the parallelism parameter +# in .circleci/config.templ.yml +[[envs.appsec_integrations_fastapi.matrix]] +python = ["3.8", "3.10", "3.13"] +fastapi = ["==0.86.0"] +anyio = ["==3.7.1"] + +[[envs.appsec_integrations_fastapi.matrix]] +python = ["3.8", "3.10", "3.13"] +fastapi = ["==0.94.1"] + +[[envs.appsec_integrations_fastapi.matrix]] +python = ["3.8", "3.10", "3.13"] +fastapi = ["~=0.114.2"] + ## ASM FastAPI @@ -466,7 +505,8 @@ _DD_IAST_PATCH_MODULES = "scripts.iast" test = [ "uname -a", "pip freeze", - "python -m pytest tests/appsec/iast_aggregated_memcheck/test_aggregated_memleaks.py", + # We use --no-cov due to a pytest-cov problem with eval https://github.com/pytest-dev/pytest-cov/issues/676 + "python -m pytest --no-cov tests/appsec/iast_aggregated_memcheck/test_aggregated_memleaks.py", ] [[envs.iast_aggregated_leak_testing.matrix]] diff --git a/releasenotes/notes/iast-feat-xss-django-6781a8b9a4092832.yaml b/releasenotes/notes/iast-feat-xss-django-6781a8b9a4092832.yaml new file mode 100644 index 00000000000..db470196b36 --- /dev/null +++ b/releasenotes/notes/iast-feat-xss-django-6781a8b9a4092832.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Code Security (IAST): XSS detection for Django applications, + which will be displayed on your DataDog Vulnerability Explorer dashboard. + See the `Application Vulnerability Management `_ documentation for more information about this feature. diff --git a/releasenotes/notes/no_IAST_unguarded_loading_in_common_module_patches-123cf6d3f8844823.yaml b/releasenotes/notes/no_IAST_unguarded_loading_in_common_module_patches-123cf6d3f8844823.yaml new file mode 100644 index 00000000000..c88f0e042e5 --- /dev/null +++ b/releasenotes/notes/no_IAST_unguarded_loading_in_common_module_patches-123cf6d3f8844823.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + ASM: This fix resolves an issue where IAST modules could be loaded, even if disabled, + which could create an ImportError exception on Windows. \ No newline at end of file diff --git a/releasenotes/notes/remove-deprecated-code-integrations-ae6970bbf9b10047.yaml b/releasenotes/notes/remove-deprecated-code-integrations-ae6970bbf9b10047.yaml new file mode 100644 index 00000000000..8b007a636d4 --- /dev/null +++ b/releasenotes/notes/remove-deprecated-code-integrations-ae6970bbf9b10047.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + integrations: Removes deprecated interfaces from all integrations. \ No newline at end of file diff --git a/releasenotes/notes/remove-deprecated-tracing-modules-a129231d42e1218d.yaml b/releasenotes/notes/remove-deprecated-tracing-modules-a129231d42e1218d.yaml new file mode 100644 index 00000000000..575bb8f1e55 --- /dev/null +++ b/releasenotes/notes/remove-deprecated-tracing-modules-a129231d42e1218d.yaml @@ -0,0 +1,4 @@ +--- +other: + - | + tracing: Removes the deprecated tracing modules and constants from the ``ddtrace`` package. diff --git a/releasenotes/notes/remove-tracing-attrs-3-0-5743fa668289d5bc.yaml b/releasenotes/notes/remove-tracing-attrs-3-0-5743fa668289d5bc.yaml new file mode 100644 index 00000000000..35ee9378801 --- /dev/null +++ b/releasenotes/notes/remove-tracing-attrs-3-0-5743fa668289d5bc.yaml @@ -0,0 +1,15 @@ +--- +upgrade: + - | + tracer: Removes deprecated parameters from ``Tracer.configure(...)`` method and removes the ``Tracer.sampler`` attribute. + - | + tracing: Drops support for multiple tracer instances, ``ddtrace.trace.Tracer`` can not be reinitialized. + - | + span: Removes the deprecated ``Span.sampled`` property + - | + sampling: Drops support for configuring sampling rules using functions and regex in the ``ddtrace.tracer.sampler.rules[].choose_matcher(...)`` method + and removes the ``timestamp_ns`` parameter from ``ddtrace.internal.rate_limiter.RateLimiter.is_allowed()``. + - | + configurations: Drops support for configuring ``DD_TRACE_METHODS`` with the '[]' notation. Ensure DD_TRACE_METHODS use the ':' notation instead". + - | + opentracing: Removes the deprecated ``ddtracer`` parameter from ``ddtrace.opentracer.tracer.Tracer()``. \ No newline at end of file diff --git a/scripts/iast/mod_leak_functions.py b/scripts/iast/mod_leak_functions.py index bf96d93c497..f53e7aa2e94 100644 --- a/scripts/iast/mod_leak_functions.py +++ b/scripts/iast/mod_leak_functions.py @@ -258,6 +258,7 @@ def sink_points(string_tainted): except Exception: pass + _ = eval(f"'a' + '{string_tainted}'") # Weak Randomness vulnerability _ = random.randint(1, 10) diff --git a/tests/appsec/iast/taint_sinks/_taint_sinks_utils.py b/tests/appsec/iast/taint_sinks/_taint_sinks_utils.py index 288b72d015c..ae69fbda120 100644 --- a/tests/appsec/iast/taint_sinks/_taint_sinks_utils.py +++ b/tests/appsec/iast/taint_sinks/_taint_sinks_utils.py @@ -22,6 +22,7 @@ def get_parametrize(vuln_type, ignore_list=None): "$1 - Tainted range based redaction - multiple ranges", "Redacted source that needs to be truncated", "Query with single quoted string literal and null source", + "No redacted that needs to be truncated - whole text", ): continue diff --git a/tests/appsec/iast/taint_sinks/test_xss_redacted.py b/tests/appsec/iast/taint_sinks/test_xss_redacted.py new file mode 100644 index 00000000000..c192962e53e --- /dev/null +++ b/tests/appsec/iast/taint_sinks/test_xss_redacted.py @@ -0,0 +1,48 @@ +import os + +import pytest + +from ddtrace.appsec._iast._taint_tracking import origin_to_str +from ddtrace.appsec._iast._taint_tracking import str_to_origin +from ddtrace.appsec._iast.constants import VULN_XSS +from ddtrace.appsec._iast.taint_sinks.xss import XSS +from tests.appsec.iast.taint_sinks._taint_sinks_utils import _taint_pyobject_multiranges +from tests.appsec.iast.taint_sinks._taint_sinks_utils import get_parametrize +from tests.appsec.iast.taint_sinks.conftest import _get_iast_data + + +ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +@pytest.mark.parametrize( + "evidence_input, sources_expected, vulnerabilities_expected,element", list(get_parametrize(VULN_XSS)) +) +def test_xss_redaction_suite( + evidence_input, sources_expected, vulnerabilities_expected, iast_context_defaults, element +): + tainted_object = evidence_input_value = evidence_input.get("value", "") + if evidence_input_value: + tainted_object = _taint_pyobject_multiranges( + evidence_input_value, + [ + ( + input_ranges["iinfo"]["parameterName"], + input_ranges["iinfo"]["parameterValue"], + str_to_origin(input_ranges["iinfo"]["type"]), + input_ranges["start"], + input_ranges["end"] - input_ranges["start"], + ) + for input_ranges in evidence_input.get("ranges", {}) + ], + ) + + XSS.report(tainted_object) + + data = _get_iast_data() + vulnerability = list(data["vulnerabilities"])[0] + source = list(data["sources"])[0] + source["origin"] = origin_to_str(source["origin"]) + + assert vulnerability["type"] == VULN_XSS + assert vulnerability["evidence"] == vulnerabilities_expected["evidence"] + assert source == sources_expected diff --git a/tests/appsec/integrations/django_tests/conftest.py b/tests/appsec/integrations/django_tests/conftest.py index d150edf68be..57bd68db6a6 100644 --- a/tests/appsec/integrations/django_tests/conftest.py +++ b/tests/appsec/integrations/django_tests/conftest.py @@ -5,6 +5,7 @@ import pytest from ddtrace.appsec._iast import enable_iast_propagation +from ddtrace.appsec._iast._patch_modules import patch_iast from ddtrace.contrib.internal.django.patch import patch from ddtrace.trace import Pin from tests.appsec.iast.conftest import _end_iast_context_and_oce @@ -27,11 +28,22 @@ def pytest_configure(): ) ): settings.DEBUG = False - enable_iast_propagation() + patch_iast() patch() + enable_iast_propagation() django.setup() +@pytest.fixture +def debug_mode(): + from django.conf import settings + + original_debug = settings.DEBUG + settings.DEBUG = True + yield + settings.DEBUG = original_debug + + @pytest.fixture def tracer(): tracer = DummyTracer() diff --git a/tests/appsec/integrations/django_tests/django_app/settings.py b/tests/appsec/integrations/django_tests/django_app/settings.py index 9464c37fd43..cbd7eea9c25 100644 --- a/tests/appsec/integrations/django_tests/django_app/settings.py +++ b/tests/appsec/integrations/django_tests/django_app/settings.py @@ -4,12 +4,7 @@ from tests.webclient import PingFilter -tracer.configure( - settings={ - "FILTERS": [PingFilter()], - } -) - +tracer._configure(trace_processors=[PingFilter()]) ALLOWED_HOSTS = [ "testserver", @@ -45,7 +40,7 @@ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [ - os.path.join(BASE_DIR, "templates"), + os.path.join(BASE_DIR, "django_app", "templates"), ], "APP_DIRS": True, "OPTIONS": { diff --git a/tests/appsec/integrations/django_tests/django_app/templates/index.html b/tests/appsec/integrations/django_tests/django_app/templates/index.html new file mode 100644 index 00000000000..7135619ca9d --- /dev/null +++ b/tests/appsec/integrations/django_tests/django_app/templates/index.html @@ -0,0 +1,5 @@ + + +

Input: {{ user_input }}

+ + \ No newline at end of file diff --git a/tests/appsec/integrations/django_tests/django_app/templates/index_autoescape.html b/tests/appsec/integrations/django_tests/django_app/templates/index_autoescape.html new file mode 100644 index 00000000000..ef5f5a64ed4 --- /dev/null +++ b/tests/appsec/integrations/django_tests/django_app/templates/index_autoescape.html @@ -0,0 +1,7 @@ + + +

{% autoescape on %} + {{ user_input }} +{% endautoescape %}

+ + diff --git a/tests/appsec/integrations/django_tests/django_app/templates/index_safe.html b/tests/appsec/integrations/django_tests/django_app/templates/index_safe.html new file mode 100644 index 00000000000..8bc39da3351 --- /dev/null +++ b/tests/appsec/integrations/django_tests/django_app/templates/index_safe.html @@ -0,0 +1,5 @@ + + +

Input: {{ user_input|safe }}

+ + \ No newline at end of file diff --git a/tests/appsec/integrations/django_tests/django_app/urls.py b/tests/appsec/integrations/django_tests/django_app/urls.py index dd1d069ad77..e79b6bee284 100644 --- a/tests/appsec/integrations/django_tests/django_app/urls.py +++ b/tests/appsec/integrations/django_tests/django_app/urls.py @@ -73,6 +73,10 @@ def shutdown(request): handler("appsec/insecure-cookie/test_insecure/$", views.view_insecure_cookies_insecure), handler("appsec/insecure-cookie/test_secure/$", views.view_insecure_cookies_secure), handler("appsec/insecure-cookie/test_empty_cookie/$", views.view_insecure_cookies_empty), + handler("appsec/xss/$", views.xss_http_request_parameter_mark_safe), + handler("appsec/xss/secure/$", views.xss_secure), + handler("appsec/xss/safe/$", views.xss_http_request_parameter_template_safe), + handler("appsec/xss/autoscape/$", views.xss_http_request_parameter_autoscape), path( "appsec/sqli_http_path_parameter//", views.sqli_http_path_parameter, diff --git a/tests/appsec/integrations/django_tests/django_app/views.py b/tests/appsec/integrations/django_tests/django_app/views.py index 693a9eab365..685b3c598c2 100644 --- a/tests/appsec/integrations/django_tests/django_app/views.py +++ b/tests/appsec/integrations/django_tests/django_app/views.py @@ -8,6 +8,8 @@ from django.db import connection from django.http import HttpResponse from django.http import JsonResponse +from django.shortcuts import render +from django.utils.safestring import mark_safe from ddtrace.appsec import _asm_request_context from ddtrace.appsec._iast._taint_tracking import OriginType @@ -68,6 +70,34 @@ def checkuser_view(request, user_id): return HttpResponse(status=200) +def xss_http_request_parameter_mark_safe(request): + user_input = request.GET.get("input", "") + + # label xss_http_request_parameter_mark_safe + return render(request, "index.html", {"user_input": mark_safe(user_input)}) + + +def xss_secure(request): + user_input = request.GET.get("input", "") + + # label xss_http_request_parameter_mark_safe + return render(request, "index.html", {"user_input": user_input}) + + +def xss_http_request_parameter_template_safe(request): + user_input = request.GET.get("input", "") + + # label xss_http_request_parameter_template_safe + return render(request, "index_safe.html", {"user_input": user_input}) + + +def xss_http_request_parameter_autoscape(request): + user_input = request.GET.get("input", "") + + # label xss_http_request_parameter_autoscape + return render(request, "index_autoescape.html", {"user_input": user_input}) + + def sqli_http_request_parameter(request): import bcrypt from django.contrib.auth.hashers import BCryptSHA256PasswordHasher diff --git a/tests/appsec/integrations/django_tests/test_django_appsec_iast.py b/tests/appsec/integrations/django_tests/test_django_appsec_iast.py index dd400c64df6..657688f5760 100644 --- a/tests/appsec/integrations/django_tests/test_django_appsec_iast.py +++ b/tests/appsec/integrations/django_tests/test_django_appsec_iast.py @@ -3,20 +3,16 @@ import pytest -from ddtrace.appsec._asm_request_context import start_context +from ddtrace.appsec._common_module_patches import patch_common_modules from ddtrace.appsec._constants import IAST -from ddtrace.appsec._iast import oce -from ddtrace.appsec._iast._patch_modules import patch_iast from ddtrace.appsec._iast.constants import VULN_CMDI from ddtrace.appsec._iast.constants import VULN_HEADER_INJECTION from ddtrace.appsec._iast.constants import VULN_INSECURE_COOKIE from ddtrace.appsec._iast.constants import VULN_SQL_INJECTION from ddtrace.appsec._iast.constants import VULN_STACKTRACE_LEAK -from ddtrace.ext import SpanTypes from ddtrace.internal.compat import urlencode from ddtrace.settings.asm import config as asm_config from tests.appsec.iast.iast_utils import get_line_and_hash -from tests.utils import override_env from tests.utils import override_global_config @@ -25,7 +21,9 @@ @pytest.fixture(autouse=True) def iast_context(): - with override_env({IAST.ENV: "True", IAST.ENV_REQUEST_SAMPLING: "100", "DD_IAST_DEDUPLICATION_ENABLED": "false"}): + with override_global_config( + dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) + ): yield @@ -85,32 +83,28 @@ def _aux_appsec_get_root_span_with_exception( @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_weak_hash(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - patch_iast({"weak_hash": True}) - root_span, _ = _aux_appsec_get_root_span(client, test_spans, tracer, url="/appsec/weak-hash/") - str_json = root_span.get_tag(IAST.JSON) - assert str_json is not None, "no JSON tag in root span" - vulnerability = json.loads(str_json)["vulnerabilities"][0] - assert vulnerability["location"]["path"].endswith(TEST_FILE) - assert vulnerability["evidence"]["value"] == "md5" + root_span, _ = _aux_appsec_get_root_span(client, test_spans, tracer, url="/appsec/weak-hash/") + str_json = root_span.get_tag(IAST.JSON) + assert str_json is not None, "no JSON tag in root span" + vulnerability = json.loads(str_json)["vulnerabilities"][0] + assert vulnerability["location"]["path"].endswith(TEST_FILE) + assert vulnerability["evidence"]["value"] == "md5" @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_user_agent_iast_enabled(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), - content_type="application/x-www-form-urlencoded", - url="/appsec/taint-checking-enabled/?q=aaa", - headers={"HTTP_USER_AGENT": "test/1.2.3"}, - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), + content_type="application/x-www-form-urlencoded", + url="/appsec/taint-checking-enabled/?q=aaa", + headers={"HTTP_USER_AGENT": "test/1.2.3"}, + ) - assert response.status_code == 200 - assert response.content == b"test/1.2.3" + assert response.status_code == 200 + assert response.content == b"test/1.2.3" @pytest.mark.parametrize( @@ -156,8 +150,6 @@ def test_django_view_with_exception(client, test_spans, tracer, payload, content @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_user_agent_iast_disabled(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False, _iast_deduplication_enabled=False)): - oce.reconfigure() - root_span, response = _aux_appsec_get_root_span( client, test_spans, @@ -177,191 +169,181 @@ def test_django_tainted_user_agent_iast_disabled(client, test_spans, tracer): @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_user_agent_iast_enabled_sqli_http_request_parameter(client, test_spans, tracer): - with override_global_config( - dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) - ): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), - content_type="application/x-www-form-urlencoded", - url="/appsec/sqli_http_request_parameter/?q=SELECT 1 FROM sqlite_master WHERE name='", - headers={"HTTP_USER_AGENT": "test/1.2.3"}, - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), + content_type="application/x-www-form-urlencoded", + url="/appsec/sqli_http_request_parameter/?q=SELECT 1 FROM sqlite_master WHERE name='", + headers={"HTTP_USER_AGENT": "test/1.2.3"}, + ) - vuln_type = "SQL_INJECTION" + vuln_type = "SQL_INJECTION" - assert response.status_code == 200 - assert response.content == b"test/1.2.3" + assert response.status_code == 200 + assert response.content == b"test/1.2.3" - loaded = json.loads(root_span.get_tag(IAST.JSON)) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - line, hash_value = get_line_and_hash("iast_enabled_sqli_http_request_parameter", vuln_type, filename=TEST_FILE) + line, hash_value = get_line_and_hash("iast_enabled_sqli_http_request_parameter", vuln_type, filename=TEST_FILE) - assert loaded["sources"] == [ - { - "name": "q", - "origin": "http.request.parameter", - "pattern": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN", - "redacted": True, - } - ] - - assert loaded["vulnerabilities"][0]["type"] == vuln_type - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [ - {"source": 0, "value": "SELECT "}, - {"pattern": "h", "redacted": True, "source": 0}, - {"source": 0, "value": " FROM sqlite_master WHERE name='"}, - {"redacted": True}, - {"value": "'"}, - ] + assert loaded["sources"] == [ + { + "name": "q", + "origin": "http.request.parameter", + "pattern": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN", + "redacted": True, } - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["hash"] == hash_value + ] + + assert loaded["vulnerabilities"][0]["type"] == vuln_type + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"source": 0, "value": "SELECT "}, + {"pattern": "h", "redacted": True, "source": 0}, + {"source": 0, "value": " FROM sqlite_master WHERE name='"}, + {"redacted": True}, + {"value": "'"}, + ] + } + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_parameter_name_get(client, test_spans, tracer): - with override_global_config( - dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) - ): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - content_type="application/x-www-form-urlencoded", - url="/appsec/sqli_http_request_parameter_name_get/?SELECT=unused", - headers={"HTTP_USER_AGENT": "test/1.2.3"}, - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + content_type="application/x-www-form-urlencoded", + url="/appsec/sqli_http_request_parameter_name_get/?SELECT=unused", + headers={"HTTP_USER_AGENT": "test/1.2.3"}, + ) - vuln_type = "SQL_INJECTION" + vuln_type = "SQL_INJECTION" - assert response.status_code == 200 - assert response.content == b"test/1.2.3" + assert response.status_code == 200 + assert response.content == b"test/1.2.3" - loaded = json.loads(root_span.get_tag(IAST.JSON)) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - line, hash_value = get_line_and_hash( - "iast_enabled_sqli_http_request_parameter_name_get", vuln_type, filename=TEST_FILE - ) + line, hash_value = get_line_and_hash( + "iast_enabled_sqli_http_request_parameter_name_get", vuln_type, filename=TEST_FILE + ) - assert loaded["sources"] == [ + assert loaded["sources"] == [ + { + "name": "SELECT", + "origin": "http.request.parameter.name", + "value": "SELECT", + } + ] + + assert loaded["vulnerabilities"][0]["type"] == vuln_type + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"source": 0, "value": "SELECT"}, { - "name": "SELECT", - "origin": "http.request.parameter.name", - "value": "SELECT", - } + "value": " ", + }, + { + "redacted": True, + }, ] - - assert loaded["vulnerabilities"][0]["type"] == vuln_type - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [ - {"source": 0, "value": "SELECT"}, - { - "value": " ", - }, - { - "redacted": True, - }, - ] - } - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["hash"] == hash_value + } + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_parameter_name_post(client, test_spans, tracer): - with override_global_config( - dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) - ): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - payload=urlencode({"SELECT": "unused"}), - content_type="application/x-www-form-urlencoded", - url="/appsec/sqli_http_request_parameter_name_post/", - headers={"HTTP_USER_AGENT": "test/1.2.3"}, - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + payload=urlencode({"SELECT": "unused"}), + content_type="application/x-www-form-urlencoded", + url="/appsec/sqli_http_request_parameter_name_post/", + headers={"HTTP_USER_AGENT": "test/1.2.3"}, + ) - vuln_type = "SQL_INJECTION" + vuln_type = "SQL_INJECTION" - assert response.status_code == 200 - assert response.content == b"test/1.2.3" + assert response.status_code == 200 + assert response.content == b"test/1.2.3" + + loaded = json.loads(root_span.get_tag(IAST.JSON)) - loaded = json.loads(root_span.get_tag(IAST.JSON)) + line, hash_value = get_line_and_hash( + "iast_enabled_sqli_http_request_parameter_name_post", vuln_type, filename=TEST_FILE + ) - line, hash_value = get_line_and_hash( - "iast_enabled_sqli_http_request_parameter_name_post", vuln_type, filename=TEST_FILE - ) + assert loaded["sources"] == [ + { + "name": "SELECT", + "origin": "http.request.parameter.name", + "value": "SELECT", + } + ] - assert loaded["sources"] == [ + assert loaded["vulnerabilities"][0]["type"] == vuln_type + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"source": 0, "value": "SELECT"}, + { + "value": " ", + }, { - "name": "SELECT", - "origin": "http.request.parameter.name", - "value": "SELECT", - } + "redacted": True, + }, ] - - assert loaded["vulnerabilities"][0]["type"] == vuln_type - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [ - {"source": 0, "value": "SELECT"}, - { - "value": " ", - }, - { - "redacted": True, - }, - ] - } - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["hash"] == hash_value + } + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_header_value(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), - content_type="application/x-www-form-urlencoded", - url="/appsec/sqli_http_request_header_value/", - headers={"HTTP_USER_AGENT": "master"}, - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), + content_type="application/x-www-form-urlencoded", + url="/appsec/sqli_http_request_header_value/", + headers={"HTTP_USER_AGENT": "master"}, + ) - assert response.status_code == 200 - assert response.content == b"master" + assert response.status_code == 200 + assert response.content == b"master" - loaded = json.loads(root_span.get_tag(IAST.JSON)) - - assert loaded["sources"] == [{"origin": "http.request.header", "name": "HTTP_USER_AGENT", "value": "master"}] - assert loaded["vulnerabilities"][0]["type"] == VULN_SQL_INJECTION - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [ - {"value": "SELECT "}, - {"redacted": True}, - {"value": " FROM sqlite_"}, - {"source": 0, "value": "master"}, - ] - } + loaded = json.loads(root_span.get_tag(IAST.JSON)) - line, hash_value = get_line_and_hash( - "iast_enabled_sqli_http_request_header_value", VULN_SQL_INJECTION, filename=TEST_FILE - ) - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["hash"] == hash_value + assert loaded["sources"] == [{"origin": "http.request.header", "name": "HTTP_USER_AGENT", "value": "master"}] + assert loaded["vulnerabilities"][0]["type"] == VULN_SQL_INJECTION + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"value": "SELECT "}, + {"redacted": True}, + {"value": " FROM sqlite_"}, + {"source": 0, "value": "master"}, + ] + } + + line, hash_value = get_line_and_hash( + "iast_enabled_sqli_http_request_header_value", VULN_SQL_INJECTION, filename=TEST_FILE + ) + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value @pytest.mark.django_db() @@ -387,39 +369,38 @@ def test_django_iast_disabled_sqli_http_request_header_value(client, test_spans, @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_header_name(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), - content_type="application/x-www-form-urlencoded", - url="/appsec/sqli_http_request_header_name/", - headers={"master": "test/1.2.3"}, - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + payload=urlencode({"mytestingbody_key": "mytestingbody_value"}), + content_type="application/x-www-form-urlencoded", + url="/appsec/sqli_http_request_header_name/", + headers={"master": "test/1.2.3"}, + ) - assert response.status_code == 200 - assert response.content == b"test/1.2.3" + assert response.status_code == 200 + assert response.content == b"test/1.2.3" - loaded = json.loads(root_span.get_tag(IAST.JSON)) - - assert loaded["sources"] == [{"origin": "http.request.header.name", "name": "master", "value": "master"}] - assert loaded["vulnerabilities"][0]["type"] == VULN_SQL_INJECTION - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [ - {"value": "SELECT "}, - {"redacted": True}, - {"value": " FROM sqlite_"}, - {"value": "master", "source": 0}, - ] - } + loaded = json.loads(root_span.get_tag(IAST.JSON)) - line, hash_value = get_line_and_hash( - "iast_enabled_sqli_http_request_header_name", VULN_SQL_INJECTION, filename=TEST_FILE - ) - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["hash"] == hash_value + assert loaded["sources"] == [{"origin": "http.request.header.name", "name": "master", "value": "master"}] + assert loaded["vulnerabilities"][0]["type"] == VULN_SQL_INJECTION + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"value": "SELECT "}, + {"redacted": True}, + {"value": " FROM sqlite_"}, + {"value": "master", "source": 0}, + ] + } + + line, hash_value = get_line_and_hash( + "iast_enabled_sqli_http_request_header_name", VULN_SQL_INJECTION, filename=TEST_FILE + ) + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value @pytest.mark.django_db() @@ -498,41 +479,38 @@ def test_django_iast_disabled_sqli_http_path_parameter(client, test_spans, trace @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_cookies_name(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/sqli_http_request_cookie_name/", - cookies={"master": "test/1.2.3"}, - ) - assert response.status_code == 200 - assert response.content == b"test/1.2.3" + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/sqli_http_request_cookie_name/", + cookies={"master": "test/1.2.3"}, + ) + assert response.status_code == 200 + assert response.content == b"test/1.2.3" - loaded = json.loads(root_span.get_tag(IAST.JSON)) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - vulnerability = False - for vuln in loaded["vulnerabilities"]: - if vuln["type"] == VULN_SQL_INJECTION: - vulnerability = vuln + vulnerability = False + for vuln in loaded["vulnerabilities"]: + if vuln["type"] == VULN_SQL_INJECTION: + vulnerability = vuln - assert vulnerability, "No {} reported".format(VULN_SQL_INJECTION) + assert vulnerability, "No {} reported".format(VULN_SQL_INJECTION) - assert loaded["sources"] == [{"origin": "http.request.cookie.name", "name": "master", "value": "master"}] - assert vulnerability["evidence"] == { - "valueParts": [ - {"value": "SELECT "}, - {"redacted": True}, - {"value": " FROM sqlite_"}, - {"value": "master", "source": 0}, - ] - } - line, hash_value = get_line_and_hash( - "iast_enabled_sqli_http_cookies_name", VULN_SQL_INJECTION, filename=TEST_FILE - ) - assert vulnerability["location"]["path"] == TEST_FILE - assert vulnerability["location"]["line"] == line - assert vulnerability["hash"] == hash_value + assert loaded["sources"] == [{"origin": "http.request.cookie.name", "name": "master", "value": "master"}] + assert vulnerability["evidence"] == { + "valueParts": [ + {"value": "SELECT "}, + {"redacted": True}, + {"value": " FROM sqlite_"}, + {"value": "master", "source": 0}, + ] + } + line, hash_value = get_line_and_hash("iast_enabled_sqli_http_cookies_name", VULN_SQL_INJECTION, filename=TEST_FILE) + assert vulnerability["location"]["path"] == TEST_FILE + assert vulnerability["location"]["line"] == line + assert vulnerability["hash"] == hash_value @pytest.mark.django_db() @@ -556,43 +534,40 @@ def test_django_iast_disabled_sqli_http_cookies_name(client, test_spans, tracer) @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_cookies_value(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/sqli_http_request_cookie_value/", - cookies={"master": "master"}, - ) - assert response.status_code == 200 - assert response.content == b"master" + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/sqli_http_request_cookie_value/", + cookies={"master": "master"}, + ) + assert response.status_code == 200 + assert response.content == b"master" - loaded = json.loads(root_span.get_tag(IAST.JSON)) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - vulnerability = False - for vuln in loaded["vulnerabilities"]: - if vuln["type"] == VULN_SQL_INJECTION: - vulnerability = vuln + vulnerability = False + for vuln in loaded["vulnerabilities"]: + if vuln["type"] == VULN_SQL_INJECTION: + vulnerability = vuln - assert vulnerability, "No {} reported".format(VULN_SQL_INJECTION) - assert loaded["sources"] == [{"origin": "http.request.cookie.value", "name": "master", "value": "master"}] - assert vulnerability["type"] == "SQL_INJECTION" + assert vulnerability, "No {} reported".format(VULN_SQL_INJECTION) + assert loaded["sources"] == [{"origin": "http.request.cookie.value", "name": "master", "value": "master"}] + assert vulnerability["type"] == "SQL_INJECTION" - assert vulnerability["evidence"] == { - "valueParts": [ - {"value": "SELECT "}, - {"redacted": True}, - {"value": " FROM sqlite_"}, - {"value": "master", "source": 0}, - ] - } + assert vulnerability["evidence"] == { + "valueParts": [ + {"value": "SELECT "}, + {"redacted": True}, + {"value": " FROM sqlite_"}, + {"value": "master", "source": 0}, + ] + } - line, hash_value = get_line_and_hash( - "iast_enabled_sqli_http_cookies_value", VULN_SQL_INJECTION, filename=TEST_FILE - ) - assert vulnerability["location"]["line"] == line - assert vulnerability["location"]["path"] == TEST_FILE - assert vulnerability["hash"] == hash_value + line, hash_value = get_line_and_hash("iast_enabled_sqli_http_cookies_value", VULN_SQL_INJECTION, filename=TEST_FILE) + assert vulnerability["location"]["line"] == line + assert vulnerability["location"]["path"] == TEST_FILE + assert vulnerability["hash"] == hash_value @pytest.mark.django_db() @@ -623,35 +598,34 @@ def test_django_iast_disabled_sqli_http_cookies_value(client, test_spans, tracer @pytest.mark.django_db() @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_body(client, test_spans, tracer, payload, content_type): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/sqli_http_request_body/", - payload=payload, - content_type=content_type, - ) - loaded = json.loads(root_span.get_tag(IAST.JSON)) - - line, hash_value = get_line_and_hash("iast_enabled_sqli_http_body", VULN_SQL_INJECTION, filename=TEST_FILE) - - assert loaded["sources"] == [{"origin": "http.request.body", "name": "http.request.body", "value": "master"}] - assert loaded["vulnerabilities"][0]["type"] == VULN_SQL_INJECTION - assert loaded["vulnerabilities"][0]["hash"] == hash_value - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [ - {"value": "SELECT "}, - {"redacted": True}, - {"value": " FROM sqlite_"}, - {"value": "master", "source": 0}, - ] - } - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/sqli_http_request_body/", + payload=payload, + content_type=content_type, + ) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - assert response.status_code == 200 - assert response.content == b"master" + line, hash_value = get_line_and_hash("iast_enabled_sqli_http_body", VULN_SQL_INJECTION, filename=TEST_FILE) + + assert loaded["sources"] == [{"origin": "http.request.body", "name": "http.request.body", "value": "master"}] + assert loaded["vulnerabilities"][0]["type"] == VULN_SQL_INJECTION + assert loaded["vulnerabilities"][0]["hash"] == hash_value + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"value": "SELECT "}, + {"redacted": True}, + {"value": " FROM sqlite_"}, + {"value": "master", "source": 0}, + ] + } + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + + assert response.status_code == 200 + assert response.content == b"master" @pytest.mark.parametrize( @@ -718,244 +692,314 @@ def test_django_iast_disabled_sqli_http_body(client, test_spans, tracer): @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_querydict(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True)): - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/validate_querydict/?x=1&y=2&x=3", - ) + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/validate_querydict/?x=1&y=2&x=3", + ) - assert root_span.get_tag(IAST.JSON) is None - assert response.status_code == 200 - assert ( - response.content == b"x=['1', '3'], all=[('x', ['1', '3']), ('y', ['2'])]," - b" keys=['x', 'y'], urlencode=x=1&x=3&y=2" - ) + assert root_span.get_tag(IAST.JSON) is None + assert response.status_code == 200 + assert ( + response.content == b"x=['1', '3'], all=[('x', ['1', '3']), ('y', ['2'])]," + b" keys=['x', 'y'], urlencode=x=1&x=3&y=2" + ) @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_command_injection(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - patch_iast({"command_injection": True}) - from ddtrace.appsec._common_module_patches import patch_common_modules - - patch_common_modules() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/command-injection/", - payload="master", - content_type="application/json", - ) + patch_common_modules() + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/command-injection/", + payload="master", + content_type="application/json", + ) - loaded = json.loads(root_span.get_tag(IAST.JSON)) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - line, hash_value = get_line_and_hash("iast_command_injection", VULN_CMDI, filename=TEST_FILE) + line, hash_value = get_line_and_hash("iast_command_injection", VULN_CMDI, filename=TEST_FILE) - assert loaded["sources"] == [ - {"name": "http.request.body", "origin": "http.request.body", "pattern": "abcdef", "redacted": True} - ] - assert loaded["vulnerabilities"][0]["type"] == VULN_CMDI - assert loaded["vulnerabilities"][0]["hash"] == hash_value - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [{"value": "dir "}, {"redacted": True}, {"pattern": "abcdef", "redacted": True, "source": 0}] - } - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["sources"] == [ + {"name": "http.request.body", "origin": "http.request.body", "pattern": "abcdef", "redacted": True} + ] + assert loaded["vulnerabilities"][0]["type"] == VULN_CMDI + assert loaded["vulnerabilities"][0]["hash"] == hash_value + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [{"value": "dir "}, {"redacted": True}, {"pattern": "abcdef", "redacted": True, "source": 0}] + } + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_header_injection(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - patch_iast({"header_injection": True}) - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/header-injection/", - payload="master", - content_type="application/json", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/header-injection/", + payload="master", + content_type="application/json", + ) - loaded = json.loads(root_span.get_tag(IAST.JSON)) + loaded = json.loads(root_span.get_tag(IAST.JSON)) - line, hash_value = get_line_and_hash("iast_header_injection", VULN_HEADER_INJECTION, filename=TEST_FILE) + line, hash_value = get_line_and_hash("iast_header_injection", VULN_HEADER_INJECTION, filename=TEST_FILE) - assert loaded["sources"] == [{"origin": "http.request.body", "name": "http.request.body", "value": "master"}] - assert loaded["vulnerabilities"][0]["type"] == VULN_HEADER_INJECTION - assert loaded["vulnerabilities"][0]["hash"] == hash_value - assert loaded["vulnerabilities"][0]["evidence"] == { - "valueParts": [{"value": "Header-Injection: "}, {"source": 0, "value": "master"}] - } - assert loaded["vulnerabilities"][0]["location"]["line"] == line - assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["sources"] == [{"origin": "http.request.body", "name": "http.request.body", "value": "master"}] + assert loaded["vulnerabilities"][0]["type"] == VULN_HEADER_INJECTION + assert loaded["vulnerabilities"][0]["hash"] == hash_value + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [{"value": "Header-Injection: "}, {"source": 0, "value": "master"}] + } + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/insecure-cookie/test_insecure/", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/insecure-cookie/test_insecure/", + ) - assert root_span.get_metric(IAST.ENABLED) == 1.0 + assert root_span.get_metric(IAST.ENABLED) == 1.0 - loaded = json.loads(root_span.get_tag(IAST.JSON)) - assert loaded["sources"] == [] - assert len(loaded["vulnerabilities"]) == 1 - vulnerability = loaded["vulnerabilities"][0] - assert vulnerability["type"] == VULN_INSECURE_COOKIE - assert vulnerability["evidence"] == {"valueParts": [{"value": "insecure"}]} - assert "path" not in vulnerability["location"].keys() - assert "line" not in vulnerability["location"].keys() - assert vulnerability["location"]["spanId"] - assert vulnerability["hash"] + loaded = json.loads(root_span.get_tag(IAST.JSON)) + assert loaded["sources"] == [] + assert len(loaded["vulnerabilities"]) == 1 + vulnerability = loaded["vulnerabilities"][0] + assert vulnerability["type"] == VULN_INSECURE_COOKIE + assert vulnerability["evidence"] == {"valueParts": [{"value": "insecure"}]} + assert "path" not in vulnerability["location"].keys() + assert "line" not in vulnerability["location"].keys() + assert vulnerability["location"]["spanId"] + assert vulnerability["hash"] @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_secure(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/insecure-cookie/test_secure/", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/insecure-cookie/test_secure/", + ) - assert root_span.get_metric(IAST.ENABLED) == 1.0 + assert root_span.get_metric(IAST.ENABLED) == 1.0 - assert root_span.get_tag(IAST.JSON) is None + assert root_span.get_tag(IAST.JSON) is None @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_empty_cookie(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/insecure-cookie/test_empty_cookie/", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/insecure-cookie/test_empty_cookie/", + ) - assert root_span.get_metric(IAST.ENABLED) == 1.0 + assert root_span.get_metric(IAST.ENABLED) == 1.0 - assert root_span.get_tag(IAST.JSON) is None + assert root_span.get_tag(IAST.JSON) is None @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_2_insecure_1_secure(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/insecure-cookie/test_insecure_2_1/", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/insecure-cookie/test_insecure_2_1/", + ) - assert root_span.get_metric(IAST.ENABLED) == 1.0 + assert root_span.get_metric(IAST.ENABLED) == 1.0 - loaded = json.loads(root_span.get_tag(IAST.JSON)) - assert loaded["sources"] == [] - assert len(loaded["vulnerabilities"]) == 2 + loaded = json.loads(root_span.get_tag(IAST.JSON)) + assert loaded["sources"] == [] + assert len(loaded["vulnerabilities"]) == 2 @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_special_characters(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): - oce.reconfigure() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/insecure-cookie/test_insecure_special/", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/insecure-cookie/test_insecure_special/", + ) - assert root_span.get_metric(IAST.ENABLED) == 1.0 + assert root_span.get_metric(IAST.ENABLED) == 1.0 - loaded = json.loads(root_span.get_tag(IAST.JSON)) - assert loaded["sources"] == [] - assert len(loaded["vulnerabilities"]) == 1 - vulnerability = loaded["vulnerabilities"][0] - assert vulnerability["type"] == VULN_INSECURE_COOKIE - assert vulnerability["evidence"] == {"valueParts": [{"value": "insecure"}]} - assert "path" not in vulnerability["location"].keys() - assert "line" not in vulnerability["location"].keys() - assert vulnerability["location"]["spanId"] - assert vulnerability["hash"] + loaded = json.loads(root_span.get_tag(IAST.JSON)) + assert loaded["sources"] == [] + assert len(loaded["vulnerabilities"]) == 1 + vulnerability = loaded["vulnerabilities"][0] + assert vulnerability["type"] == VULN_INSECURE_COOKIE + assert vulnerability["evidence"] == {"valueParts": [{"value": "insecure"}]} + assert "path" not in vulnerability["location"].keys() + assert "line" not in vulnerability["location"].keys() + assert vulnerability["location"]["spanId"] + assert vulnerability["hash"] @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_stacktrace_leak(client, test_spans, tracer): - with override_global_config(dict(_iast_enabled=True, _deduplication_enabled=False)): - oce.reconfigure() - root_span, _ = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/stacktrace_leak/", - ) + root_span, _ = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/stacktrace_leak/", + ) + + assert root_span.get_metric(IAST.ENABLED) == 1.0 + + loaded = json.loads(root_span.get_tag(IAST.JSON)) + assert loaded["sources"] == [] + assert len(loaded["vulnerabilities"]) == 1 + vulnerability = loaded["vulnerabilities"][0] + assert vulnerability["type"] == VULN_STACKTRACE_LEAK + assert vulnerability["evidence"] == { + "valueParts": [ + {"value": 'Module: ".home.foobaruser.sources.minimal-django-example.app.py"\nException: IndexError'} + ] + } + assert vulnerability["hash"] + + +def test_django_stacktrace_from_technical_500_response(client, test_spans, tracer, debug_mode): + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/stacktrace_leak_500/", + content_type="text/html", + ) + + assert response.status_code == 500, "Expected a 500 status code" + assert root_span.get_metric(IAST.ENABLED) == 1.0 + + loaded = json.loads(root_span.get_tag(IAST.JSON)) + # technical_500_response reports a XSS also + vulnerability = [vln for vln in loaded["vulnerabilities"] if vln["type"] == VULN_STACKTRACE_LEAK][0] + assert vulnerability["evidence"] == { + "valueParts": [ + {"value": "Module: tests.appsec.integrations.django_tests.django_app.views\nException: Exception"} + ] + } + assert vulnerability["hash"] + + +def test_django_xss(client, test_spans, tracer): + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/xss/?input=", + ) + + vuln_type = "XSS" - assert root_span.get_metric(IAST.ENABLED) == 1.0 - - loaded = json.loads(root_span.get_tag(IAST.JSON)) - assert loaded["sources"] == [] - assert len(loaded["vulnerabilities"]) == 1 - vulnerability = loaded["vulnerabilities"][0] - assert vulnerability["type"] == VULN_STACKTRACE_LEAK - assert vulnerability["evidence"] == { - "valueParts": [ - {"value": 'Module: ".home.foobaruser.sources.minimal-django-example.app.py"\nException: IndexError'} - ] + assert response.status_code == 200 + assert response.content == b"\n\n

Input:

\n\n" + + loaded = json.loads(root_span.get_tag(IAST.JSON)) + + line, hash_value = get_line_and_hash("xss_http_request_parameter_mark_safe", vuln_type, filename=TEST_FILE) + + assert loaded["sources"] == [ + { + "name": "input", + "origin": "http.request.parameter", + "value": "", } - assert vulnerability["hash"] + ] + assert loaded["vulnerabilities"][0]["type"] == vuln_type + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"source": 0, "value": ""}, + ] + } + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value -@pytest.fixture -def debug_mode(): - from django.conf import settings - original_debug = settings.DEBUG - settings.DEBUG = True - yield - settings.DEBUG = original_debug +def test_django_xss_safe_template_tag(client, test_spans, tracer): + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/xss/safe/?input=", + ) + vuln_type = "XSS" -@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") -def test_django_stacktrace_from_technical_500_response(client, test_spans, tracer, debug_mode): - with override_global_config(dict(_iast_enabled=True, _deduplication_enabled=False)): - with tracer.trace("test", span_type=SpanTypes.WEB, service="test") as span: - start_context(span) - oce.reconfigure() - root_span, response = _aux_appsec_get_root_span( - client, - test_spans, - tracer, - url="/appsec/stacktrace_leak_500/", - content_type="text/html", - ) - - assert response.status_code == 500, "Expected a 500 status code" - assert root_span.get_metric(IAST.ENABLED) == 1.0 - - loaded = json.loads(root_span.get_tag(IAST.JSON)) - assert loaded["sources"] == [] - assert len(loaded["vulnerabilities"]) == 1 - vulnerability = loaded["vulnerabilities"][0] - assert vulnerability["type"] == VULN_STACKTRACE_LEAK - assert vulnerability["evidence"] == { - "valueParts": [ - {"value": "Module: tests.appsec.integrations.django_tests.django_app.views\nException: Exception"} - ] - } - assert vulnerability["hash"] + assert response.status_code == 200 + assert response.content == b"\n\n

Input:

\n\n" + + loaded = json.loads(root_span.get_tag(IAST.JSON)) + + line, hash_value = get_line_and_hash("xss_http_request_parameter_template_safe", vuln_type, filename=TEST_FILE) + + assert loaded["sources"] == [ + { + "name": "input", + "origin": "http.request.parameter", + "value": "", + } + ] + + assert loaded["vulnerabilities"][0]["type"] == vuln_type + assert loaded["vulnerabilities"][0]["evidence"] == { + "valueParts": [ + {"source": 0, "value": ""}, + ] + } + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE + assert loaded["vulnerabilities"][0]["location"]["line"] == line + assert loaded["vulnerabilities"][0]["hash"] == hash_value + + +def test_django_xss_autoscape(client, test_spans, tracer): + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/xss/autoscape/?input=", + ) + + assert response.status_code == 200 + assert ( + response.content + == b"\n\n

\n <script>alert('XSS')</script>\n

\n\n\n" + ), f"Error. content is {response.content}" + + loaded = root_span.get_tag(IAST.JSON) + assert loaded is None + + +def test_django_xss_secure(client, test_spans, tracer): + root_span, response = _aux_appsec_get_root_span( + client, + test_spans, + tracer, + url="/appsec/xss/secure/?input=", + ) + + assert response.status_code == 200 + assert ( + response.content + == b"\n\n

Input: <script>alert('XSS')</script>

\n\n" + ) + + loaded = root_span.get_tag(IAST.JSON) + assert loaded is None diff --git a/ddtrace/contrib/botocore/services/__init__.py b/tests/appsec/integrations/fastapi_tests/__init__.py similarity index 100% rename from ddtrace/contrib/botocore/services/__init__.py rename to tests/appsec/integrations/fastapi_tests/__init__.py diff --git a/tests/appsec/integrations/fastapi_tests/app.py b/tests/appsec/integrations/fastapi_tests/app.py new file mode 100644 index 00000000000..40df0036fd2 --- /dev/null +++ b/tests/appsec/integrations/fastapi_tests/app.py @@ -0,0 +1,6 @@ +from fastapi import FastAPI + + +def get_app(): + app = FastAPI() + return app diff --git a/tests/appsec/integrations/fastapi_tests/conftest.py b/tests/appsec/integrations/fastapi_tests/conftest.py new file mode 100644 index 00000000000..5b235f5e6dd --- /dev/null +++ b/tests/appsec/integrations/fastapi_tests/conftest.py @@ -0,0 +1,41 @@ +from fastapi.testclient import TestClient +import pytest + +import ddtrace +from ddtrace.contrib.internal.fastapi.patch import patch as fastapi_patch +from ddtrace.contrib.internal.fastapi.patch import unpatch as fastapi_unpatch +from tests.utils import DummyTracer +from tests.utils import TracerSpanContainer + +from . import app + + +@pytest.fixture +def tracer(): + original_tracer = ddtrace.tracer + tracer = DummyTracer() + + ddtrace.tracer = tracer + fastapi_patch() + yield tracer + ddtrace.tracer = original_tracer + fastapi_unpatch() + + +@pytest.fixture +def test_spans(tracer): + container = TracerSpanContainer(tracer) + yield container + container.reset() + + +@pytest.fixture +def fastapi_application(tracer): + application = app.get_app() + yield application + + +@pytest.fixture +def client(tracer, fastapi_application): + with TestClient(fastapi_application) as test_client: + yield test_client diff --git a/tests/contrib/fastapi/test_fastapi_appsec.py b/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec.py similarity index 100% rename from tests/contrib/fastapi/test_fastapi_appsec.py rename to tests/appsec/integrations/fastapi_tests/test_fastapi_appsec.py diff --git a/tests/contrib/fastapi/test_fastapi_appsec_iast.py b/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py similarity index 99% rename from tests/contrib/fastapi/test_fastapi_appsec_iast.py rename to tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py index 23174d81abf..81702f3c8d9 100644 --- a/tests/contrib/fastapi/test_fastapi_appsec_iast.py +++ b/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py @@ -35,7 +35,7 @@ from tests.utils import override_global_config -TEST_FILE_PATH = "tests/contrib/fastapi/test_fastapi_appsec_iast.py" +TEST_FILE_PATH = "tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py" fastapi_version = tuple([int(v) for v in _fastapi_version.split(".")]) diff --git a/tests/appsec/integrations/pygoat_tests/test_pygoat.py b/tests/appsec/integrations/pygoat_tests/test_pygoat.py index 8bb8baae1bd..8e6ff5da0ff 100644 --- a/tests/appsec/integrations/pygoat_tests/test_pygoat.py +++ b/tests/appsec/integrations/pygoat_tests/test_pygoat.py @@ -5,7 +5,6 @@ import requests from tests.appsec.iast.conftest import iast_context_defaults -from tests.utils import flaky span_defaults = iast_context_defaults # So ruff does not remove it @@ -108,7 +107,6 @@ def test_nohttponly_cookie(client): assert vulnerability_in_traces("NO_HTTPONLY_COOKIE", client.agent_session) -@flaky(1735812000) def test_weak_random(client): reply = client.pygoat_session.get(PYGOAT_URL + "/otp?email=test%40test.com", headers=TESTAGENT_HEADERS) assert reply.status_code == 200 @@ -124,7 +122,6 @@ def test_weak_hash(client): assert vulnerability_in_traces("WEAK_HASH", client.agent_session) -@flaky(1735812000) def test_cmdi(client): payload = {"domain": "google.com && ls", "csrfmiddlewaretoken": client.csrftoken} reply = client.pygoat_session.post(PYGOAT_URL + "/cmd_lab", data=payload, headers=TESTAGENT_HEADERS) @@ -132,7 +129,6 @@ def test_cmdi(client): assert vulnerability_in_traces("COMMAND_INJECTION", client.agent_session) -@pytest.mark.skip("TODO: fix interaction with new RASP rules") def test_sqli(client): payload = {"name": "admin", "pass": "anything' OR '1' ='1", "csrfmiddlewaretoken": client.csrftoken} reply = client.pygoat_session.post(PYGOAT_URL + "/sql_lab", data=payload, headers=TESTAGENT_HEADERS) @@ -142,34 +138,20 @@ def test_sqli(client): @pytest.mark.skip("TODO: SSRF is not implemented for open()") def test_ssrf1(client, iast_context_defaults): - from ddtrace.appsec._iast._taint_tracking import OriginType - from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject - - s = "templates/Lab/ssrf/blogs/blog2.txt" - tainted_path = taint_pyobject( - pyobject=s, - source_name="test_ssrf", - source_value=s, - source_origin=OriginType.PARAMETER, - ) - payload = {"blog": tainted_path, "csrfmiddlewaretoken": client.csrftoken} + payload = {"blog": "templates/Lab/ssrf/blogs/blog2.txt", "csrfmiddlewaretoken": client.csrftoken} reply = client.pygoat_session.post(PYGOAT_URL + "/ssrf_lab", data=payload, headers=TESTAGENT_HEADERS) assert reply.status_code == 200 assert vulnerability_in_traces("SSRF", client.agent_session) def test_ssrf2(client, iast_context_defaults): - from ddtrace.appsec._iast._taint_tracking import OriginType - from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject - - s = "http://example.com" - tainted_path = taint_pyobject( - pyobject=s, - source_name="test_ssrf", - source_value=s, - source_origin=OriginType.PARAMETER, - ) - payload = {"url": tainted_path, "csrfmiddlewaretoken": client.csrftoken} + payload = {"url": "http://example.com", "csrfmiddlewaretoken": client.csrftoken} reply = client.pygoat_session.post(PYGOAT_URL + "/ssrf_lab2", data=payload, headers=TESTAGENT_HEADERS) assert reply.status_code == 200 assert vulnerability_in_traces("SSRF", client.agent_session) + + +def test_xss(client): + reply = client.pygoat_session.get(PYGOAT_URL + '/xssL?q=', headers=TESTAGENT_HEADERS) + assert reply.status_code == 200 + assert vulnerability_in_traces("XSS", client.agent_session) diff --git a/tests/appsec/suitespec.yml b/tests/appsec/suitespec.yml index 8f10e3ddee7..3ee0afdb8c5 100644 --- a/tests/appsec/suitespec.yml +++ b/tests/appsec/suitespec.yml @@ -6,10 +6,10 @@ components: appsec_iast: - ddtrace/appsec/iast/* urllib: - - ddtrace/contrib/urllib/* + - ddtrace/contrib/_urllib.py - ddtrace/contrib/internal/urllib/* webbrowser: - - ddtrace/contrib/webbrowser/* + - ddtrace/contrib/_webbrowser.py - ddtrace/contrib/internal/webbrowser/* suites: appsec: diff --git a/tests/ci_visibility/suitespec.yml b/tests/ci_visibility/suitespec.yml index 9012ced61d8..46e524e9f4d 100644 --- a/tests/ci_visibility/suitespec.yml +++ b/tests/ci_visibility/suitespec.yml @@ -7,14 +7,14 @@ components: dd_coverage: - ddtrace/internal/coverage/* pytest: - - ddtrace/contrib/pytest/* - - ddtrace/contrib/pytest_bdd/* - - ddtrace/contrib/pytest_benchmark/* + - ddtrace/contrib/_pytest.py + - ddtrace/contrib/_pytest_bdd.py + - ddtrace/contrib/_pytest_benchmark.py selenium: - - ddtrace/contrib/selenium/* + - ddtrace/contrib/_selenium.py - ddtrace/contrib/internal/selenium/* unittest: - - ddtrace/contrib/unittest/* + - ddtrace/contrib/_unittest.py suites: ci_visibility: parallelism: 4 diff --git a/tests/contrib/langchain/cassettes/openai_embedding_query.yaml b/tests/contrib/langchain/cassettes/openai_embedding_query.yaml deleted file mode 100644 index eee82a8fd90..00000000000 --- a/tests/contrib/langchain/cassettes/openai_embedding_query.yaml +++ /dev/null @@ -1,201 +0,0 @@ -interactions: -- request: - body: '{"input": [[576, 374, 264, 1296, 3319, 13]], "model": "text-embedding-ada-002", - "encoding_format": "base64"}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '108' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.12.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - Linux - x-stainless-package-version: - - 1.12.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.10.3 - method: POST - uri: https://api.openai.com/v1/embeddings - response: - body: - string: !!binary | - H4sIAAAAAAAAA1R6WQ+ySrfm/fcrdvatfSIiUIt9h4DIWKXigJ1OB1BRFJGhqqBOzn/v4PvldPeN - iUCUGtYzrfrPf/311991Vt7y/u9//vr7/ez6v//HdO2a9unf//z1P//1119//fWfv8//78lbld2u - 1+en+D3+u/n8XG/D3//8Jf33lf/70D9//Y3qzmbGU4Siva1rCveraNjKu11bjjdUAvMwrNkGOS/E - ST/XYGfnW3ZA6i5mRV8DvBfdi861GkRHoShQ2Eo6XvK+KIfEUFIUsaVDbON6bodkvnKB1HGIobzF - cbfbphxd50PONlWuZDTdyAn4XXlilvop2t6Z3zrt8h4FzrWHHY/no+UAGbKWmb39aUVuZC6qa5eS - jX73snFfYQNsabbHdWylYmhJ6KDZgRZ0PruUaEzLQw4x8/ZYH2PJEusQY3iq2yMVnqvF9NVHNtA5 - XuHuEQZoMTsFPiLR4oD5LO2tbieiHKn7jUc2sbUrR/3FE3g9v3PmzzNZ9NqjbqC0yQwv8kBHdLV6 - SGhD2gOWavrKqt3rJMHb0hNi2Nrb4ru+MPRNJPuYB997QC96cIDSlD/0c7+/2v6kohfaP283PCPM - i/ln5R2gVo0Dy60noEGWVwDfQ8bxXLmOVvdklwIlY70lGd7SbJBlb6aqK1LiOWu/1tjei0JPH08b - D3Fdo5Gxh623cLJp03mRJTdX9QRBJDNmXdWyFW/nnUBQ6DGxSbAP+sXYVjC/v3zihs2pFS9bxiBV - g0NCrV4FncDJCchwackKullQtZXuw7vz91gq9rusv3SVBt2ZFSyasU8wmF9O4dDknISZp1vUrIIO - 2AU7bMXI1xozMwHweOeyHetQK7Z7o4LOWWp0TmQSjxGDAzil7BC7pq94UM0OA1HonETtycjkxecB - sDXyDYtvRpFxRHc3eGmZQ7wm2olaOh98ILdOo8v3fC0ko05cyCr0osp1WLSvs5s1EHpuxLzD18hq - OF04PPqHTceFzOOhXxxdyE7XgZk77YKomH8buB7Pb7YxsJb1zmoNgC5tjeVlvsv6ft/kcECHE7ke - 0jDmY/h1YVMUiH7x/YCEb541EE1hk+03poFYwfoFM0vSaFP2FyFujfkC+1Xc8fnlcySkvDgh+41k - 5voJFVx+blx4HJKKXLbPsq0fnnsD7C0CDIrogu7Jdk949KXNLDDeFtd2YQhlJ7XMy+7nQLixOZur - 3/TKbPPyjcd9UVcQrZcmMRZsZUn7vQfQqaaKKbzeLW93ngKjPTJm9UFf8mqeOpBunJBZgR0G3OOX - CqRl01Ekvb2MQ7YMkdu3T7JB0aPsZhfuwjHgHiHKdW+Nmfeu0GdhBlhTzbFk4uLNkMisBX7Vn03Z - WZd8D6Csv8Q77/SS5kHOESqJRlz9vm/72tAobFMjYS5q9Lh/xZ0E+zbwWHhdk0AgTdvC2jhTPKp6 - FAyJc5RgrlYEo7azWrGTnznSL5lJF8YmCMbXm+fIMYuear7ZtkMuyhopQUp63qeN4PN1RdF83CKC - 4fUuxaG4AFrf4EQMLd5m/K03GtyDomepbwalKPp6hszZ+UTwakXFKLfuCbLAOZIgXJclf19WBnxj - 48LWO9xY/GrkBTo68ZwEq3ONaPYOGji+R0wiT9CYVZ+LiV4DzVgUaa3VnxJu68/7fsus1p2hMf52 - KXKz5I2HiNgl9w+iAIUWI+20h50NuzqQ0cJ17vhNAhTXrm880anBPkZhpsbiGmAf7Lcqs1UQ79tR - nS1dGBreEP/9bYV46d8CqcmswarMH+XY1a8DePXcYCHTnPg7u95HrTUXA1v1Dy5aTz2YcLWKjGWf - dyW61VFX0BihiPJ4doyb3dUPIXs7KRbkMSv5t1FGGEPbIiQJ3mKUSbNF5/W7Yqb9eqBvuXVu2k7N - dLrs7puAququ00NRrVnYCq/k8spqQM5nGC+yD46HTWEmYFj4QYWvkz/j1yTbPjFjWs9ufftKSP/K - C2aJ14CGcBhdOEgrk/mqx7I/+DfhJRbRKUbCU3MDuGrdGNHqHAmHvF5ox5YtI3LQxG+TnXwwjtcb - lcQLWZ1RJz6sxLUjZh6YQc/Oigk6bEa2ud/tUr6kSfOnHuNi7wbj4vOYQZ40HC+n+yJNUgmtjSOl - c6M1swUiOEGV2vV4OMvPTEjPiKN9vFxgtD8HltBSXKO1mmJiFSwthaGwEB284EzwO10iHlyXB/Ae - RKWLi3qyBt9TNQCTepSnroH43PC2GlzbAWdMFPE4P6wPaI6yC/FpJpU//gK5T1ckON02aLS+jQPe - Wrqyq5xyNAi/PYERoJCYnruzhirREuR40ort2Oktbo4cbrX0MgKJgkdVjs91KMNr2NZ49k7PaHyA - O0NkXeXEyXYP1Jnntw2HOMjpbJPGwVQ/B23vxyWxVeqUCyd/GTAn/plZl7FCI8/ONSx2zUCsy+gI - rgRyDemjsMmEz/G49z8z8IOWE/eYz7OmUJoKLSRxIPYTW9Yi4+s99Bn7EsN8GFP9oAIG6QAk+C5x - 29nKttMfs7Rhvn+/WWPsDB1IUShRlR5oydvdStOLbXpl0fotibpoAoDQL19k3S2aWBy/Rw65gb5Y - HZUrGiXLsHXrofZYn4dq2bN7WEOvWyYF65kjsZKUGRx2pz1VrofSGkLVGUHdtSfi1MnK4kmnF2hz - gi8xhGDWUJ2tEFBTYqrevVW2zGal8oefHWbcYqYtMw2ywD7+9rv4xuNMRk5XDBSFa6scHyuao81p - 9iX+B4lswsMb0rVtTeyFfi9F5OW1tpCOD4LxaheI/FqkEBTzGL8vZZENLScvLV6eIrK5NqQVDSwN - tNDvc7a+lEXMXJ5g9LAeBiPeNbB+fAZXfbbHqr41BVcbYcOO3g5YkaSqHFsz24JpFi5WwkPxmy9H - F6vrixGjNeNBuZlb/W7KJtnMm0NAi+x6QnQervCiyddo6Kjx1NP9tWZuE9WlkH3HRhojnErHNo7r - wVcBlkbxZvZLv8b8jUSHLm8u2JrDJ2BbSewh/zolvjTRgJh1q3NVGE6EG97n8bQ+ALIyXPHjs2Kl - MM4lhdb31vj82vUtD9RrCpVKe2J5bhp3DUk7dL57Szz/kJO1jEzDBOZ7DYvklIsuMvahVj/iCDO8 - SuPBD762ep41DvM287gd/O5VwWHDDWbI65OgUbSq0aQfWPhO3/G0/xvYryqF+RtuofHaXEK4ae2G - 2HY7BLy/dg7K0blg1utio0VRDE+wHqin2vjFFr/dE0Ad/qxY9H0EmdQt0xlky8FnG+dzawcOFwUt - 2shk7mDdW5ECUNi7SsiCNx8Ej7P1iCY9gDX3IGLRpOEBVXdaE7/sL//2E9Z4LrAm8waN32WNgRbv - CzHR+LQm/lTgtPpcMe8fm3J8fpZPNM0fVSRUxkx/BClszXhHsCeWbT3pC1gksCbGbHkvvx65HzTj - uGrZT2+wk7/K0fu6lrGg6lqMkp9TVBV+TkLpPZb0+/hUkHhvxoydaFpqhbkMhLk9ibj7zYT96bZ/ - 9M9cue4D/mS7QjeOVkv1/eqDxvOYnJB8bDTmfiTbkveVY8B5/amw8lDGmJvSeALmjjFVJ733w09U - 303yR+/Ws9nehP3ebNnGLXk7DBt7BqmLTvgx4eVg71QDVaeXz7yT1Aaj9NZG+Lz8NwYr3ARjknxv - UPGKMOvYNgHt1kP9G9+fehaHYgew1oY3W5MAZf1NUfEfvWn0Sz0b7/vdEz56J7M1XqxLeU1QCLuo - osQ8toYQreryP+vnrMDL+vnlW8Dkz+hs7/aiX5yjJ0qka8qc5VEq+blUKfLww8XjZ5WI74G5L7D9 - Zzrtfy3r+Wxl/9ELv/00+ZsT6AU9E19bbtqJ72Qk9mefReH6FPCjXr8g7PYcqw8lK0fPvnZIRd+U - rJlxDHiyO+coOGcrrLpRFA9ZlL6UbRcfsQQGzTo9cWegzfYhFbtXFFPvjjgoUXShz4INMR8Hy4Bh - 14STHh0D5i70Rh2V4xr7jycL+gr1tja0+Mos52IE3F/SEME81Sc9IAR3ngaGYRVeCNZXSjBM+gTK - Tm5psd6moseXMddTwpfEnR825eCWNQfttNnjx5m921Hm/ajl6VVjmx2Gltn28NKbJFNJ0G1FMJ7V - bgbPWnpiPWdmOd4Xdojw7hWzbf/4lL1+iAGWMFSYl9t7xg+aiUG61h92IMHeGsbKS7W9ONkkfIQt - GrarcVQnfmSeXiUl34ZSquOUDiSa/PG7ngc3iOr5m6pb5ZIx67XWwBs3dzwGqVL2wV7vwJTtGyM5 - W1jdYXVT4BubFyzsdoMGY6XkYN0bRpd3WFo/vIGjs5uzzcKPA5oaD/4HT4dvegjGGt1uaKOtQ7Z5 - z9+IZ4tHDmZk6cRI3UJ01+uDa+nGDtnkn4NB/TgOOJ68mva7b4n4PU+0cLbR6GzlTnr9dEtQ88mP - Uz2+rPGbpoDkm0iYkad1yeVSPsC385cs4quu7LSdjeG9oC8Mm9RoJdU1Uu0bxDsq7TZ2MMrHTQfQ - 0YitPHeDeCOgApjpPtbevC6FSreOxkOeM3fCp+FROy7E6wAT8ywHpfCv+gx5nLpkvShOGV/hxxbe - po9xmyzDbAgPLwXOy8PIQk+sre51oznalv6SGa1rBctg9q3+/N4KTm5MTetiIHFpbr96bb8v+f5E - kZolxOX9F/UoumM0+U2MHs8k65dL1Qe0kW9Y882gFWun4Ai6LmI53p7byb/MgNqjz9bHoyPa3PQP - sBrtIx4894NEfHuOerRemHjYrlE7XqNgBnGlpAxrwcpi7kFz4eXInGprRNE4ron782tYmvh0lNz+ - CStsB1TGCyxE9dkZKIWVSqb1FsJ83iikT5RNemQnRg0ZmvbTb9HetUuZLFYK9MY48VHtBkIgqLVm - MD9U36TepMcPJiLrV87265UUd+1+sGF30Cw8Ll9uK5Su1tQB1VvKDeFmo0yee8jTu8bMmf1F3NTu - o/bDV/vYilhEpmGgXRHfqawmVix3wdnR/O5xYjipScCNcLT/6CfPdraliN/LFBrHhz/+kW8br4E+ - 67+TPpwF9H5wqbZIZmtmtmQ/6RV/D2L7NOjStFjWustOhi9UDZZc1W+HYL+gKLjtn/T7kfqYjsUb - gyNvLLYpLMmiOp5zsOUhZ6HSsWzYVnmN7qZkMmeaXy4h2YD41t/J45tK1nBb+gYSi3tP7GEv2t4t - C65P3ymT7aj98au2Gp0jMYCYcf9Yxzn8/HA9KlLLzoslQKuzjMpu+cnG5h3NoFZeD3ZEpY0W3VZs - wZwdT2xz9mnM1EVHNbl6FsS1lKjlSjCrtapebJh9UTsxzK5nDu3C5MwtLD2mt/MMoFL3Gv0M1inj - j+3V1iY/SMhMljM63GYG6E63Z94JfcSUXzlQOHJAQplff/kCRubyvsDDma3bUcfLEU6E70l0XSsx - +3wNrPNPeKDCkcdyoCdXgp1iVlhpIrcdlJJ1oNDnyFabcIHoA4wZmi0v2z96ZtiYug9H+7YgId4u - W2q3uy04cRozT5KYaJa7XQ5ulr7xw2FWPC5CS4PbeXam8s3IgynfonBfwJttLo4RL6zjZwu5i/Wf - HxOMhvMGtfuTgcdab9BQbvENtv4cWMQ01vJ1cTHQ04gWzOdnpxXWKsNgFcWJWVRdI4FDYcKhUUpG - vntbjIvvxYUNiR7EXh5Na6GUHwrfw4VTyW53wfidgfTjJ2KyE7M6vKlkJFd2T7MxtNFwYMYLikLa - Mq+rTtkwh3zy589owt918K3zZITbzpEp0pZcdI/+eYLQf7yYjw6pxbjPK9iuFjeymQ9bVI7SlNAU - QYVnJ+K3PDg1FH75lXfeXVveX18ODOlhybbtLRHDBtU3+KRVTKxXsSq5ee4drbV2LxKAMEVn1FsX - wsvLYHGtH6wuBMQhuw5rWiRxi/hPX9sWcaiAk4bGA8YHKMY2pdJw4dlwShQHfcs8ZOGknwTzvASw - 1Mn0WNOoXLbG8Qajcl6zaMKXZXKQcuDhmBNPNb1skTyEgjQZFHK5VzESSqPS33hZ5Amcqfu2CX98 - /CePFFth2yAx9MI1PaxjaZpv+PFVUzmzuK4/aaL+/Ml6UcjZID5KBcvGlqn00vWsj6XKRD8/uPBp - LQYp/rg/viJYIiSr0R4lsG3ygDn3xc4aI8wl+JjLkHaHtLQG94sx+rNfJv1Fp7wc5feZTUjpXuIp - /wN0kZsLcXZYxIOEVxTNFi+HTfmvxZ8ydWF5aS1ii43bMlXohTb5QRa0nVXKyvJZ6MWwtZhbJ6Ic - a33dILSRbsQuLjTg5nabK8ez92bODsfxGH9fyY8f/tTzz29ppyb06YhGMxiebfeExdN5EbMP7OxP - PR8araTKvl8H8hULF94vaUafmV5nrew7DjwNsqCIrmur92k8Il6ND7K6kUqMizDQfnkKsZhhtqMS - GzWcvvyMYZof4Zt3BR2jT0wmPI3Zy55hLf8WJ/LL06hYJRpSSZKwKd+2+M0MKCiBbDL/6OTBlE+/ - /uT/A0lZ/N68mYSydxEx/3MzBH8X1wa5fcRYcEJaNt4PRqcXl41LSBCUWbX4fEFb1U+L/PyD9PMH - iWR9Jn0SlmPzXs+UafxkVdRtLAq2daHM9DXZjEqb8fqTptp7diHT9yBerFOQEY3yBR2Gui/bie+h - 9YM1VS8Raxfbu2HqvzzvqtV+LG2cpw8G/QDxJr4Zlnlmw8SX7CJ/bTFw2GnA+UH8u17lJ/FRt85L - 5o1P1+LOp6/RM0kYIwf7G4zD+ZHoU/8Hjwo5oIGdFQPYKp8zvHd7xC8801DMTZW58+wVT3nxC402 - Z8yjB9zyENAIxNEFwaZcIhFPFN2phsq8D/ID2W+qEdyVdCC7qZ/Rnwu7++Etce38GvT6IZuBMOxo - 8o+fdqjnVg6TXiAWGtuMJQe4wbKMjgx7p3VAf3l3kl6PWJnep1/qpwpA2XyJH2bcYvSp7EGxHYTF - Sz5nP7xASpAQqoQHA33oJsWQBYVLfv2Cn36EMXQssp43j7Z/rLNcex8uAfnhKY+P9QFN+oSFadeU - /LA6adB3Xs7ym2ZbU97qw3ZxkdjmiW9ouMLnpk36iZ3O/tsS1ediQBai+5Tvvlp+DzYF7PdGy5JV - bwoeXOcHbfORCTFnD8j44Ksz6M0gwU9fdyy+OmCKzNy5EDOIM8TDdOXo+1WwZs4TH9vFcqm6cDdT - QpXuzjMuzw/pr19BnJf/aZmZD3vAuyr+kzfwTSSPkM2alvgntAumetLQu9dzFshcsr79ZW4DBNIH - c8V9T3o5saHhlYTnvSwFv/4UzMc9IqunkIMJP+pf/4HZTlEF/UzRZZjwn1nPFyl5gd8arL/qnJn9 - QwuK98UzIXnwhvJK89rhPT62+tQvIVO+IbqVsHzQt9sX2076f+rPzCCIJMbCTWyJRV32KXgnahFv - fNaWYN4q0e5ymmDFT7AYlvqtggovzH/z65ogDAilEr1026Ic5lpvan6+KeknSzZCytMg1aJr5RHz - qUHQTXoGOUGUkJCvyow+VtUNeP1pyaZO/Ez+6dEfv66ro2eNjH3t3/4lN7zaWaK7XxRg+9Obzrzr - SjR953cw8RfZBfHYvo5FdoIp3yBRMsvKkVxa6aeXMEpmntUln8RBlzB8kF++IPTn+AK5Kgrmu5Fc - Nj89v3EKmZmtuyi7d6pgEKIpiWWyhRj3RfGCzZA+iPd4vlFv4rSBDQfKXBQ1qEcbdQT7YHdsm7oF - Gqv4FP7RG4IZz7LLUyuB3FC/ZBM2fdZevRPAJzOdP3jYxu95CiMLK2Io7rrlyjdQtJ//NWvdR90Y - 6xyueaPiAbqbNfXHKjCzuiJulgwBlfy8gwkv6fYpOjQGb+8Ez03p/fR2NozVKoU/eQ1oY8Db5FTo - 0/sTnLMW/dl/L1JmdJYKVfALjxU4PRWZbHhVIrYM9D3M/C4juxdzf/NpQ57UnKWzmZ1JRwvbqLsb - ElvvXnfEyHEmo0P5IfggXih4Sm5f/Ob3x4dW/avHKR+hKFl28ZjcZw400W1L0TY0suXrGeRwt6ML - XuxwE4h3qTUwdG9p8pNtWcdyKcOtTnz61hddyaPHsUOvbWYSY5ZG1vLnpxq8/NC+Z7boMx7tYUfz - A3P0exHQ3tua8PfvVMB//euvv/7X74RBVV9v7+lgQH8b+v/476MC/5Fe0/+QJPnPMQTapcXt73/+ - fQLh729bV9/+f/f16/bp/v7nL+3PUYO/+7pP3//P5X9Nf/Rf//o/AAAA//8DAPkwyVDeIAAA - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 862e6dc81e690f36-EWR - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Mon, 11 Mar 2024 20:52:32 GMT - Server: - - cloudflare - Set-Cookie: - - __cf_bm=YXU4DtMePAsaJx2kty.2jSeqq5zjQQY1epSJLQkBDq0-1710190352-1.0.1.1-IZASGeqa6i8uV9e7rvisun.N6t0Vsj8fdicmV4OF.AUAcpXJ7bOwpjV8QBMZV37zd91bdrc_2dZ62W3Y3pZ_Rw; - path=/; expires=Mon, 11-Mar-24 21:22:32 GMT; domain=.api.openai.com; HttpOnly; - Secure; SameSite=None - - _cfuvid=v6MSy3Sk6pxtoYL8kXXuNiO2j0OK_HAODXl1hNcZp0o-1710190352774-0.0.1.1-604800000; - path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - Transfer-Encoding: - - chunked - access-control-allow-origin: - - '*' - alt-svc: - - h3=":443"; ma=86400 - openai-model: - - text-embedding-ada-002 - openai-organization: - - datadog-4 - openai-processing-ms: - - '21' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=15724800; includeSubDomains - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '10000000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '9999994' - x-ratelimit-reset-requests: - - 6ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_75612d53833fe21791b4426615e1d4ca - status: - code: 200 - message: OK -version: 1 diff --git a/tests/contrib/langchain/test_langchain.py b/tests/contrib/langchain/test_langchain.py index a811a53099b..86a14f524d9 100644 --- a/tests/contrib/langchain/test_langchain.py +++ b/tests/contrib/langchain/test_langchain.py @@ -37,6 +37,7 @@ def request_vcr(): yield get_request_vcr() +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_openai_llm_sync(langchain_openai, request_vcr): llm = langchain_openai.OpenAI() @@ -44,6 +45,7 @@ def test_openai_llm_sync(langchain_openai, request_vcr): llm.invoke("Can you explain what Descartes meant by 'I think, therefore I am'?") +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_openai_llm_sync_multiple_prompts(langchain_openai, request_vcr): llm = langchain_openai.OpenAI() @@ -56,6 +58,7 @@ def test_openai_llm_sync_multiple_prompts(langchain_openai, request_vcr): ) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.asyncio @pytest.mark.snapshot(ignores=IGNORE_FIELDS) async def test_openai_llm_async(langchain_openai, request_vcr): @@ -64,6 +67,7 @@ async def test_openai_llm_async(langchain_openai, request_vcr): await llm.agenerate(["Which team won the 2019 NBA finals?"]) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_openai_llm_error(langchain, langchain_openai, request_vcr): import openai # Imported here because the os env OPENAI_API_KEY needs to be set via langchain fixture before import @@ -79,6 +83,7 @@ def test_openai_llm_error(langchain, langchain_openai, request_vcr): llm.generate([12345, 123456]) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.skipif(LANGCHAIN_VERSION < (0, 2), reason="Requires separate cassette for langchain v0.1") @pytest.mark.snapshot def test_cohere_llm_sync(langchain_cohere, request_vcr): @@ -87,6 +92,7 @@ def test_cohere_llm_sync(langchain_cohere, request_vcr): llm.invoke("What is the secret Krabby Patty recipe?") +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.skipif( LANGCHAIN_VERSION < (0, 2) or sys.version_info < (3, 10), reason="Requires separate cassette for langchain v0.1, Python 3.9", @@ -186,8 +192,7 @@ async def test_openai_chat_model_async_generate(langchain_openai, request_vcr): def test_openai_embedding_query(langchain_openai, request_vcr): with mock.patch("langchain_openai.OpenAIEmbeddings._get_len_safe_embeddings", return_value=[0.0] * 1536): embeddings = langchain_openai.OpenAIEmbeddings() - with request_vcr.use_cassette("openai_embedding_query.yaml"): - embeddings.embed_query("this is a test query.") + embeddings.embed_query("this is a test query.") @pytest.mark.snapshot @@ -227,6 +232,7 @@ def test_pinecone_vectorstore_similarity_search(langchain_openai, request_vcr): vectorstore.similarity_search("Who was Alan Turing?", 1) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_lcel_chain_simple(langchain_core, langchain_openai, request_vcr): prompt = langchain_core.prompts.ChatPromptTemplate.from_messages( @@ -239,6 +245,7 @@ def test_lcel_chain_simple(langchain_core, langchain_openai, request_vcr): chain.invoke({"input": "how can langsmith help with testing?"}) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_lcel_chain_complicated(langchain_core, langchain_openai, request_vcr): prompt = langchain_core.prompts.ChatPromptTemplate.from_template( @@ -268,6 +275,7 @@ def test_lcel_chain_complicated(langchain_core, langchain_openai, request_vcr): chain.invoke({"topic": "chickens", "style": "a 90s rapper"}) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.asyncio @pytest.mark.snapshot(ignores=IGNORE_FIELDS) async def test_lcel_chain_simple_async(langchain_core, langchain_openai, request_vcr): @@ -315,6 +323,7 @@ def test_lcel_chain_batch_311(langchain_core, langchain_openai, request_vcr): chain.batch(inputs=["chickens", "pigs"]) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_lcel_chain_nested(langchain_core, langchain_openai, request_vcr): """ @@ -367,6 +376,7 @@ def test_lcel_chain_non_dict_input(langchain_core): sequence.invoke(1) +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_lcel_with_tools_openai(langchain_core, langchain_openai, request_vcr): import langchain_core.tools @@ -387,6 +397,7 @@ def add(a: int, b: int) -> int: llm_with_tools.invoke("What is the sum of 1 and 2?") +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_lcel_with_tools_anthropic(langchain_core, langchain_anthropic, request_vcr): import langchain_core.tools @@ -413,16 +424,15 @@ def test_faiss_vectorstore_retrieval(langchain_community, langchain_openai, requ pytest.skip("langchain-community not installed which is required for this test.") pytest.importorskip("faiss", reason="faiss required for this test.") with mock.patch("langchain_openai.OpenAIEmbeddings._get_len_safe_embeddings", return_value=[[0.0] * 1536]): - with request_vcr.use_cassette("openai_embedding_query.yaml"): - faiss = langchain_community.vectorstores.faiss.FAISS.from_texts( - ["this is a test query."], - embedding=langchain_openai.OpenAIEmbeddings(), - ) - retriever = faiss.as_retriever() + faiss = langchain_community.vectorstores.faiss.FAISS.from_texts( + ["this is a test query."], embedding=langchain_openai.OpenAIEmbeddings() + ) + retriever = faiss.as_retriever() with request_vcr.use_cassette("openai_retrieval_embedding.yaml"): retriever.invoke("What was the message of the last test query?") +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_streamed_chain(langchain_core, langchain_openai, streamed_response_responder): client = streamed_response_responder( @@ -444,6 +454,7 @@ def test_streamed_chain(langchain_core, langchain_openai, streamed_response_resp pass +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_streamed_chat(langchain_openai, streamed_response_responder): client = streamed_response_responder( @@ -459,6 +470,7 @@ def test_streamed_chat(langchain_openai, streamed_response_responder): pass +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) def test_streamed_llm(langchain_openai, streamed_response_responder): client = streamed_response_responder( @@ -520,6 +532,7 @@ async def test_astreamed_chat(langchain_openai, async_streamed_response_responde pass +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot( ignores=IGNORE_FIELDS, token="tests.contrib.langchain.test_langchain.test_streamed_llm", @@ -539,8 +552,7 @@ async def test_astreamed_llm(langchain_openai, async_streamed_response_responder pass -# TODO: needs fixing in follow-up -@pytest.mark.skip(reason="Problematic test that needs fixing") +@flaky(until=1754218112, reason="Problematic test that needs fixing") @pytest.mark.snapshot(ignores=(IGNORE_FIELDS + ["meta.langchain.request.inputs.0"])) def test_streamed_json_output_parser(langchain, langchain_core, langchain_openai, streamed_response_responder): client = streamed_response_responder( diff --git a/tests/contrib/suitespec.yml b/tests/contrib/suitespec.yml index 40a677109fc..366e28aaaf9 100644 --- a/tests/contrib/suitespec.yml +++ b/tests/contrib/suitespec.yml @@ -1,60 +1,61 @@ --- components: aiohttp: - - ddtrace/contrib/aiohttp/* + - ddtrace/contrib/aiohttp.py - ddtrace/contrib/internal/aiohttp/* - - ddtrace/contrib/aiohttp_jinja2/* + - ddtrace/contrib/_aiohttp_jinja2.py - ddtrace/contrib/internal/aiohttp_jinja2/* aiopg: - - ddtrace/contrib/aiopg/* + - ddtrace/contrib/_aiopg.py - ddtrace/contrib/internal/aiopg/* algoliasearch: - - ddtrace/contrib/algoliasearch/* + - ddtrace/contrib/_algoliasearch.py - ddtrace/contrib/internal/algoliasearch/* asgi: - - ddtrace/contrib/asgi/* + - ddtrace/contrib/asgi.py - ddtrace/contrib/internal/asgi/* asyncio: - - ddtrace/contrib/asyncio/* + - ddtrace/contrib/_asyncio.py avro: - - ddtrace/contrib/avro/* + - ddtrace/contrib/_avro.py - ddtrace/contrib/internal/avro/* aws_lambda: - - ddtrace/contrib/aws_lambda/* + - ddtrace/contrib/_aws_lambda.py - ddtrace/contrib/internal/aws_lambda/* - ddtrace/ext/aws.py azure_functions: - - ddtrace/contrib/azure_functions/* + - ddtrace/contrib/_azure_functions.py - ddtrace/contrib/internal/azure_functions/* botocore: - - ddtrace/contrib/botocore/* + - ddtrace/contrib/_botocore.py - ddtrace/contrib/internal/botocore/* - - ddtrace/contrib/boto/* + - ddtrace/contrib/_boto.py - ddtrace/contrib/internal/boto/* - - ddtrace/contrib/aiobotocore/* + - ddtrace/contrib/_aiobotocore.py - ddtrace/contrib/internal/aiobotocore/* bottle: - - ddtrace/contrib/bottle/* + - ddtrace/contrib/bottle.py - ddtrace/contrib/internal/bottle/* cassandra: - - ddtrace/contrib/cassandra/* + - ddtrace/contrib/_cassandra.py - ddtrace/contrib/internal/cassandra/* - ddtrace/ext/cassandra.py celery: - - ddtrace/contrib/celery/* + - ddtrace/contrib/celery.py - ddtrace/contrib/internal/celery/* cherrypy: - - ddtrace/contrib/cherrypy/* + - ddtrace/contrib/cherrypy.py - ddtrace/contrib/internal/cherrypy/* consul: - - ddtrace/contrib/consul/* + - ddtrace/contrib/_consul.py - ddtrace/contrib/internal/consul/* - ddtrace/ext/consul.py contrib: - ddtrace/contrib/__init__.py - ddtrace/contrib/trace_utils.py - - ddtrace/contrib/trace_utils_async.py - - ddtrace/contrib/internal/* + - ddtrace/contrib/internal/trace_utils_async.py + - ddtrace/contrib/internal/trace_utils.py + - ddtrace/contrib/internal/redis_utils.py - ddtrace/ext/__init__.py - ddtrace/ext/http.py - ddtrace/ext/net.py @@ -69,182 +70,180 @@ components: - tests/contrib/__init__.py - tests/contrib/suitespec.yml coverage: - - ddtrace/contrib/coverage/* + - ddtrace/contrib/_coverage.py - ddtrace/contrib/internal/coverage/* dbapi: - - ddtrace/contrib/dbapi/* - - ddtrace/contrib/dbapi_async/* + - ddtrace/contrib/dbapi.py + - ddtrace/contrib/dbapi_async.py - ddtrace/ext/db.py django: - - ddtrace/contrib/django/* + - ddtrace/contrib/_django.py - ddtrace/contrib/internal/django/* dogpile_cache: - - ddtrace/contrib/dogpile_cache/* + - ddtrace/contrib/_dogpile_cache.py - ddtrace/contrib/internal/dogpile_cache/* dramatiq: - - ddtrace/contrib/dramatiq/* + - ddtrace/contrib/_dramatiq.py - ddtrace/contrib/internal/dramatiq/* elasticsearch: - - ddtrace/contrib/elasticsearch/* + - ddtrace/contrib/_elasticsearch.py - ddtrace/contrib/internal/elasticsearch/* - ddtrace/ext/elasticsearch.py falcon: - - ddtrace/contrib/falcon/* + - ddtrace/contrib/falcon.py - ddtrace/contrib/internal/falcon/* fastapi: - - ddtrace/contrib/fastapi/* + - ddtrace/contrib/_fastapi.py - ddtrace/contrib/internal/fastapi/* flask: - - ddtrace/contrib/flask/* + - ddtrace/contrib/_flask.py - ddtrace/contrib/internal/flask/* - - ddtrace/contrib/flask_cache/* + - ddtrace/contrib/flask_cache.py - ddtrace/contrib/internal/flask_cache/* - - ddtrace/contrib/flask_login/* freezegun: - - ddtrace/contrib/freezegun/* + - ddtrace/contrib/_freezegun.py - ddtrace/contrib/internal/freezegun/* futures: - - ddtrace/contrib/futures/* + - ddtrace/contrib/_futures.py - ddtrace/contrib/internal/futures/* gevent: - - ddtrace/contrib/gevent/* + - ddtrace/contrib/_gevent.py - ddtrace/contrib/internal/gevent/* graphql: - - ddtrace/contrib/graphql/* + - ddtrace/contrib/_graphql.py - ddtrace/contrib/internal/graphql/* grpc: - - ddtrace/contrib/grpc/* + - ddtrace/contrib/_grpc.py - ddtrace/contrib/internal/grpc/* gunicorn: - - ddtrace/contrib/gunicorn/* + - ddtrace/contrib/_gunicorn.py httplib: - - ddtrace/contrib/httplib/* + - ddtrace/contrib/_httplib.py - ddtrace/contrib/internal/httplib/* httpx: - - ddtrace/contrib/httpx/* + - ddtrace/contrib/_httpx.py - ddtrace/contrib/internal/httpx/* jinja2: - - ddtrace/contrib/jinja2/* + - ddtrace/contrib/_jinja2.py - ddtrace/contrib/internal/jinja2/* kafka: - - ddtrace/contrib/kafka/* + - ddtrace/contrib/_kafka.py - ddtrace/contrib/internal/kafka/* - ddtrace/ext/kafka.py kombu: - - ddtrace/contrib/kombu/* + - ddtrace/contrib/_kombu.py - ddtrace/contrib/internal/kombu/* - ddtrace/ext/kombu.py logbook: - - ddtrace/contrib/logbook/* + - ddtrace/contrib/_logbook.py - ddtrace/contrib/internal/logbook/* logging: - - ddtrace/contrib/logging/* + - ddtrace/contrib/_logging.py - ddtrace/contrib/internal/logging/* loguru: - - ddtrace/contrib/logging/* + - ddtrace/contrib/_logging.py - ddtrace/contrib/internal/logging/* - - ddtrace/contrib/loguru/* + - ddtrace/contrib/_loguru.py - ddtrace/contrib/internal/loguru/* mako: - - ddtrace/contrib/mako/* + - ddtrace/contrib/_mako.py - ddtrace/contrib/internal/mako/* mariadb: - - ddtrace/contrib/mariadb/* + - ddtrace/contrib/_mariadb.py - ddtrace/contrib/internal/mariadb/* molten: - - ddtrace/contrib/molten/* + - ddtrace/contrib/_molten.py - ddtrace/contrib/internal/molten/* mongo: - - ddtrace/contrib/pymongo/* + - ddtrace/contrib/_pymongo.py - ddtrace/contrib/internal/pymongo/* - - ddtrace/contrib/mongoengine/* + - ddtrace/contrib/_mongoengine.py - ddtrace/contrib/internal/mongoengine/* - ddtrace/ext/mongo.py mysql: - - ddtrace/contrib/mysql/* + - ddtrace/contrib/_mysql.py - ddtrace/contrib/internal/mysql/* - - ddtrace/contrib/mysqldb/* + - ddtrace/contrib/_mysqldb.py - ddtrace/contrib/internal/mysqldb/* - - ddtrace/contrib/pymysql/* + - ddtrace/contrib/_pymysql.py - ddtrace/contrib/internal/pymysql/* - - ddtrace/contrib/aiomysql/* + - ddtrace/contrib/_aiomysql.py - ddtrace/contrib/internal/aiomysql/* pg: - - ddtrace/contrib/aiopg/* + - ddtrace/contrib/_aiopg.py - ddtrace/contrib/internal/aiopg/* - - ddtrace/contrib/asyncpg/* + - ddtrace/contrib/_asyncpg.py - ddtrace/contrib/internal/psycopg/* - ddtrace/contrib/internal/asyncpg/* - - ddtrace/contrib/psycopg/* + - ddtrace/contrib/_psycopg.py protobuf: - - ddtrace/contrib/protobuf/* + - ddtrace/contrib/_protobuf.py - ddtrace/contrib/internal/protobuf/* pylibmc: - - ddtrace/contrib/pylibmc/* + - ddtrace/contrib/pylibmc.py - ddtrace/contrib/internal/pylibmc/* pymemcache: - - ddtrace/contrib/pymemcache/* + - ddtrace/contrib/_pymemcache.py - ddtrace/contrib/internal/pymemcache/* - ddtrace/ext/memcached.py pynamodb: - - ddtrace/contrib/pynamodb/* + - ddtrace/contrib/_pynamodb.py - ddtrace/contrib/internal/pynamodb/* pyodbc: - - ddtrace/contrib/pyodbc/* + - ddtrace/contrib/_pyodbc.py - ddtrace/contrib/internal/pyodbc/* pyramid: - - ddtrace/contrib/pyramid/* + - ddtrace/contrib/pyramid.py - ddtrace/contrib/internal/pyramid/* redis: - - ddtrace/contrib/rediscluster/* + - ddtrace/contrib/_rediscluster.py - ddtrace/contrib/internal/rediscluster/* - - ddtrace/contrib/redis/* + - ddtrace/contrib/_redis.py - ddtrace/contrib/internal/redis/* - - ddtrace/contrib/aredis/* + - ddtrace/contrib/_aredis.py - ddtrace/contrib/internal/aredis/* - - ddtrace/contrib/yaaredis/* + - ddtrace/contrib/_yaaredis.py - ddtrace/contrib/internal/yaaredis/* - ddtrace/_trace/utils_redis.py - - ddtrace/contrib/redis_utils.py - - ddtrace/contrib/trace_utils_redis.py + - ddtrace/contrib/internal/redis_utils.py - ddtrace/ext/redis.py requests: - - ddtrace/contrib/requests/* + - ddtrace/contrib/requests.py - ddtrace/contrib/internal/requests/* rq: - - ddtrace/contrib/rq/* + - ddtrace/contrib/_rq.py sanic: - - ddtrace/contrib/sanic/* + - ddtrace/contrib/_sanic.py - ddtrace/contrib/internal/sanic/* snowflake: - - ddtrace/contrib/snowflake/* + - ddtrace/contrib/_snowflake.py - ddtrace/contrib/internal/snowflake/* sqlalchemy: - - ddtrace/contrib/sqlalchemy/* + - ddtrace/contrib/sqlalchemy.py - ddtrace/contrib/internal/sqlalchemy/* sqlite3: - - ddtrace/contrib/sqlite3/* + - ddtrace/contrib/_sqlite3.py - ddtrace/contrib/internal/sqlite3/* starlette: - - ddtrace/contrib/starlette/* + - ddtrace/contrib/_starlette.py - ddtrace/contrib/internal/starlette/* structlog: - - ddtrace/contrib/structlog/* + - ddtrace/contrib/_structlog.py - ddtrace/contrib/internal/structlog/* subprocess: - - ddtrace/contrib/subprocess/* + - ddtrace/contrib/_subprocess.py - ddtrace/contrib/internal/subprocess/* tornado: - - ddtrace/contrib/tornado/* + - ddtrace/contrib/tornado.py - ddtrace/contrib/internal/tornado/* urllib3: - - ddtrace/contrib/urllib3/* + - ddtrace/contrib/_urllib3.py - ddtrace/contrib/internal/urllib3/* vertica: - - ddtrace/contrib/vertica/* + - ddtrace/contrib/_vertica.py - ddtrace/contrib/internal/vertica/* wsgi: - - ddtrace/contrib/wsgi/* + - ddtrace/contrib/wsgi.py - ddtrace/contrib/internal/wsgi/* suites: aiobotocore: diff --git a/tests/integration/test_tracemethods.py b/tests/integration/test_tracemethods.py index 15129c56161..7353c12182a 100644 --- a/tests/integration/test_tracemethods.py +++ b/tests/integration/test_tracemethods.py @@ -27,14 +27,10 @@ "mod.mod2.mod3:Class.test_method,Class.test_method2", [("mod.mod2.mod3", "Class.test_method"), ("mod.mod2.mod3", "Class.test_method2")], ), - ("module[method1, method2]", []), ("module", []), ("module.", []), ("module.method", []), - ("module.method[m1,m2,]", []), ("module.method;module.method", []), - ("module.method[m1];module.method[m1,m2,]", []), - ("module.method[[m1]", []), ], ) def test_trace_methods_parse(dd_trace_methods: str, expected_output: List[Tuple[str, str]]): @@ -43,37 +39,6 @@ def test_trace_methods_parse(dd_trace_methods: str, expected_output: List[Tuple[ assert _parse_trace_methods(dd_trace_methods) == expected_output -def test_legacy_trace_methods_parse(): - from ddtrace.internal.tracemethods import _parse_legacy_trace_methods - - assert _parse_legacy_trace_methods("") == [] - assert _parse_legacy_trace_methods("module[method1]") == ["module.method1"] - assert _parse_legacy_trace_methods("module[method1,method2]") == ["module.method1", "module.method2"] - assert _parse_legacy_trace_methods("module[method1,method2];mod2[m1,m2]") == [ - "module.method1", - "module.method2", - "mod2.m1", - "mod2.m2", - ] - assert _parse_legacy_trace_methods("mod.submod[m1,m2,m3]") == ["mod.submod.m1", "mod.submod.m2", "mod.submod.m3"] - assert _parse_legacy_trace_methods("mod.submod.subsubmod[m1,m2]") == [ - "mod.submod.subsubmod.m1", - "mod.submod.subsubmod.m2", - ] - assert _parse_legacy_trace_methods("mod.mod2.mod3.Class[test_method,test_method2]") == [ - "mod.mod2.mod3.Class.test_method", - "mod.mod2.mod3.Class.test_method2", - ] - assert _parse_legacy_trace_methods("module[method1, method2]") == [] - assert _parse_legacy_trace_methods("module") == [] - assert _parse_legacy_trace_methods("module.") == [] - assert _parse_legacy_trace_methods("module.method") == [] - assert _parse_legacy_trace_methods("module.method[m1,m2,]") == [] - assert _parse_legacy_trace_methods("module.method;module.method") == [] - assert _parse_legacy_trace_methods("module.method[m1];module.method[m1,m2,]") == [] - assert _parse_legacy_trace_methods("module.method[[m1]") == [] - - def _test_method(): pass @@ -105,9 +70,9 @@ def test_method(self): ddtrace_run=True, env=dict( DD_TRACE_METHODS=( - "tests.integration.test_tracemethods[_test_method,_test_method2];" - "tests.integration.test_tracemethods._Class[test_method,test_method2];" - "tests.integration.test_tracemethods._Class.NestedClass[test_method]" + "tests.integration.test_tracemethods:_test_method,_test_method2;" + "tests.integration.test_tracemethods:_Class.test_method,_Class.test_method2;" + "tests.integration.test_tracemethods:_Class.NestedClass.test_method" ) ), ) @@ -139,8 +104,8 @@ async def _async_test_method2(): def test_ddtrace_run_trace_methods_async(ddtrace_run_python_code_in_subprocess): env = os.environ.copy() env["DD_TRACE_METHODS"] = ( - "tests.integration.test_tracemethods[_async_test_method,_async_test_method2];" - "tests.integration.test_tracemethods._Class[async_test_method]" + "tests.integration.test_tracemethods:_async_test_method,_async_test_method2;" + "tests.integration.test_tracemethods:_Class.async_test_method" ) tests_dir = os.path.dirname(os.path.dirname(__file__)) env["PYTHONPATH"] = os.pathsep.join([tests_dir, env.get("PYTHONPATH", "")]) diff --git a/tests/internal/test_module.py b/tests/internal/test_module.py index 668dcb3d175..d93c361ac3f 100644 --- a/tests/internal/test_module.py +++ b/tests/internal/test_module.py @@ -528,51 +528,43 @@ def test_module_import_side_effect(): import tests.internal.side_effect_module # noqa:F401 -def test_deprecated_modules_in_ddtrace_contrib(): - # Test that all files in the ddtrace/contrib directory except a few exceptions (ex: ddtrace/contrib/redis_utils.py) - # have the deprecation template below. - deprecation_template = """from ddtrace.contrib.internal.{} import * # noqa: F403 -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate - - -def __getattr__(name): - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - category=DDTraceDeprecationWarning, - ) - - if name in globals(): - return globals()[name] - raise AttributeError("%s has no attribute %s", __name__, name) -""" - +def test_public_modules_in_ddtrace_contrib(): + # Ensures that public modules are not accidentally added to the integration API contrib_dir = Path(DDTRACE_PATH) / "ddtrace" / "contrib" - missing_deprecations = set() + public_modules = set() for directory, _, file_names in os.walk(contrib_dir): - if directory.startswith(str(contrib_dir / "internal")): - # Files in ddtrace/contrib/internal/... are not part of the public API, they should not be deprecated + relative_dir = Path(directory).relative_to(contrib_dir) + if "internal" in relative_dir.parts or any([x.startswith("_") for x in relative_dir.parts]): continue + # Open files in ddtrace/contrib/ and check if the content matches the template for file_name in file_names: # Skip internal and __init__ modules, as they are not supposed to have the deprecation template if file_name.endswith(".py") and not (file_name.startswith("_") or file_name == "__init__.py"): # Get the relative path of the file from ddtrace/contrib to the deprecated file (ex: pymongo/patch) - relative_path = Path(directory).relative_to(contrib_dir) / file_name[:-3] # Remove the .py extension + relative_dir_with_file = relative_dir / file_name[:-3] # Remove the .py extension # Convert the relative path to python module format (ex: [pymongo, patch] -> pymongo.patch) - sub_modules = ".".join(relative_path.parts) - with open(os.path.join(directory, file_name), "r") as f: - content = f.read() - if deprecation_template.format(sub_modules) != content: - missing_deprecations.add(f"ddtrace.contrib.{sub_modules}") - - assert missing_deprecations == set( - [ - "ddtrace.contrib.trace_utils", - # Note: The modules below are deprecated but they do not follow the template above - "ddtrace.contrib.redis_utils", - "ddtrace.contrib.trace_utils_async", - "ddtrace.contrib.trace_utils_redis", - ] - ) + sub_modules = ".".join(relative_dir_with_file.parts) + public_modules.add(f"ddtrace.contrib.{sub_modules}") + + # The following modules contain attributes that are exposed to ddtrace users. All other modules in ddtrace.contrib + # are internal. + assert public_modules == { + "ddtrace.contrib.trace_utils", + "ddtrace.contrib.celery", + "ddtrace.contrib.tornado", + "ddtrace.contrib.asgi", + "ddtrace.contrib.bottle", + "ddtrace.contrib.flask_cache", + "ddtrace.contrib.aiohttp", + "ddtrace.contrib.dbapi_async", + "ddtrace.contrib.wsgi", + "ddtrace.contrib.sqlalchemy", + "ddtrace.contrib.falcon", + "ddtrace.contrib.pylibmc", + "ddtrace.contrib.dbapi", + "ddtrace.contrib.cherrypy", + "ddtrace.contrib.requests", + "ddtrace.contrib.pyramid", + } diff --git a/tests/internal/test_settings.py b/tests/internal/test_settings.py index a3f5fa97802..2ff1843690e 100644 --- a/tests/internal/test_settings.py +++ b/tests/internal/test_settings.py @@ -615,3 +615,28 @@ def test_remoteconfig_header_tags(run_python_code_in_subprocess): env=env, ) assert status == 0, f"err={err.decode('utf-8')} out={out.decode('utf-8')}" + + +def test_config_public_properties_and_methods(): + # Regression test to prevent unexpected changes to public attributes in Config + # By default most attributes should be private and set via Environment Variables + from ddtrace.settings import Config + + public_attrs = set() + c = Config() + # Check for public attributes in Config + for attr in dir(c): + if not attr.startswith("_") and not attr.startswith("__"): + public_attrs.add(attr) + # Check for public keys in Config._config + for key in c._config: + if not key.startswith("_"): + public_attrs.add(key) + + assert public_attrs == { + "service", + "service_mapping", + "env", + "tags", + "version", + }, public_attrs diff --git a/tests/llmobs/suitespec.yml b/tests/llmobs/suitespec.yml index 29ee63dc0dd..a9d3da34dc5 100644 --- a/tests/llmobs/suitespec.yml +++ b/tests/llmobs/suitespec.yml @@ -1,24 +1,24 @@ --- components: anthropic: - - ddtrace/contrib/anthropic/* + - ddtrace/contrib/_anthropic.py - ddtrace/contrib/internal/anthropic/* google_generativeai: - - ddtrace/contrib/google_generativeai/* + - ddtrace/contrib/_google_generativeai.py - ddtrace/contrib/internal/google_generativeai/* vertexai: - - ddtrace/contrib/vertexai/* + - ddtrace/contrib/_vertexai.py - ddtrace/contrib/internal/vertexai/* langchain: - - ddtrace/contrib/langchain/* + - ddtrace/contrib/_langchain.py - ddtrace/contrib/internal/langchain/* llmobs: - ddtrace/llmobs/* openai: - - ddtrace/contrib/openai/* + - ddtrace/contrib/_openai.py - ddtrace/contrib/internal/openai/* langgraph: - - ddtrace/contrib/langgraph/* + - ddtrace/contrib/_langgraph.py - ddtrace/contrib/internal/langgraph/* suites: anthropic: diff --git a/tests/llmobs/test_llmobs_ragas_evaluators.py b/tests/llmobs/test_llmobs_ragas_evaluators.py index c46dce740c2..a182653455a 100644 --- a/tests/llmobs/test_llmobs_ragas_evaluators.py +++ b/tests/llmobs/test_llmobs_ragas_evaluators.py @@ -7,7 +7,7 @@ from ddtrace.llmobs._evaluators.ragas.context_precision import RagasContextPrecisionEvaluator from ddtrace.llmobs._evaluators.ragas.faithfulness import RagasFaithfulnessEvaluator from ddtrace.llmobs._evaluators.runner import EvaluatorRunner -from ddtrace.span import Span +from ddtrace.trace import Span from tests.llmobs._utils import _expected_llmobs_llm_span_event from tests.llmobs._utils import _expected_ragas_answer_relevancy_spans from tests.llmobs._utils import _expected_ragas_context_precision_spans diff --git a/tests/opentracer/core/test_dd_compatibility.py b/tests/opentracer/core/test_dd_compatibility.py index 4ba14b0618f..c68b5ca6d6c 100644 --- a/tests/opentracer/core/test_dd_compatibility.py +++ b/tests/opentracer/core/test_dd_compatibility.py @@ -15,14 +15,6 @@ def test_ottracer_uses_global_ddtracer(self): tracer = ddtrace.opentracer.Tracer() assert tracer._dd_tracer is ddtrace.tracer - def test_custom_ddtracer(self): - """A user should be able to specify their own Datadog tracer instance if - they wish. - """ - custom_dd_tracer = ddtrace.trace.Tracer() - tracer = ddtrace.opentracer.Tracer(dd_tracer=custom_dd_tracer) - assert tracer._dd_tracer is custom_dd_tracer - def test_ot_dd_global_tracers(self, global_tracer): """Ensure our test function opentracer_init() prep""" ot_tracer = global_tracer diff --git a/tests/opentracer/core/test_tracer.py b/tests/opentracer/core/test_tracer.py index a0a18ff0dd8..f5534c8f1b0 100644 --- a/tests/opentracer/core/test_tracer.py +++ b/tests/opentracer/core/test_tracer.py @@ -15,8 +15,6 @@ from ddtrace.opentracer.span_context import SpanContext from ddtrace.propagation.http import HTTP_HEADER_TRACE_ID from ddtrace.settings import ConfigException -from ddtrace.trace import Tracer as DDTracer -from tests.utils import override_global_config class TestTracerConfig(object): @@ -69,12 +67,6 @@ def test_invalid_config_key(self): assert ["enabeld", "setttings"] in str(ce_info) # codespell:ignore assert tracer is not None - def test_ddtrace_fallback_config(self): - """Ensure datadog configuration is used by default.""" - with override_global_config(dict(_tracing_enabled=False)): - tracer = Tracer(dd_tracer=DDTracer()) - assert tracer._dd_tracer.enabled is False - def test_global_tags(self): """Global tags should be passed from the opentracer to the tracer.""" config = { diff --git a/tests/opentracer/test_tracer_asyncio.py b/tests/opentracer/test_tracer_asyncio.py index 230ca776986..35ece48c126 100644 --- a/tests/opentracer/test_tracer_asyncio.py +++ b/tests/opentracer/test_tracer_asyncio.py @@ -3,7 +3,6 @@ import pytest from ddtrace.constants import ERROR_MSG -from ddtrace.contrib.asyncio import context_provider @pytest.mark.asyncio @@ -66,8 +65,6 @@ async def f1(): @pytest.mark.asyncio async def test_trace_multiple_calls(ot_tracer, test_spans): - ot_tracer._dd_tracer._configure(context_provider=context_provider) - # create multiple futures so that we expect multiple # traces instead of a single one (helper not used) async def coro(): diff --git a/tests/opentracer/test_tracer_gevent.py b/tests/opentracer/test_tracer_gevent.py index 90b22c644d0..320b39ee997 100644 --- a/tests/opentracer/test_tracer_gevent.py +++ b/tests/opentracer/test_tracer_gevent.py @@ -2,7 +2,6 @@ from opentracing.scope_managers.gevent import GeventScopeManager import pytest -from ddtrace.contrib.gevent import context_provider from ddtrace.contrib.internal.gevent.patch import patch from ddtrace.contrib.internal.gevent.patch import unpatch @@ -12,7 +11,7 @@ def ot_tracer(ot_tracer_factory): """Fixture providing an opentracer configured for gevent usage.""" # patch gevent patch() - yield ot_tracer_factory("gevent_svc", {}, GeventScopeManager(), context_provider) + yield ot_tracer_factory("gevent_svc", {}, GeventScopeManager()) # unpatch gevent unpatch() diff --git a/tests/opentracer/utils.py b/tests/opentracer/utils.py index 6a34052a385..85b84865ad8 100644 --- a/tests/opentracer/utils.py +++ b/tests/opentracer/utils.py @@ -7,5 +7,5 @@ def init_tracer(service_name, dd_tracer, scope_manager=None): It accepts a Datadog tracer that should be the same one used for testing. """ - ot_tracer = Tracer(service_name, dd_tracer=dd_tracer, scope_manager=scope_manager) + ot_tracer = Tracer(service_name, scope_manager=scope_manager, _dd_tracer=dd_tracer) return ot_tracer diff --git a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-None].json b/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-None].json deleted file mode 100644 index 65eec00d960..00000000000 --- a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-None].json +++ /dev/null @@ -1,77 +0,0 @@ -[[ - { - "name": "openai.request", - "service": "ddtrace_subprocess_dir", - "resource": "createCompletion", - "trace_id": 0, - "span_id": 1, - "parent_id": 0, - "type": "", - "error": 0, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "65674d7100000000", - "component": "openai", - "language": "python", - "openai.api_base": "https://api.openai.com/v1", - "openai.api_type": "open_ai", - "openai.organization.name": "datadog-4", - "openai.request.client": "OpenAI", - "openai.request.endpoint": "/v1/completions", - "openai.request.max_tokens": "10", - "openai.request.method": "POST", - "openai.request.model": "ada", - "openai.request.n": "2", - "openai.request.prompt.0": "Hello world", - "openai.request.stop": ".", - "openai.request.temperature": "0.8", - "openai.response.choices.0.finish_reason": "length", - "openai.response.choices.0.text": ", relax!\u201d I said to my laptop", - "openai.response.choices.1.finish_reason": "stop", - "openai.response.choices.1.text": " (1", - "openai.response.created": "1681852797", - "openai.response.id": "cmpl-76n1xLvRKv3mfjx7hJ41UHrHy9ar6", - "openai.response.model": "ada", - "openai.user.api_key": "sk-...key>", - "runtime-id": "8c92d3e850d9413593bf481d805039d1" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1, - "_dd.tracer_kr": 1.0, - "_sampling_priority_v1": 1, - "openai.organization.ratelimit.requests.limit": 3000, - "openai.organization.ratelimit.requests.remaining": 2999, - "openai.organization.ratelimit.tokens.limit": 250000, - "openai.organization.ratelimit.tokens.remaining": 249979, - "process_id": 20673 - }, - "duration": 21745000, - "start": 1701268849462298000 - }, - { - "name": "requests.request", - "service": "openai", - "resource": "POST /v1/completions", - "trace_id": 0, - "span_id": 2, - "parent_id": 1, - "type": "http", - "error": 0, - "meta": { - "_dd.base_service": "ddtrace_subprocess_dir", - "component": "requests", - "http.method": "POST", - "http.status_code": "200", - "http.url": "https://api.openai.com/v1/completions", - "http.useragent": "OpenAI/v1 PythonBindings/0.27.2", - "out.host": "api.openai.com", - "span.kind": "client" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1 - }, - "duration": 2999000, - "start": 1701268849479960000 - }]] diff --git a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-v0].json b/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-v0].json deleted file mode 100644 index d6417fb5667..00000000000 --- a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-v0].json +++ /dev/null @@ -1,77 +0,0 @@ -[[ - { - "name": "openai.request", - "service": "ddtrace_subprocess_dir", - "resource": "createCompletion", - "trace_id": 0, - "span_id": 1, - "parent_id": 0, - "type": "", - "error": 0, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "65674d7200000000", - "component": "openai", - "language": "python", - "openai.api_base": "https://api.openai.com/v1", - "openai.api_type": "open_ai", - "openai.organization.name": "datadog-4", - "openai.request.client": "OpenAI", - "openai.request.endpoint": "/v1/completions", - "openai.request.max_tokens": "10", - "openai.request.method": "POST", - "openai.request.model": "ada", - "openai.request.n": "2", - "openai.request.prompt.0": "Hello world", - "openai.request.stop": ".", - "openai.request.temperature": "0.8", - "openai.response.choices.0.finish_reason": "length", - "openai.response.choices.0.text": ", relax!\u201d I said to my laptop", - "openai.response.choices.1.finish_reason": "stop", - "openai.response.choices.1.text": " (1", - "openai.response.created": "1681852797", - "openai.response.id": "cmpl-76n1xLvRKv3mfjx7hJ41UHrHy9ar6", - "openai.response.model": "ada", - "openai.user.api_key": "sk-...key>", - "runtime-id": "675032183b244929ba8c3a0a1c0021e5" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1, - "_dd.tracer_kr": 1.0, - "_sampling_priority_v1": 1, - "openai.organization.ratelimit.requests.limit": 3000, - "openai.organization.ratelimit.requests.remaining": 2999, - "openai.organization.ratelimit.tokens.limit": 250000, - "openai.organization.ratelimit.tokens.remaining": 249979, - "process_id": 20696 - }, - "duration": 20412000, - "start": 1701268850764763000 - }, - { - "name": "requests.request", - "service": "openai", - "resource": "POST /v1/completions", - "trace_id": 0, - "span_id": 2, - "parent_id": 1, - "type": "http", - "error": 0, - "meta": { - "_dd.base_service": "ddtrace_subprocess_dir", - "component": "requests", - "http.method": "POST", - "http.status_code": "200", - "http.url": "https://api.openai.com/v1/completions", - "http.useragent": "OpenAI/v1 PythonBindings/0.27.2", - "out.host": "api.openai.com", - "span.kind": "client" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1 - }, - "duration": 3134000, - "start": 1701268850780901000 - }]] diff --git a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-v1].json b/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-v1].json deleted file mode 100644 index 979ea768ef5..00000000000 --- a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[None-v1].json +++ /dev/null @@ -1,77 +0,0 @@ -[[ - { - "name": "openai.request", - "service": "ddtrace_subprocess_dir", - "resource": "createCompletion", - "trace_id": 0, - "span_id": 1, - "parent_id": 0, - "type": "", - "error": 0, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "65674d7400000000", - "component": "openai", - "language": "python", - "openai.api_base": "https://api.openai.com/v1", - "openai.api_type": "open_ai", - "openai.organization.name": "datadog-4", - "openai.request.client": "OpenAI", - "openai.request.endpoint": "/v1/completions", - "openai.request.max_tokens": "10", - "openai.request.method": "POST", - "openai.request.model": "ada", - "openai.request.n": "2", - "openai.request.prompt.0": "Hello world", - "openai.request.stop": ".", - "openai.request.temperature": "0.8", - "openai.response.choices.0.finish_reason": "length", - "openai.response.choices.0.text": ", relax!\u201d I said to my laptop", - "openai.response.choices.1.finish_reason": "stop", - "openai.response.choices.1.text": " (1", - "openai.response.created": "1681852797", - "openai.response.id": "cmpl-76n1xLvRKv3mfjx7hJ41UHrHy9ar6", - "openai.response.model": "ada", - "openai.user.api_key": "sk-...key>", - "runtime-id": "1f3499a720954236be60cf0fece4246c" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1, - "_dd.tracer_kr": 1.0, - "_sampling_priority_v1": 1, - "openai.organization.ratelimit.requests.limit": 3000, - "openai.organization.ratelimit.requests.remaining": 2999, - "openai.organization.ratelimit.tokens.limit": 250000, - "openai.organization.ratelimit.tokens.remaining": 249979, - "process_id": 20714 - }, - "duration": 19970000, - "start": 1701268852029562000 - }, - { - "name": "http.client.request", - "service": "ddtrace_subprocess_dir", - "resource": "POST /v1/completions", - "trace_id": 0, - "span_id": 2, - "parent_id": 1, - "type": "http", - "error": 0, - "meta": { - "_dd.peer.service.source": "out.host", - "component": "requests", - "http.method": "POST", - "http.status_code": "200", - "http.url": "https://api.openai.com/v1/completions", - "http.useragent": "OpenAI/v1 PythonBindings/0.27.2", - "out.host": "api.openai.com", - "peer.service": "api.openai.com", - "span.kind": "client" - }, - "metrics": { - "_dd.measured": 1 - }, - "duration": 2897000, - "start": 1701268852045569000 - }]] diff --git a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-None].json b/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-None].json deleted file mode 100644 index a80c1218caf..00000000000 --- a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-None].json +++ /dev/null @@ -1,77 +0,0 @@ -[[ - { - "name": "openai.request", - "service": "mysvc", - "resource": "createCompletion", - "trace_id": 0, - "span_id": 1, - "parent_id": 0, - "type": "", - "error": 0, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "65674d7500000000", - "component": "openai", - "language": "python", - "openai.api_base": "https://api.openai.com/v1", - "openai.api_type": "open_ai", - "openai.organization.name": "datadog-4", - "openai.request.client": "OpenAI", - "openai.request.endpoint": "/v1/completions", - "openai.request.max_tokens": "10", - "openai.request.method": "POST", - "openai.request.model": "ada", - "openai.request.n": "2", - "openai.request.prompt.0": "Hello world", - "openai.request.stop": ".", - "openai.request.temperature": "0.8", - "openai.response.choices.0.finish_reason": "length", - "openai.response.choices.0.text": ", relax!\u201d I said to my laptop", - "openai.response.choices.1.finish_reason": "stop", - "openai.response.choices.1.text": " (1", - "openai.response.created": "1681852797", - "openai.response.id": "cmpl-76n1xLvRKv3mfjx7hJ41UHrHy9ar6", - "openai.response.model": "ada", - "openai.user.api_key": "sk-...key>", - "runtime-id": "1244eea37568412fb5bdedf9c37ed48a" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1, - "_dd.tracer_kr": 1.0, - "_sampling_priority_v1": 1, - "openai.organization.ratelimit.requests.limit": 3000, - "openai.organization.ratelimit.requests.remaining": 2999, - "openai.organization.ratelimit.tokens.limit": 250000, - "openai.organization.ratelimit.tokens.remaining": 249979, - "process_id": 20736 - }, - "duration": 19953000, - "start": 1701268853284736000 - }, - { - "name": "requests.request", - "service": "openai", - "resource": "POST /v1/completions", - "trace_id": 0, - "span_id": 2, - "parent_id": 1, - "type": "http", - "error": 0, - "meta": { - "_dd.base_service": "mysvc", - "component": "requests", - "http.method": "POST", - "http.status_code": "200", - "http.url": "https://api.openai.com/v1/completions", - "http.useragent": "OpenAI/v1 PythonBindings/0.27.2", - "out.host": "api.openai.com", - "span.kind": "client" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1 - }, - "duration": 2837000, - "start": 1701268853300833000 - }]] diff --git a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-v0].json b/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-v0].json deleted file mode 100644 index f3f9c57f768..00000000000 --- a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-v0].json +++ /dev/null @@ -1,77 +0,0 @@ -[[ - { - "name": "openai.request", - "service": "mysvc", - "resource": "createCompletion", - "trace_id": 0, - "span_id": 1, - "parent_id": 0, - "type": "", - "error": 0, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "65674d7600000000", - "component": "openai", - "language": "python", - "openai.api_base": "https://api.openai.com/v1", - "openai.api_type": "open_ai", - "openai.organization.name": "datadog-4", - "openai.request.client": "OpenAI", - "openai.request.endpoint": "/v1/completions", - "openai.request.max_tokens": "10", - "openai.request.method": "POST", - "openai.request.model": "ada", - "openai.request.n": "2", - "openai.request.prompt.0": "Hello world", - "openai.request.stop": ".", - "openai.request.temperature": "0.8", - "openai.response.choices.0.finish_reason": "length", - "openai.response.choices.0.text": ", relax!\u201d I said to my laptop", - "openai.response.choices.1.finish_reason": "stop", - "openai.response.choices.1.text": " (1", - "openai.response.created": "1681852797", - "openai.response.id": "cmpl-76n1xLvRKv3mfjx7hJ41UHrHy9ar6", - "openai.response.model": "ada", - "openai.user.api_key": "sk-...key>", - "runtime-id": "12b4a711854c44f681695957b545dcf5" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1, - "_dd.tracer_kr": 1.0, - "_sampling_priority_v1": 1, - "openai.organization.ratelimit.requests.limit": 3000, - "openai.organization.ratelimit.requests.remaining": 2999, - "openai.organization.ratelimit.tokens.limit": 250000, - "openai.organization.ratelimit.tokens.remaining": 249979, - "process_id": 20750 - }, - "duration": 25352000, - "start": 1701268854568669000 - }, - { - "name": "requests.request", - "service": "openai", - "resource": "POST /v1/completions", - "trace_id": 0, - "span_id": 2, - "parent_id": 1, - "type": "http", - "error": 0, - "meta": { - "_dd.base_service": "mysvc", - "component": "requests", - "http.method": "POST", - "http.status_code": "200", - "http.url": "https://api.openai.com/v1/completions", - "http.useragent": "OpenAI/v1 PythonBindings/0.27.2", - "out.host": "api.openai.com", - "span.kind": "client" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1 - }, - "duration": 3922000, - "start": 1701268854588758000 - }]] diff --git a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-v1].json b/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-v1].json deleted file mode 100644 index 0696ae54454..00000000000 --- a/tests/snapshots/tests.contrib.openai.test_openai_v0.test_integration_service_name[mysvc-v1].json +++ /dev/null @@ -1,77 +0,0 @@ -[[ - { - "name": "openai.request", - "service": "mysvc", - "resource": "createCompletion", - "trace_id": 0, - "span_id": 1, - "parent_id": 0, - "type": "", - "error": 0, - "meta": { - "_dd.p.dm": "-0", - "_dd.p.tid": "65674d7700000000", - "component": "openai", - "language": "python", - "openai.api_base": "https://api.openai.com/v1", - "openai.api_type": "open_ai", - "openai.organization.name": "datadog-4", - "openai.request.client": "OpenAI", - "openai.request.endpoint": "/v1/completions", - "openai.request.max_tokens": "10", - "openai.request.method": "POST", - "openai.request.model": "ada", - "openai.request.n": "2", - "openai.request.prompt.0": "Hello world", - "openai.request.stop": ".", - "openai.request.temperature": "0.8", - "openai.response.choices.0.finish_reason": "length", - "openai.response.choices.0.text": ", relax!\u201d I said to my laptop", - "openai.response.choices.1.finish_reason": "stop", - "openai.response.choices.1.text": " (1", - "openai.response.created": "1681852797", - "openai.response.id": "cmpl-76n1xLvRKv3mfjx7hJ41UHrHy9ar6", - "openai.response.model": "ada", - "openai.user.api_key": "sk-...key>", - "runtime-id": "03e7664126ea4fe99e0aefec4efd003c" - }, - "metrics": { - "_dd.measured": 1, - "_dd.top_level": 1, - "_dd.tracer_kr": 1.0, - "_sampling_priority_v1": 1, - "openai.organization.ratelimit.requests.limit": 3000, - "openai.organization.ratelimit.requests.remaining": 2999, - "openai.organization.ratelimit.tokens.limit": 250000, - "openai.organization.ratelimit.tokens.remaining": 249979, - "process_id": 20772 - }, - "duration": 19966000, - "start": 1701268855885252000 - }, - { - "name": "http.client.request", - "service": "mysvc", - "resource": "POST /v1/completions", - "trace_id": 0, - "span_id": 2, - "parent_id": 1, - "type": "http", - "error": 0, - "meta": { - "_dd.peer.service.source": "out.host", - "component": "requests", - "http.method": "POST", - "http.status_code": "200", - "http.url": "https://api.openai.com/v1/completions", - "http.useragent": "OpenAI/v1 PythonBindings/0.27.2", - "out.host": "api.openai.com", - "peer.service": "api.openai.com", - "span.kind": "client" - }, - "metrics": { - "_dd.measured": 1 - }, - "duration": 2849000, - "start": 1701268855901267000 - }]] diff --git a/tests/suitespec.yml b/tests/suitespec.yml index b135ba986c8..d9da18df66d 100644 --- a/tests/suitespec.yml +++ b/tests/suitespec.yml @@ -116,15 +116,6 @@ components: - ddtrace/_trace/* - ddtrace/trace/* - ddtrace/constants.py - - ddtrace/context.py - - ddtrace/filters.py - - ddtrace/pin.py - - ddtrace/provider.py - - ddtrace/sampler.py - - ddtrace/sampling_rule.py - - ddtrace/span.py - - ddtrace/tracer.py - - ddtrace/tracing/* - ddtrace/settings/__init__.py - ddtrace/settings/config.py - ddtrace/settings/http.py diff --git a/tests/tracer/test_sampler.py b/tests/tracer/test_sampler.py index 813dc1be439..22620d8184b 100644 --- a/tests/tracer/test_sampler.py +++ b/tests/tracer/test_sampler.py @@ -1,6 +1,5 @@ from __future__ import division -import re import unittest import mock @@ -250,7 +249,7 @@ def test_sampling_rule_init_defaults(): def test_sampling_rule_init(): - a_regex = re.compile(r"\.request$") + a_regex = "*request" a_string = "my-service" rule = SamplingRule( @@ -261,7 +260,7 @@ def test_sampling_rule_init(): assert rule.sample_rate == 0.0, "SamplingRule should store the rate it's initialized with" assert rule.service.pattern == a_string, "SamplingRule should store the service it's initialized with" - assert rule.name == a_regex, "SamplingRule should store the name regex it's initialized with" + assert rule.name.pattern == a_regex, "SamplingRule should store the name regex it's initialized with" @pytest.mark.parametrize( @@ -272,38 +271,13 @@ def test_sampling_rule_init(): (SamplingRule(sample_rate=0.0), SamplingRule(sample_rate=0.0), True), (SamplingRule(sample_rate=0.5), SamplingRule(sample_rate=1.0), False), (SamplingRule(sample_rate=1.0, service="my-svc"), SamplingRule(sample_rate=1.0, service="my-svc"), True), - ( - SamplingRule(sample_rate=1.0, service=re.compile("my-svc")), - SamplingRule(sample_rate=1.0, service=re.compile("my-svc")), - True, - ), (SamplingRule(sample_rate=1.0, service="my-svc"), SamplingRule(sample_rate=1.0, service="other-svc"), False), (SamplingRule(sample_rate=1.0, service="my-svc"), SamplingRule(sample_rate=0.5, service="my-svc"), False), - ( - SamplingRule(sample_rate=1.0, service=re.compile("my-svc")), - SamplingRule(sample_rate=0.5, service=re.compile("my-svc")), - False, - ), - ( - SamplingRule(sample_rate=1.0, service=re.compile("my-svc")), - SamplingRule(sample_rate=1.0, service=re.compile("other")), - False, - ), ( SamplingRule(sample_rate=1.0, name="span.name"), SamplingRule(sample_rate=1.0, name="span.name"), True, ), - ( - SamplingRule(sample_rate=1.0, name=re.compile("span.name")), - SamplingRule(sample_rate=1.0, name=re.compile("span.name")), - True, - ), - ( - SamplingRule(sample_rate=1.0, name=re.compile("span.name")), - SamplingRule(sample_rate=1.0, name=re.compile("span.other")), - False, - ), ( SamplingRule(sample_rate=1.0, name="span.name"), SamplingRule(sample_rate=0.5, name="span.name"), @@ -316,16 +290,6 @@ def test_sampling_rule_init(): SamplingRule(sample_rate=1.0, service="my-svc", name="span.name"), True, ), - ( - SamplingRule(sample_rate=1.0, service="my-svc", name=re.compile("span.name")), - SamplingRule(sample_rate=1.0, service="my-svc", name=re.compile("span.name")), - True, - ), - ( - SamplingRule(sample_rate=1.0, service=re.compile("my-svc"), name=re.compile("span.name")), - SamplingRule(sample_rate=1.0, service=re.compile("my-svc"), name=re.compile("span.name")), - True, - ), ( SamplingRule(sample_rate=1.0, service="my-svc", name="span.name"), SamplingRule(sample_rate=0.5, service="my-svc", name="span.name"), @@ -491,15 +455,6 @@ def test_sampling_rule_init_via_env(): ("test.span", None, False), ("test.span", "test.span", True), ("test.span", "test_span", False), - ("test.span", re.compile(r"^test\.span$"), True), - ("test_span", re.compile(r"^test.span$"), True), - ("test.span", re.compile(r"^test_span$"), False), - ("test.span", re.compile(r"test"), True), - ("test.span", re.compile(r"test\.span|another\.span"), True), - ("another.span", re.compile(r"test\.span|another\.span"), True), - ("test.span", lambda name: "span" in name, True), - ("test.span", lambda name: "span" not in name, False), - ("test.span", lambda name: 1 / 0, False), ] ], ) @@ -518,20 +473,8 @@ def test_sampling_rule_matches_name(span, rule, span_expected_to_match_rule): ("my-service", None, False), (None, "tests.tracer", True), ("tests.tracer", "my-service", False), - ("tests.tracer", re.compile(r"my-service"), False), - ("tests.tracer", lambda service: "service" in service, False), ("my-service", "my-service", True), ("my-service", "my_service", False), - ("my-service", re.compile(r"^my-"), True), - ("my_service", re.compile(r"^my[_-]"), True), - ("my-service", re.compile(r"^my_"), False), - ("my-service", re.compile(r"my-service"), True), - ("my-service", re.compile(r"my"), True), - ("my-service", re.compile(r"my-service|another-service"), True), - ("another-service", re.compile(r"my-service|another-service"), True), - ("my-service", lambda service: "service" in service, True), - ("my-service", lambda service: "service" not in service, False), - ("my-service", lambda service: 1 / 0, False), ] ], ) @@ -553,7 +496,7 @@ def test_sampling_rule_matches_service(span, rule, span_expected_to_match_rule): SamplingRule( sample_rate=1, name="test.span", - service=re.compile(r"^my-"), + service="my-*", ), True, ), @@ -567,7 +510,7 @@ def test_sampling_rule_matches_service(span, rule, span_expected_to_match_rule): SamplingRule( sample_rate=0, name="test.span", - service=re.compile(r"^my-"), + service="my-*", ), True, ), @@ -580,7 +523,7 @@ def test_sampling_rule_matches_service(span, rule, span_expected_to_match_rule): SamplingRule( sample_rate=1, name="test_span", - service=re.compile(r"^my-"), + service="my-*", ), False, ), @@ -593,7 +536,7 @@ def test_sampling_rule_matches_service(span, rule, span_expected_to_match_rule): SamplingRule( sample_rate=1, name="test.span", - service=re.compile(r"^service-"), + service="service-", ), False, ), @@ -605,26 +548,6 @@ def test_sampling_rule_matches(span, rule, span_expected_to_match_rule): ) -def test_sampling_rule_matches_exception(): - def pattern(prop): - raise Exception("an error occurred") - - rule = SamplingRule(sample_rate=1.0, name=pattern) - span = create_span(name="test.span") - - with mock.patch("ddtrace._trace.sampling_rule.log") as mock_log: - assert ( - rule.matches(span) is False - ), "SamplingRule should not match when its name pattern function throws an exception" - mock_log.warning.assert_called_once_with( - "%r pattern %r failed with %r", - rule, - pattern, - "test.span", - exc_info=True, - ) - - @pytest.mark.subprocess( parametrize={"DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED": ["true", "false"]}, ) diff --git a/tests/tracer/test_tracer.py b/tests/tracer/test_tracer.py index 0a75e5fc037..1aa1c42bf1d 100644 --- a/tests/tracer/test_tracer.py +++ b/tests/tracer/test_tracer.py @@ -2010,21 +2010,6 @@ def test_ctx_api(): assert core.get_items(["appsec.key"]) == [None] -@pytest.mark.subprocess(parametrize={"IMPORT_DDTRACE_TRACER": ["true", "false"]}) -def test_import_ddtrace_tracer_not_module(): - import os - - import_ddtrace_tracer = os.environ["IMPORT_DDTRACE_TRACER"] == "true" - - if import_ddtrace_tracer: - import ddtrace.tracer # noqa: F401 - - from ddtrace.trace import Tracer - from ddtrace.trace import tracer - - assert isinstance(tracer, Tracer) - - @pytest.mark.parametrize("sca_enabled", ["true", "false"]) @pytest.mark.parametrize("appsec_enabled", [True, False]) @pytest.mark.parametrize("iast_enabled", [True, False])