diff --git a/sentry_sdk/__init__.py b/sentry_sdk/__init__.py index 9fd7253fc2..e03f3b4484 100644 --- a/sentry_sdk/__init__.py +++ b/sentry_sdk/__init__.py @@ -47,6 +47,8 @@ "trace", "monitor", "logger", + "start_session", + "end_session", ] # Initialize the debug support after everything is loaded diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index e56109cbd0..698a2085ab 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -82,6 +82,8 @@ def overload(x): "start_transaction", "trace", "monitor", + "start_session", + "end_session", ] @@ -450,3 +452,17 @@ def continue_trace( return get_isolation_scope().continue_trace( environ_or_headers, op, name, source, origin ) + + +@scopemethod +def start_session( + session_mode="application", # type: str +): + # type: (...) -> None + return get_isolation_scope().start_session(session_mode=session_mode) + + +@scopemethod +def end_session(): + # type: () -> None + return get_isolation_scope().end_session() diff --git a/tests/test_api_sessions.py b/tests/test_api_sessions.py new file mode 100644 index 0000000000..4770da0acd --- /dev/null +++ b/tests/test_api_sessions.py @@ -0,0 +1,50 @@ +import sentry_sdk + + +def test_start_session_basic(sentry_init, capture_envelopes): + """Test that start_session starts a session on the isolation scope.""" + sentry_init(release="test-release", environment="test-env") + envelopes = capture_envelopes() + + # Start a session using the top-level API + sentry_sdk.start_session() + + # End the session + sentry_sdk.end_session() + sentry_sdk.flush() + + # Check that we got a session envelope + assert len(envelopes) == 1 + sess = envelopes[0] + assert len(sess.items) == 1 + sess_event = sess.items[0].payload.json + + assert sess_event["attrs"] == { + "release": "test-release", + "environment": "test-env", + } + assert sess_event["status"] == "exited" + + +def test_start_session_with_mode(sentry_init, capture_envelopes): + """Test that start_session accepts session_mode parameter.""" + sentry_init(release="test-release", environment="test-env") + envelopes = capture_envelopes() + + # Start a session with request mode + sentry_sdk.start_session(session_mode="request") + sentry_sdk.end_session() + sentry_sdk.flush() + + # Request mode sessions are aggregated + assert len(envelopes) == 1 + sess = envelopes[0] + assert len(sess.items) == 1 + sess_event = sess.items[0].payload.json + + assert sess_event["attrs"] == { + "release": "test-release", + "environment": "test-env", + } + # Request sessions show up as aggregates + assert "aggregates" in sess_event