Repository navigation
Reconcile M3 with upstream and add payment-intent hooks - #7
mikezupper wants to merge 8 commits into
Conversation
Accept dicts, text, bytes, binary files, and async byte streams with
an optional content type. Send omitted and None payloads as empty
bodies.
Add StreamPayload(source=...) for streaming data sources. To accommodate
402 (payment) and other error response codes without consuming the payload,
the client sends an `Expect: 100-continue` and waits for the 100 before
transmitting the body. This is something that most HTTP servers do by
default already, including golang's. Bounded (non-streaming) inputs do
not wait for the 100.
In the case that there is still an error after payment, streaming input
is buffered for replay during runner failover (optional, but enabled by
default). Seekable files are rewound instead of buffered.
This is API-compatible with existing callers, with a few tweaks:
* `None` payloads now don't send a body, instead of `{}`
* `stream=True` (response streaming) now honors `timeout` instead of
using a fixed 10s
Also remove an unused `Label` field from runner registration.
Support sync and async on_payment_session callbacks in call_runner and expose LivePaymentSession.manifest_id for payment attribution. Invoke the callback for each new session. Validate segCreds when parsing signer responses and remove redundant caller checks. Cover callback ordering, failures, and cancellation.
Store token from `reserved` events and make them available to session events. Add LiveRunnerRegistration.stop_session() so apps can stop sessions before receiving application traffic.
Updates `aiohttp` from 3.13.3 to 3.14.4 Updates `idna` from 3.11 to 3.15
There was a problem hiding this comment.
The new hooks match the added tests. on_payment_attempt is awaited before the first signing request of a new session, and a failure there does not sign. on_payment_error receives the original signing or validation exception, including a blank segCreds, and a failure there aborts a challenge refresh. Cancelling while the signer wait is in progress does not call the error hook.
Requesting changes because the merge drops the releases/m3 rule that a blank segment still keeps the signer's new cursor. Metered renewals then resubmit the previous cursor, and these hooks never see that attempt.
Sent by Cursor Automation: build-track code reviews
|
There was a problem hiding this comment.
The blank-segment cursor gap from the last review is fixed. _payment_request stores a dict state and then raises PaymentError when segCreds is missing or "", so send_payment never POSTs that segment. A later get_payment or send_payment on the same session sends the new cursor. A non-string segCreds, a missing state, and a non-string payment still fail without replacing _state.
The payment-intent hooks are unchanged and match their tests: on_payment_attempt runs before the first sign and a failure there does not sign; on_payment_error receives the original exception and can abort a challenge refresh; cancellation during the signer wait does not call the error hook. Those hooks still wrap only the upfront get_payment. A metered renewal that gets a blank segment keeps the new cursor, logs the PaymentError, and retries on the next cycle.
tests/test_live_payment_session.py and TestPaymentSessionCallback passed (40).
Sent by Cursor Automation: build-track code reviews
|
I noticed your PR is based on https://github.com/NE-Build-Track/livepeer-python-gateway/tree/releases/m3 The current state of upstream for livepeer-python-gateway is following main branch. The commits previously made to releases/m3 can be dropped and synced with upstream. This is likely the root cause of testing errors. The current livepeer-gateway pin in livepeer-builder-core is livepeer@76a1a1c. See https://github.com/NE-Build-Track/livepeer-builder-core/blob/dec3e4b160bfc660b1040c39798ff9070afbddee/pyproject.toml#L25 |
|
Superseded by NE-Build-Track/livepeer-builder-core#61. That PR now includes NE-Build-Track/livepeer-builder-core#62 (decision D53), which was merged into its branch. builder-core no longer needs SDK hooks to record payment intent. It now owns the paid runner call (
A lost or malformed reply, a signer 5xx, or a cancellation leaves the manifest Reference: NE-Build-Track/livepeer-builder-core#56, rebased onto that work, is on https://github.com/NE-Build-Track/livepeer-builder-core/tree/rebase/payment-intent-on-62. On that branch:
It passes 1141 tests (27 PostgreSQL cases skipped locally). Not covered by builder-core: this PR's last commit, I'm leaving this PR open for you to close. |
|
Closed. Builder-core no longer needs this change in the SDK. Each part of it now lives in builder-core, which pins upstream livepeer-python-gateway
|





A signer can charge before its response is lost, cancelled or rejected by validation. Recording payment only in the success callback leaves consumers unable to attribute that charge or safely decide whether to fail over.
This brings
releases/m3up to the publishedreleases/finalbaseline (2017a80) and adds optional hooks for durable intent:on_payment_attempt(session)before the first signing request of each new session. A hook failure prevents signing.on_payment_error(session, error)for signing or validation exceptions before a challenge-refresh retry. Consumers receive the original exception and manifest ID.The old fork's early callback and cancellation drain are deliberately superseded. Builder-core's companion change records unknown intent before signing, prevents failover on an ambiguous outcome, and reconciles it against unique allocation/manifest usage evidence. These hooks provide the SDK boundary; persistence and the paid/unpaid/unknown policy belong to the consumer.
The history merge preserves the M3 ancestry and makes this PR directly mergeable. The implementation combines upstream
2017a80, the intent/error hooks and preservation of the signer cursor when blank segment credentials are rejected.Validation: 343 tests passed; Ruff passed; wheel and source distribution built. Companion builder-core validation passed 975 tests with SQLite and PostgreSQL, including lost replies, malformed responses, cancellation, failed intent writes, restart recovery and later usage reconciliation.