Preserve bound args for upload handlers#6602
Conversation
Greptile SummaryThis PR fixes issue #5290 by threading extra bound handler arguments all the way through the upload pipeline — from the Python compile-time EventSpec, through the JavaScript uploadFiles client, and into the backend event dispatch for both buffered and streaming upload paths.
Confidence Score: 5/5Safe to merge; the fix is complete end-to-end with both unit and integration test coverage. The Python compile-time path, the JS client, and both backend upload paths are all updated consistently. The previously flagged gaps are fully addressed. No regressions in the normal no-extra-args path. No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "fix: carry upload bound args as a form f..." | Re-trigger Greptile |
22f9b26 to
9da7528
Compare
Merging this PR will not alter performance
Comparing Footnotes
|
Args bound to an upload handler (e.g. State.on_drop(rx.upload_files(...), field)) were preserved in the compiled event spec but never reached the backend handler, since uploads travel over a REST endpoint instead of the socket. The client now forwards the named extra args via a URL-encoded JSON header, which the upload endpoint decodes and merges into the event payload. Bound names that clash with reserved upload keys are rejected at build time. Fixes reflex-dev#5290.
…etdixit200/reflex into fix/upload-bound-event-args
|
The runtime upload path is covered on the current head now: the compiled event carries Focused verification: |
|
@greptile please rereview. |
Validate the reflex-event-args header before parsing form data so a malformed or non-object JSON payload yields a 400 instead of a 500.
… them Bound handler args were sent in a URL-encoded HTTP header, which the streaming chunk parser never read, so chunked uploads dropped them and the header path was capped by server limits. Move the args into a leading __reflex_event_args multipart field parsed ahead of the first file chunk, dispatching the handler once it is read. The field is size-bounded and rejected if it arrives after a file part.
|
@greptile please rereview. |
All Submissions:
Type of change
Changes To Core Features:
Description
Fixes #5290.
EventHandler.__call__returned immediately when it sawrx.upload_files(...)orrx.upload_files_chunk(...), so any other bound arguments supplied to the same event handler were dropped. This keeps the upload client-handler spec, but appends normal bound handler arguments to the resultingEventSpecsoon_drop=State.handle_upload(rx.upload_files(...), field)preservesfield.AI-assisted: OpenAI Codex, with local review and verification.
Testing
uv run pytest tests/units/components/core/test_upload.py::test_upload_files_preserves_bound_event_args -qfailed becausefieldwas missing from the upload event args.uv run pytest tests/units/components/core/test_upload.py -quv run pytest tests/units/test_event.py -quv run pytest tests/units/test_app.py -q -k 'upload and not compile_writes_upload_files_provider_app_wrap'uv run ruff check packages/reflex-base/src/reflex_base/event/__init__.py tests/units/components/core/test_upload.pyuv run pyright packages/reflex-base/src/reflex_base/event/__init__.py tests/units/components/core/test_upload.py(0 errors, 1 existing warning inevent/__init__.py)git diff --checkNote:
uv run pytest tests/units/test_app.py -q -k uploadcurrently fails in unrelatedtest_compile_writes_upload_files_provider_app_wrapwithAttributeError: 'DynamicState' object has no attribute 'dynamic'; the remaining 18 upload-selected app tests pass with that case excluded.