Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: Allow suppressing Stripe notices
pr_url: https://github.com/stripe/stripe-python/pull/1909
semver_level: minor
---

Set the `STRIPE_SUPPRESS_NOTICES` environment variable to `true` to suppress Stripe notices in test and sandbox environments when not running under a detected AI agent. Notices remain enabled by default and continue to be shown to AI agents.
27 changes: 23 additions & 4 deletions stripe/_api_requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,31 @@
_default_proxy: Optional[str] = None


def _maybe_emit_stripe_notice(rheaders: Mapping[str, str]) -> None:
def _maybe_emit_stripe_notice(
rheaders: Mapping[str, str],
environ: Optional[Mapping[str, str]] = None,
) -> None:
notice = rheaders.get("Stripe-Notice")
if notice:
import warnings
if not notice:
return

environ = os.environ if environ is None else environ
ai_agent = _APIRequestor._detect_ai_agent(environ)
if (
not ai_agent
and environ.get("STRIPE_SUPPRESS_NOTICES", "").lower() == "true"
):
return

if not ai_agent:
notice += (
"\nTo suppress Stripe notices in test and sandbox environments, "
"set the STRIPE_SUPPRESS_NOTICES environment variable to true."
)

import warnings

warnings.warn(notice)
warnings.warn(notice)


def is_v2_delete_resp(method: str, api_mode: ApiMode) -> bool:
Expand Down
55 changes: 54 additions & 1 deletion tests/test_api_requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

import stripe
import io
from stripe._api_requestor import _api_encode, _APIRequestor
from stripe._api_requestor import (
_api_encode,
_APIRequestor,
_maybe_emit_stripe_notice,
)
from stripe._customer import Customer
from stripe._request_options import RequestOptions
from stripe._requestor_options import (
Expand Down Expand Up @@ -1077,6 +1081,55 @@ def test_stripe_notice_header_emits_warning(
with pytest.warns(UserWarning, match="test notice value"):
requestor.request("get", self.v1_path, {}, base_address="api")

def test_stripe_notice_tells_humans_how_to_suppress_notices(self):
with pytest.warns(UserWarning) as warning:
_maybe_emit_stripe_notice(
{"Stripe-Notice": "test notice value"}, {}
)

assert str(warning[0].message) == (
"test notice value\n"
"To suppress Stripe notices in test and sandbox environments, "
"set the STRIPE_SUPPRESS_NOTICES environment variable to true."
)

@pytest.mark.parametrize("suppression_value", ["true", "TRUE"])
def test_stripe_notice_can_be_suppressed_for_humans(
self, suppression_value
):
import warnings

with warnings.catch_warnings():
warnings.simplefilter("error")
_maybe_emit_stripe_notice(
{"Stripe-Notice": "test notice value"},
{"STRIPE_SUPPRESS_NOTICES": suppression_value},
)

@pytest.mark.parametrize(
"suppression_value", ["", "false", "1", "invalid"]
)
def test_stripe_notice_is_not_suppressed_for_other_values(
self, suppression_value
):
with pytest.warns(UserWarning):
_maybe_emit_stripe_notice(
{"Stripe-Notice": "test notice value"},
{"STRIPE_SUPPRESS_NOTICES": suppression_value},
)

def test_stripe_notice_is_not_suppressed_for_ai_agents(self):
with pytest.warns(UserWarning) as warning:
_maybe_emit_stripe_notice(
{"Stripe-Notice": "test notice value"},
{
"STRIPE_SUPPRESS_NOTICES": "true",
"CODEX_SANDBOX": "1",
},
)

assert str(warning[0].message) == "test notice value"

@pytest.mark.anyio
async def test_stripe_notice_header_emits_warning_async(
self, requestor, http_client_mock
Expand Down