sentry_sdk.client
import os import uuid import random import socket from collections.abc import Mapping from datetime import datetime, timezone from importlib import import_module from typing import TYPE_CHECKING, List, Dict, cast, overload import warnings from sentry_sdk._compat import check_uwsgi_thread_support from sentry_sdk._metrics_batcher import MetricsBatcher from sentry_sdk._span_batcher import SpanBatcher from sentry_sdk.utils import ( AnnotatedValue, ContextVar, capture_internal_exceptions, current_stacktrace, env_to_bool, format_timestamp, get_sdk_name, get_type_name, get_default_release, handle_in_app, logger, get_before_send_log, get_before_send_metric, has_logs_enabled, has_metrics_enabled, ) from sentry_sdk.serializer import serialize from sentry_sdk.tracing import trace from sentry_sdk.tracing_utils import has_span_streaming_enabled from sentry_sdk.transport import ( HttpTransportCore, make_transport, AsyncHttpTransport, ) from sentry_sdk.consts import ( SPANDATA, DEFAULT_MAX_VALUE_LENGTH, DEFAULT_OPTIONS, INSTRUMENTER, VERSION, ClientConstructor, ) from sentry_sdk.integrations import _DEFAULT_INTEGRATIONS, setup_integrations from sentry_sdk.integrations.dedupe import DedupeIntegration from sentry_sdk.sessions import SessionFlusher from sentry_sdk.envelope import Envelope from sentry_sdk.profiler.continuous_profiler import setup_continuous_profiler from sentry_sdk.profiler.transaction_profiler import ( has_profiling_enabled, Profile, setup_profiler, ) from sentry_sdk.scrubber import EventScrubber from sentry_sdk.monitor import Monitor if TYPE_CHECKING: from typing import Any from typing import Callable from typing import Optional from typing import Sequence from typing import Type from typing import Union from typing import TypeVar from sentry_sdk._types import Event, Hint, SDKInfo, Log, Metric, EventDataCategory from sentry_sdk.integrations import Integration from sentry_sdk.scope import Scope from sentry_sdk.session import Session from sentry_sdk.spotlight import SpotlightClient from sentry_sdk.traces import StreamedSpan from sentry_sdk.transport import Transport, Item from sentry_sdk._log_batcher import LogBatcher from sentry_sdk._metrics_batcher import MetricsBatcher from sentry_sdk.utils import Dsn I = TypeVar("I", bound=Integration) # noqa: E741 _client_init_debug = ContextVar("client_init_debug") SDK_INFO: "SDKInfo" = { "name": "sentry.python", # SDK name will be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations() "version": VERSION, "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], } def _get_options(*args: "Optional[str]", **kwargs: "Any") -> "Dict[str, Any]": if args and (isinstance(args[0], (bytes, str)) or args[0] is None): dsn: "Optional[str]" = args[0] args = args[1:] else: dsn = None if len(args) > 1: raise TypeError("Only single positional argument is expected") rv = dict(DEFAULT_OPTIONS) options = dict(*args, **kwargs) if dsn is not None and options.get("dsn") is None: options["dsn"] = dsn for key, value in options.items(): if key not in rv: raise TypeError("Unknown option %r" % (key,)) rv[key] = value if rv["dsn"] is None: rv["dsn"] = os.environ.get("SENTRY_DSN") if rv["release"] is None: rv["release"] = get_default_release() if rv["environment"] is None: rv["environment"] = os.environ.get("SENTRY_ENVIRONMENT") or "production" if rv["debug"] is None: rv["debug"] = env_to_bool(os.environ.get("SENTRY_DEBUG"), strict=True) or False if rv["server_name"] is None and hasattr(socket, "gethostname"): rv["server_name"] = socket.gethostname() if rv["instrumenter"] is None: rv["instrumenter"] = INSTRUMENTER.SENTRY if rv["project_root"] is None: try: project_root = os.getcwd() except Exception: project_root = None rv["project_root"] = project_root if rv["enable_tracing"] is True and rv["traces_sample_rate"] is None: rv["traces_sample_rate"] = 1.0 if rv["event_scrubber"] is None: rv["event_scrubber"] = EventScrubber( send_default_pii=( False if rv["send_default_pii"] is None else rv["send_default_pii"] ) ) if rv["socket_options"] and not isinstance(rv["socket_options"], list): logger.warning( "Ignoring socket_options because of unexpected format. See urllib3.HTTPConnection.socket_options for the expected format." ) rv["socket_options"] = None if rv["keep_alive"] is None: rv["keep_alive"] = ( env_to_bool(os.environ.get("SENTRY_KEEP_ALIVE"), strict=True) or False ) if rv["enable_tracing"] is not None: warnings.warn( "The `enable_tracing` parameter is deprecated. Please use `traces_sample_rate` instead.", DeprecationWarning, stacklevel=2, ) return rv try: # Python 3.6+ module_not_found_error = ModuleNotFoundError except Exception: # Older Python versions module_not_found_error = ImportError # type: ignore class BaseClient: """ .. versionadded:: 2.0.0 The basic definition of a client that is used for sending data to Sentry. """ spotlight: "Optional[SpotlightClient]" = None def __init__(self, options: "Optional[Dict[str, Any]]" = None) -> None: self.options: "Dict[str, Any]" = ( options if options is not None else DEFAULT_OPTIONS ) self.transport: "Optional[Transport]" = None self.monitor: "Optional[Monitor]" = None self.log_batcher: "Optional[LogBatcher]" = None self.metrics_batcher: "Optional[MetricsBatcher]" = None self.span_batcher: "Optional[SpanBatcher]" = None self.integrations: "dict[str, Integration]" = {} def __getstate__(self, *args: "Any", **kwargs: "Any") -> "Any": return {"options": {}} def __setstate__(self, *args: "Any", **kwargs: "Any") -> None: pass @property def dsn(self) -> "Optional[str]": return None @property def parsed_dsn(self) -> "Optional[Dsn]": return None def should_send_default_pii(self) -> bool: return False def is_active(self) -> bool: """ .. versionadded:: 2.0.0 Returns whether the client is active (able to send data to Sentry) """ return False