Skip to content

Commit

Permalink
Support emmett-core extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
gi0baro committed Oct 13, 2024
1 parent fd96df8 commit e5ab475
Show file tree
Hide file tree
Showing 11 changed files with 392 additions and 309 deletions.
28 changes: 16 additions & 12 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/emmett-sentry
permissions:
id-token: write

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install and configure Poetry
uses: gi0baro/[email protected]
with:
virtualenvs-in-project: true
- name: Publish
python-version: 3.12
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Build distributions
run: |
poetry build
poetry publish
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
uv build
- name: Publish package to pypi
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ __pycache__
*.egg-info/*
build/*
dist/*
poetry.lock
uv.lock
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.DEFAULT_GOAL := all
pysources = emmett_sentry

.PHONY: format
format:
ruff check --fix $(pysources)
ruff format $(pysources)

.PHONY: lint
lint:
ruff check $(pysources)
ruff format --check $(pysources)

.PHONY: all
all: format lint
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Emmett-Sentry is an [Emmett framework](https://emmett.sh) extension integrating [Sentry](https://sentry.io) monitoring platform.

[![pip version](https://img.shields.io/pypi/v/emmett-sentry.svg?style=flat)](https://pypi.python.org/pypi/emmett-sentry)

## Installation

You can install Emmett-Sentry using pip:
Expand Down
2 changes: 1 addition & 1 deletion emmett_sentry/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .ext import Sentry # noqa
from .ext import Sentry
2 changes: 1 addition & 1 deletion emmett_sentry/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.6.1"
__version__ = "0.7.0"
18 changes: 18 additions & 0 deletions emmett_sentry/_imports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
try:
from emmett import current
from emmett.extensions import Extension, Signals, listen_signal

_is_emmett = True
except ImportError:
_is_emmett = False
from emmett55 import current
from emmett_core.datastructures import sdict
from emmett_core.extensions import Extension

Signals = sdict()

def listen_signal(*args, **kwargs):
def wrapper(f):
return f

return wrapper
84 changes: 45 additions & 39 deletions emmett_sentry/ext.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
import sys

from typing import Any, Awaitable, Callable, Dict, Optional, TypeVar

import sentry_sdk

from emmett.extensions import Extension, Signals, listen_signal
from sentry_sdk.hub import Hub

from ._imports import Extension, Signals, _is_emmett, listen_signal
from .helpers import _capture_exception, _capture_message, patch_routers

T = TypeVar('T')

T = TypeVar("T")


class Sentry(Extension):
default_config = dict(
dsn="",
environment="development",
release=None,
auto_load=True,
enable_tracing=False,
sample_rate=1.0,
tracing_sample_rate=None,
tracing_exclude_routes=[],
trace_websockets=False,
trace_orm=True,
trace_templates=True,
trace_sessions=True,
trace_cache=True,
trace_pipes=False,
integrations=[]
)
default_config = {
"dsn": "",
"environment": "development",
"release": None,
"auto_load": True,
"enable_tracing": False,
"sample_rate": 1.0,
"tracing_sample_rate": None,
"tracing_exclude_routes": [],
"trace_websockets": False,
"trace_orm": True,
"trace_templates": True,
"trace_sessions": True,
"trace_cache": True,
"trace_pipes": False,
"integrations": [],
"sdk_opts": {},
}
_initialized = False
_errmsg = "You need to configure Sentry extension before using its methods"

Expand All @@ -39,39 +38,46 @@ def on_load(self):
if not self.config.dsn:
return
self._tracing_excluded_routes = set(self.config.tracing_exclude_routes)
sentry_sdk.init(
dsn=self.config.dsn,
environment=self.config.environment,
release=self.config.release,
sample_rate=self.config.sample_rate,
traces_sample_rate=self.config.tracing_sample_rate,
before_send=self._before_send,
integrations=self.config.integrations
)
sdk_config = {
"dsn": self.config.dsn,
"environment": self.config.environment,
"release": self.config.release,
"sample_rate": self.config.sample_rate,
"traces_sample_rate": self.config.tracing_sample_rate,
"before_send": self._before_send,
"integrations": self.config.integrations,
}
sdk_config = {**sdk_config, **self.config.sdk_opts}
sentry_sdk.init(**sdk_config)
if self.config.auto_load:
patch_routers(self)
self._instrument()
self._initialized = True

def _instrument(self):
if self.config.enable_tracing:
if self.config.trace_templates:
if self.config.trace_templates and _is_emmett:
from .instrument import instrument_templater

instrument_templater(self.app)
if self.config.trace_sessions:
from .instrument import instrument_sessions

instrument_sessions()
if self.config.trace_cache:
from .instrument import instrument_cache

instrument_cache()
if self.config.trace_pipes:
from .instrument import instrument_pipes

instrument_pipes()

@listen_signal(Signals.after_database)
def _signal_db(self, database):
if self.config.enable_tracing and self.config.trace_orm:
if self.config.enable_tracing and self.config.trace_orm and _is_emmett:
from .instrument import instrument_orm

instrument_orm(database)

def _before_send(self, event, hint):
Expand All @@ -98,14 +104,14 @@ def before_send(self, f: T) -> T:


def capture_exception(exception, **contexts):
with Hub(Hub.current) as hub:
with sentry_sdk.get_current_scope() as scope:
for key, val in contexts.items():
hub.scope.set_context(key, val)
_capture_exception(hub, exception)
scope.set_context(key, val)
_capture_exception(exception)


def capture_message(message, level, **contexts):
with Hub(Hub.current) as hub:
with sentry_sdk.get_current_scope() as scope:
for key, val in contexts.items():
hub.scope.set_context(key, val)
_capture_message(hub, message, level=level)
scope.set_context(key, val)
_capture_message(message, level=level)
Loading

0 comments on commit e5ab475

Please sign in to comment.