Skip to content

Commit

Permalink
Allow (some) autocompletion for top-level API (#2213)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivana Kellyerova committed Jul 4, 2023
1 parent 8051d92 commit 7719950
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 79 deletions.
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
from sentry_sdk.tracing import Span

T = TypeVar("T")
Expand Down Expand Up @@ -77,46 +70,36 @@ def scopemethod(f):
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)

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 @@ def last_event_id():
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

0 comments on commit 7719950

Please sign in to comment.