async def sentry_patched_asgi_handler(self, receive, send): # type: (Any, Any, Any) -> Any if Hub.current.get_integration(DjangoIntegration) is None: return await old_app(self, receive, send) middleware = SentryAsgiMiddleware( lambda _scope: old_app.__get__(self, cls), unsafe_context_data=True) return await middleware(self.scope)(receive, send)
def create_app(): app = FastAPI( title=config.APP_NAME, version=config.APP_VERSION or "0.1.0", debug=config.APP_DEBUG, ) app.include_router(api.router, prefix="/api") sentry_sdk.init(dsn=config.SENTRY_DSN) return SentryAsgiMiddleware(app)
def test_websocket(sentry_init, capture_events, request): sentry_init(debug=True, send_default_pii=True) # Bind client to main thread because context propagation for the websocket # client does not work. Hub.main.bind_client(Hub.current.client) request.addfinalizer(lambda: Hub.main.bind_client(None)) events = capture_events() from starlette.testclient import TestClient def message(): capture_message("hi") raise ValueError("oh no") async def app(scope, receive, send): assert scope["type"] == "websocket" websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.send_text(message()) await websocket.close() app = SentryAsgiMiddleware(app) client = TestClient(app) with client.websocket_connect("/") as websocket: with pytest.raises(ValueError): websocket.receive_text() msg_event, error_event = events assert msg_event["message"] == "hi" (exc, ) = error_event["exception"]["values"] assert exc["type"] == "ValueError" assert exc["value"] == "oh no" assert (msg_event["request"] == error_event["request"] == { "env": { "REMOTE_ADDR": "testclient" }, "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "upgrade", "host": "testserver", "sec-websocket-key": "testserver==", "sec-websocket-version": "13", "user-agent": "testclient", }, "method": None, "query_string": None, "url": "ws://testserver/", })
def get_application(config) -> Union[FastAPI, SentryAsgiMiddleware]: application = FastAPI( title=config.PROJECT_NAME, debug=config.DEBUG, version=config.VERSION ) application.exception_handler(StarletteHTTPException)(error_fallback_action) application.include_router(router, prefix=config.API_PREFIX) # Quick root route application.get("/")(lambda: RedirectResponse(config.API_PREFIX)) if config.ENVIRONMENT == Environments.DEV: return application init_middlewares(application) return SentryAsgiMiddleware(application)
def get_app() -> FastAPI: """ Fastapi App instance. """ fast_app = FastAPI(title=APP_NAME, version=APP_VERSION, debug=DEBUG) for router in ROUTERS: fast_app.include_router(router, prefix=API_PREFIX) if SENTRY_ENABLED and SENTRY_DSN not in ("None", ""): import sentry_sdk from sentry_sdk.integrations.asgi import SentryAsgiMiddleware sentry_sdk.init(dsn=str(SENTRY_DSN)) fast_app = MiddlewareWrapper(SentryAsgiMiddleware(fast_app)) return fast_app
def create_app() -> FastAPI: app = FastAPI(title=TITLE, dependencies=[Depends(content_type.check)]) app.router.route_class = ValidationErrorLoggingRoute app.add_middleware( CORSMiddleware, allow_origins=ALLOWED_HOSTS or ["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.add_middleware(DBSessionMiddleware, db_url=DB.to_string()) app = include_api_routes(app) sentry_sdk.init(dsn=SENTRY_DSN) SentryAsgiMiddleware(app) return app
def run_server( host='0.0.0.0', port=8000, workers=None, #pylint:disable=R0913 reload=False, log_level='error', loop='uvloop', enable_sentry=False): global app #pylint:disable=W0603,C0103 if enable_sentry: sentry_sdk.init(dsn=core.setting.SENTRY_DSN, integrations=[SqlalchemyIntegration()]) app = SentryAsgiMiddleware(app).app uvicorn.run('app.__main__:app', host=host, port=port, reload=reload, \ workers=workers, log_level=log_level, loop=loop)
def get_app(*, master: bool, sentry: bool = True) -> ASGIFramework: asgi_app = Starlette( debug=True, routes=([ Route("/github-webhook", github_webhook, methods=["POST"]), Route("/tarball-ready", tarball_ready, methods=["POST"]), Route("/status", status, methods=["GET"]), Route("/error", error, methods=["GET"]), ] if master else [ Route("/prepare-host", prepare_host, methods=["PUT"]), Route("/deploy-host", deploy_host, methods=["PUT"]), Route("/status", status, methods=["GET"]), ]), ) if sentry and not settings.SENTRY_DSN: raise RuntimeError( "Cannot enable Sentry integration without SACAR_SENTRY_DSN being set" ) return SentryAsgiMiddleware(asgi_app) if sentry else asgi_app
def test_starlette_last_event_id(app, sentry_init, capture_events, request): sentry_init(send_default_pii=True) events = capture_events() @app.route("/handlederror") def handlederror(request): raise ValueError("oh no") @app.exception_handler(500) def handler(*args, **kwargs): return PlainTextResponse(last_event_id(), status_code=500) client = TestClient(SentryAsgiMiddleware(app), raise_server_exceptions=False) response = client.get("/handlederror") assert response.status_code == 500 (event, ) = events assert response.content.strip().decode("ascii") == event["event_id"] (exception, ) = event["exception"]["values"] assert exception["type"] == "ValueError" assert exception["value"] == "oh no"
def test_auto_session_tracking_with_aggregates(app, sentry_init, capture_envelopes): """ Test for correct session aggregates in auto session tracking. """ @app.route("/dogs/are/great/") @app.route("/trigger/an/error/") def great_dogs_handler(request): if request["path"] != "/dogs/are/great/": 1 / 0 return PlainTextResponse("dogs are great") sentry_init(traces_sample_rate=1.0) envelopes = capture_envelopes() app = SentryAsgiMiddleware(app) client = TestClient(app, raise_server_exceptions=False) client.get("/dogs/are/great/") client.get("/dogs/are/great/") client.get("/trigger/an/error/") sentry_sdk.flush() count_item_types = Counter() for envelope in envelopes: count_item_types[envelope.items[0].type] += 1 assert count_item_types["transaction"] == 3 assert count_item_types["event"] == 1 assert count_item_types["sessions"] == 1 assert len(envelopes) == 5 session_aggregates = envelopes[-1].items[0].payload.json["aggregates"] assert session_aggregates[0]["exited"] == 2 assert session_aggregates[0]["crashed"] == 1 assert len(session_aggregates) == 1
from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.urls import path from django_keycloak_auth.middleware import OIDCChannelsMiddleware from sentry_sdk.integrations.asgi import SentryAsgiMiddleware import customer_chat.consumers import operator_interface.consumers application = SentryAsgiMiddleware( ProtocolTypeRouter({ "websocket": AuthMiddlewareStack( OIDCChannelsMiddleware( URLRouter([ path( "ws/operator/", operator_interface.consumers.OperatorConsumer.as_asgi( )), path("ws/chat/", customer_chat.consumers.ChatConsumer.as_asgi()), ]))) }))
import os from django.conf import settings from django.core.asgi import get_asgi_application from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from .routing import router os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') websocket_application = AuthMiddlewareStack(router) if settings.FEATURE_SENTRY: websocket_application = SentryAsgiMiddleware(websocket_application) application = ProtocolTypeRouter({ 'http': get_asgi_application(), 'websocket': websocket_application, })
return await self.send(message) def _get_ip(self) -> str: client = self.scope.get("client", ("", 0)) if not client: if b"x-forwarded-for" in self.headers: return self.headers[b"x-forwarded-for"].decode() return "" return client[0] def log(self, runtime: float): """Outpot access logs in a structured format""" client = self._get_ip() query_string = "" if self.scope.get("query_string", b"") != b"": query_string = f"?{self.scope.get('query_string').decode()}" LOGGER.info( f"{self.scope.get('path', '')}{query_string}", client=client, method=self.scope.get("method", ""), scheme=self.scope.get("scheme", ""), status=self.status_code, size=self.content_length / 1000 if self.content_length > 0 else "-", runtime=runtime, ) application = SentryAsgiMiddleware(ASGILoggerMiddleware( get_asgi_application()))
import os import django from channels.routing import get_default_application from sentry_sdk.integrations.asgi import SentryAsgiMiddleware os.environ.setdefault("DJANGO_SETTINGS_MODULE", "buses.settings") django.setup() application = get_default_application() application = SentryAsgiMiddleware(application)
**Arguments:** - **job_id**: Identifier of the submitted job, as returned by the "Submit Job" endpoint. """ loop = asyncio.get_running_loop() try: job_state, job_result = await loop.run_in_executor(None, gitlab.get_job_state, job_id, True) except gitlab.GitlabHttpError: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) return job_result @app.get("/_ah/warmup", include_in_schema=False) def warmup(): return {} @app.on_event("startup") async def on_startup() -> None: app_data["task_monitor"] = asyncio.create_task(start_and_monitor_tasks(), name="task_monitor") @app.on_event("shutdown") async def on_shutdown() -> None: app_data["task_monitor"].cancel() if config.SENTRY_DSN: sentry_sdk.init(config.SENTRY_DSN, traces_sample_rate=1.0) app = SentryAsgiMiddleware(app) # typing: ignore
content={"message": "The specified email is already registered"}, ) # @app.exception_handler(ValidationError) # async def unicorn_exception_handler(request: Request, exc: ValidationError): # return JSONResponse( # status_code=422, # content={"message": f"Validation error"}, # ) # Set all CORS enabled origins if settings.BACKEND_CORS_ORIGINS: app.add_middleware( CORSMiddleware, allow_origins=[ str(origin) for origin in settings.BACKEND_CORS_ORIGINS ], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(api_router, prefix=settings.API_V1_STR) simplify_operation_ids(app) if "pytest" not in sys.modules and False: sentry_sdk.init(dsn=settings.SENTRY_DSN, traces_sample_rate=0.2) app = cast(FastAPI, SentryAsgiMiddleware(app))
""" ASGI entrypoint. Configures Django and then runs the application defined in the ASGI_APPLICATION setting. """ import os import django from channels.routing import get_default_application from sentry_sdk.integrations.asgi import SentryAsgiMiddleware os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") django.setup() SENTRY_DSN = os.environ.get("SENTRY_DSN") if SENTRY_DSN: # pragma: nocover application = SentryAsgiMiddleware(get_default_application()) else: application = get_default_application()
) @app.on_event("startup") async def startup(): if not database.is_connected: await database.connect() @app.on_event("shutdown") async def shutdown(): if database.is_connected: await database.disconnect() wrapped_app = SentryAsgiMiddleware(app) async def event_handler(event): try: await startup() await run_handler("crons", event["name"], event["payload"]) finally: await shutdown() def handler(event, context): if command := event.get("_cli_command"): # noqa native_stdout = sys.stdout native_stderr = sys.stderr output_buffer = StringIO()
# -*- encoding: utf-8 -*- # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from mergify_engine import config from mergify_engine import logs from mergify_engine.web import app as application if config.SENTRY_URL: application = SentryAsgiMiddleware(application) # type:ignore[assignment] logs.setup_logging()
def wrap_with_class(app): if dsn is None: return app else: return SentryAsgiMiddleware(app)
f"{keycloak_url}auth/realms/{realm}/protocol/openid-connect/auth", f"{keycloak_url}auth/realms/{realm}/protocol/openid-connect/token", ) application.add_event_handler( "startup", app_event_handler.start_app_handler(application, settings) ) application.add_event_handler( "shutdown", app_event_handler.stop_app_handler(application) ) application.include_router(get_router(settings)) application.middleware("http")(request_context.add_log_context) application.exception_handler(HTTPException)( exception_handlers.http_exception_handler ) application.exception_handler(RequestValidationError)( exception_handlers.validation_exception_handler ) sentry_sdk.init( dsn=settings.sentry_dsn, sample_rate=settings.sentry_traces_sample_rate, release=settings.app_version, ) return application app = SentryAsgiMiddleware(get_application())
from fastapi import FastAPI from fastapi.responses import ORJSONResponse from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from tortoise.contrib.fastapi import register_tortoise from app.controllers import tag from app.core import config app = FastAPI( title="Galaxy", servers=[ { "url": "http://localhost:8000", "description": "Developing environment" }, ], default_response_class=ORJSONResponse, ) app.include_router(tag.router, tags=["tag"]) logging.root.setLevel("INFO") if sys.argv[0] != "pytest": # pragma: no cover register_tortoise( app, config=config.db_config, add_exception_handlers=True, ) sentry_sdk.init(dsn=config.settings.sentry_dsn) app = SentryAsgiMiddleware(app)
await send({"type": "lifespan.shutdown.complete"}) return class RouteNotFoundMiddleware: """Middleware to ignore 404s for websocket requests taken from https://github.com/django/daphne/issues/165#issuecomment-808284950""" def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): try: return await self.app(scope, receive, send) except ValueError as exc: if "No route found for path" in str( exc) and scope["type"] == "websocket": await send({"type": "websocket.close"}) else: raise exc application = SentryAsgiMiddleware( ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": RouteNotFoundMiddleware(URLRouter(websocket.websocket_urlpatterns)), "lifespan": LifespanApp, }))
import os import sentry_sdk import uvicorn from fastapi import FastAPI from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from api.router import timetable from updater.db import check_for_updates sentry_sdk.init(dsn=os.environ["SENTRY_URL"]) gbu_agenda = FastAPI() gbu_agenda.include_router(timetable) SentryAsgiMiddleware(gbu_agenda) if __name__ == "__main__": check_for_updates() uvicorn.run("main:gbu_agenda", port=int(os.getenv("PORT", 5000)), host="0.0.0.0", reload=True)
# Check if header has multiple values, and use the first one return client_ip.split(", ")[0] def log(self, scope: Scope, content_length: int, runtime: float, **kwargs): """Outpot access logs in a structured format""" host = self._get_ip(scope) query_string = "" if scope.get("query_string", b"") != b"": query_string = f"?{scope.get('query_string').decode()}" LOGGER.info( f"{scope.get('path', '')}{query_string}", host=host, method=scope.get("method", ""), scheme=scope.get("scheme", ""), status=self.status_code, size=content_length / 1000 if content_length > 0 else 0, runtime=runtime, **kwargs, ) application = ASGILogger( guarantee_single_callable( SentryAsgiMiddleware( ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": URLRouter(websocket.websocket_urlpatterns), }))))