Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow (some) autocompletion for top-level API #2213

Merged
merged 16 commits into from
Jul 4, 2023
6 changes: 6 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ Main API
.. automodule:: sentry_sdk
:members:
:inherited-members:

.. autoclass:: sentry_sdk.tracing.Span
:members:

.. autoclass:: sentry_sdk.tracing.Transaction
:members:
91 changes: 28 additions & 63 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import inspect
from functools import partial

from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.hub import Hub
from sentry_sdk.scope import Scope
from sentry_sdk.tracing import NoOpSpan, Transaction
from sentry_sdk.tracing import Transaction

if TYPE_CHECKING:
from typing import Any
Expand All @@ -13,16 +14,8 @@
from typing import Callable
from typing import TypeVar
from typing import ContextManager
from typing import Union

from sentry_sdk._types import (
Event,
Hint,
Breadcrumb,
BreadcrumbHint,
ExcInfo,
MeasurementUnit,
)

from sentry_sdk._types import MeasurementUnit

Check warning on line 18 in sentry_sdk/api.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/api.py#L18

Added line #L18 was not covered by tests
from sentry_sdk.tracing import Span

T = TypeVar("T")
Expand Down Expand Up @@ -77,46 +70,36 @@
return f


@hubmethod
def capture_event(
event, # type: Event
hint=None, # type: Optional[Hint]
scope=None, # type: Optional[Any]
**scope_args # type: Any
):
# type: (...) -> Optional[str]
return Hub.current.capture_event(event, hint, scope=scope, **scope_args)
# Alias these functions to have nice auto completion for the arguments without
# having to specify them here. The `partial(..., None)` hack is needed for Sphinx
# to generate proper docs for these.
if TYPE_CHECKING:
capture_event = partial(Hub.capture_event, None)
capture_message = partial(Hub.capture_message, None)
capture_exception = partial(Hub.capture_exception, None)
add_breadcrumb = partial(Hub.add_breadcrumb, None)
start_span = partial(Hub.start_span, None)
start_transaction = partial(Hub.start_transaction, None)

Check warning on line 82 in sentry_sdk/api.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/api.py#L77-L82

Added lines #L77 - L82 were not covered by tests

else:

@hubmethod
def capture_message(
message, # type: str
level=None, # type: Optional[str]
scope=None, # type: Optional[Any]
**scope_args # type: Any
):
# type: (...) -> Optional[str]
return Hub.current.capture_message(message, level, scope=scope, **scope_args)
def capture_event(*args, **kwargs):
return Hub.current.capture_event(*args, **kwargs)

def capture_message(*args, **kwargs):
return Hub.current.capture_message(*args, **kwargs)

@hubmethod
def capture_exception(
error=None, # type: Optional[Union[BaseException, ExcInfo]]
scope=None, # type: Optional[Any]
**scope_args # type: Any
):
# type: (...) -> Optional[str]
return Hub.current.capture_exception(error, scope=scope, **scope_args)
def capture_exception(*args, **kwargs):
return Hub.current.capture_exception(*args, **kwargs)

def add_breadcrumb(*args, **kwargs):
return Hub.current.add_breadcrumb(*args, **kwargs)

@hubmethod
def add_breadcrumb(
crumb=None, # type: Optional[Breadcrumb]
hint=None, # type: Optional[BreadcrumbHint]
**kwargs # type: Any
):
# type: (...) -> None
return Hub.current.add_breadcrumb(crumb, hint, **kwargs)
def start_span(*args, **kwargs):
return Hub.current.start_span(*args, **kwargs)

def start_transaction(*args, **kwargs):
return Hub.current.start_transaction(*args, **kwargs)


@overload
Expand Down Expand Up @@ -208,24 +191,6 @@
return Hub.current.last_event_id()


@hubmethod
def start_span(
span=None, # type: Optional[Span]
**kwargs # type: Any
):
# type: (...) -> Span
return Hub.current.start_span(span=span, **kwargs)


@hubmethod
def start_transaction(
transaction=None, # type: Optional[Transaction]
**kwargs # type: Any
):
# type: (...) -> Union[Transaction, NoOpSpan]
return Hub.current.start_transaction(transaction, **kwargs)


def set_measurement(name, value, unit=""):
# type: (str, float, MeasurementUnit) -> None
transaction = Hub.current.scope.transaction
Expand Down
3 changes: 3 additions & 0 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ def capture_event(
:param hint: Contains metadata about the event that can be read from `before_send`, such as the original exception object or a HTTP request object.
:param scope: An optional scope to use for determining whether this event
should be captured.
:returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help.
"""
if disable_capture_event.get(False):
Expand Down
71 changes: 61 additions & 10 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,14 @@ def bind_client(

def capture_event(self, event, hint=None, scope=None, **scope_args):
# type: (Event, Optional[Hint], Optional[Scope], Any) -> Optional[str]
"""Captures an event. Alias of :py:meth:`sentry_sdk.Client.capture_event`."""
"""
Captures an event.

Alias of :py:meth:`sentry_sdk.Client.capture_event`.

:param scope_args: For supported `**scope_args` see
:py:meth:`sentry_sdk.Scope.update_from_kwargs`.
"""
client, top_scope = self._stack[-1]
scope = _update_scope(top_scope, scope, scope_args)
if client is not None:
Expand All @@ -348,8 +355,17 @@ def capture_event(self, event, hint=None, scope=None, **scope_args):

def capture_message(self, message, level=None, scope=None, **scope_args):
# type: (str, Optional[str], Optional[Scope], Any) -> Optional[str]
"""Captures a message. The message is just a string. If no level
is provided the default level is `info`.
"""
Captures a message.

:param message: The string to send as the message.

:param level: If no level is provided, the default level is `info`.

:param scope: An optional :py:class:`sentry_sdk.Scope` to use.

:param scope_args: For supported `**scope_args` see
:py:meth:`sentry_sdk.Scope.update_from_kwargs`.

:returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.Client.capture_event`).
"""
Expand All @@ -367,6 +383,9 @@ def capture_exception(self, error=None, scope=None, **scope_args):

:param error: An exception to catch. If `None`, `sys.exc_info()` will be used.

:param scope_args: For supported `**scope_args` see
:py:meth:`sentry_sdk.Scope.update_from_kwargs`.

:returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.Client.capture_event`).
"""
client = self.client
Expand Down Expand Up @@ -397,22 +416,48 @@ def _capture_internal_exception(
"""
logger.error("Internal error in sentry_sdk", exc_info=exc_info)

def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
# type: (Optional[Breadcrumb], Optional[BreadcrumbHint], Any) -> None
def add_breadcrumb(
self,
crumb=None, # type: Optional[Breadcrumb]
hint=None, # type: Optional[BreadcrumbHint]
timestamp=None, # type: Optional[datetime]
type=None, # type: Optional[str]
data=None, # type: Optional[Dict[str, Any]]
**kwargs # type: Any
):
# type: (...) -> None
"""
Adds a breadcrumb.

:param crumb: Dictionary with the data as the sentry v7/v8 protocol expects.
:param crumb: Dictionary with the data as the Sentry v7/v8 protocol expects.

:param hint: An optional value that can be used by `before_breadcrumb`
to customize the breadcrumbs that are emitted.

:param timestamp: The timestamp associated with this breadcrumb. Defaults
to now if not provided.

:param type: The type of the breadcrumb. Will be set to "default" if
not provided.

:param data: Additional custom data to put on the breadcrumb.

:param kwargs: Adding any further keyword arguments will not result in
an error, but the breadcrumb will be dropped before arriving to
Sentry.
"""
client, scope = self._stack[-1]
if client is None:
logger.info("Dropped breadcrumb because no client bound")
return

crumb = dict(crumb or ()) # type: Breadcrumb
if timestamp is not None:
crumb["timestamp"] = timestamp
if type is not None:
crumb["type"] = type
if data is not None:
crumb["data"] = data
crumb.update(kwargs)
if not crumb:
return
Expand Down Expand Up @@ -441,15 +486,19 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
def start_span(self, span=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs):
# type: (Optional[Span], str, Any) -> Span
"""
Create and start timing a new span whose parent is the currently active
span or transaction, if any. The return value is a span instance,
Start a span whose parent is the currently active span or transaction, if any.

The return value is a :py:class:`sentry_sdk.tracing.Span` instance,
typically used as a context manager to start and stop timing in a `with`
block.

Only spans contained in a transaction are sent to Sentry. Most
integrations start a transaction at the appropriate time, for example
for every incoming HTTP request. Use `start_transaction` to start a new
transaction when one is not already in progress.
for every incoming HTTP request. Use
:py:meth:`sentry_sdk.start_transaction` to start a new transaction when
one is not already in progress.

For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Span`.
"""
configuration_instrumenter = self.client and self.client.options["instrumenter"]

Expand Down Expand Up @@ -515,6 +564,8 @@ def start_transaction(

When the transaction is finished, it will be sent to Sentry with all its
finished child spans.

For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Transaction`.
"""
configuration_instrumenter = self.client and self.client.options["instrumenter"]

Expand Down
14 changes: 8 additions & 6 deletions sentry_sdk/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def start_child(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs):

def new_span(self, **kwargs):
# type: (**Any) -> Span
"""Deprecated: use start_child instead."""
"""Deprecated: use :py:meth:`sentry_sdk.tracing.Span.start_child` instead."""
logger.warning("Deprecated: use Span.start_child instead of Span.new_span.")
return self.start_child(**kwargs)

Expand Down Expand Up @@ -330,11 +330,10 @@ def from_traceparent(
):
# type: (...) -> Optional[Transaction]
"""
DEPRECATED: Use Transaction.continue_from_headers(headers, **kwargs)

Create a Transaction with the given params, then add in data pulled from
the given 'sentry-trace' header value before returning the Transaction.
DEPRECATED: Use :py:meth:`sentry_sdk.tracing.Transaction.continue_from_headers`.

Create a `Transaction` with the given params, then add in data pulled from
the given 'sentry-trace' header value before returning the `Transaction`.
"""
logger.warning(
"Deprecated: Use Transaction.continue_from_headers(headers, **kwargs) "
Expand Down Expand Up @@ -826,7 +825,9 @@ def trace(func=None):
Decorator to start a child span under the existing current transaction.
If there is no current transaction, then nothing will be traced.

Usage:
.. code-block::
:caption: Usage

import sentry_sdk

@sentry_sdk.trace
Expand All @@ -836,6 +837,7 @@ def my_function():
@sentry_sdk.trace
async def my_async_function():
...

"""
if PY2:
from sentry_sdk.tracing_utils_py2 import start_child_span_decorator
Expand Down
Loading