Add WebhookSignature.generate_test_header_string helper#1810
Conversation
Exposes a public utility for generating signed Stripe-Signature header values for use in tests, mirroring stripe-node's generateTestHeaderString. Closes the need to depend on the underscore-prefixed _compute_signature internal when writing tests against webhook handling code. Fixes stripe#1697
| signature: Optional[str] = None, | ||
| ) -> str: | ||
| """ | ||
| Generates a value for the `Stripe-Signature` header that can be used |
There was a problem hiding this comment.
The docstring uses a mix of markdown and RST syntax. I would suggest sticking to markdown to be consistent with the rest of the code base. You can specify parameters as:
Args:
payload: ...
secret: ...
There was a problem hiding this comment.
switched to a markdown Args: block. Thanks for the catch!
Switch generate_test_header_string's docstring from mixed markdown/RST (`:param:`) to a markdown `Args:` block, addressing @Viicos's review comment on stripe#1810.
| return mac.hexdigest() | ||
|
|
||
| @classmethod | ||
| def generate_test_header_string( |
There was a problem hiding this comment.
Question: Did you consider Webhook.generate_test_header_string? stripe-node puts the helper on the primary webhooks object. I'm curious why you chose WebhookSignature instead of Webhook
There was a problem hiding this comment.
You're right that Webhook is the better home. My original reasoning was internal cohesion (co-locating with _compute_signature and verify_header), but that's outweighed by:
- Cross-SDK consistency. stripe-node, stripe-go, and stripe-ruby all put their test header helper on the primary webhooks object, so a user hopping between SDKs knows where to look.
- Discovery via use case. The helper exists to feed
Webhook.construct_eventin tests; sitting next to it is a stronger signal than sitting next to the primitive it wraps. - Public-surface symmetry.
Webhookis the user-facing entry point;WebhookSignatureis closer to plumbing. A testing helper belongs on the surface being tested.
Moved it to Webhook.generate_test_header_string, with the implementation still delegating to WebhookSignature._compute_signature internally. Tests updated accordingly. Thanks for pushing back on this.
Per @mbroshi-stripe's review on stripe#1810, place the helper next to Webhook.construct_event (the thing it pairs with in test code) and match the placement used by stripe-node, stripe-go, and stripe-ruby. The implementation continues to delegate to WebhookSignature for the underlying signing primitive.
Summary
Adds a public
WebhookSignature.generate_test_header_string()helper that mirrors stripe-node'sgenerateTestHeaderString(), so users can sign test payloads without reaching for the underscore-prefixed_compute_signatureinternal.Fixes #1697.
Implementation notes
WebhookSignature(next toEXPECTED_SCHEME,_compute_signature, andverify_header), accessed asstripe.WebhookSignature.generate_test_header_string(...).Optionalkeyword arguments are used instead of the Node SDK's options object, matching Python conventions while preserving the full Node parameter surface (payload,secret,timestamp,scheme,signature).timestamp→int(time.time()),scheme→EXPECTED_SCHEME,signature→ computed frompayload+secret. Passingsignatureexplicitly inserts it verbatim, mirroring Node.generate_headerhelper intests/test_webhook.pywas refactored to delegate to the new public method. This proves the new API covers every existing test scenario and removes the duplicated signing logic from tests.TestGenerateTestHeaderStringclass covers: defaults, round-trip throughverify_header, custom timestamp/scheme, signature pass-through, and bad-secret failure.Example usage
Test plan
just test— 4245 passed, 6 skippedjust lint— cleanjust format-check— cleanjust typecheck— only pre-existing error instripe/_http_client.py:681(present onmaster, unrelated to this change)