-
Notifications
You must be signed in to change notification settings - Fork 96
Add append operation for efficient text streaming #171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Add new `append` operation as an optional extension to RFC 6902 - Introduce `use_append_ops` parameter to enable/disable append operations - Support automatic detection of string append scenarios in make_patch() - Maintain full backward compatibility with RFC 6902 by default - Enable optimized notation for consecutive append operations in streaming The append operation is disabled by default to maintain RFC 6902 compliance. Users can opt-in by setting use_append_ops=True in apply_patch(), make_patch(), and JsonPatch methods. This feature is particularly useful for chat applications and streaming scenarios where text is appended incrementally, reducing payload size by ~2.8x compared to replace operations.
@stefankoegl This PR is resubmitted with the append operation made optional for RFC 6902 compliance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new append
operation to python-json-patch specifically optimized for text streaming in chat applications. When streaming text character-by-character or word-by-word, this reduces payload size by only sending incremental text instead of the entire string with each update.
Key changes include:
- New
AppendOperation
class for string concatenation - Optional RFC 6902 extension controlled via
use_append_ops
parameter - Smart patch generation that automatically detects append scenarios when enabled
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
else: | ||
self._item_replaced(path, key, dst) | ||
# Check if this is a string append operation (only if append ops are enabled) | ||
if self.use_append_ops and isinstance(src, basestring) and isinstance(dst, basestring) and dst.startswith( | ||
src): | ||
appended_text = dst[len(src):] | ||
if appended_text: # Only create append op if there's actual text to append | ||
self.insert(AppendOperation({ | ||
'op': 'append', | ||
'path': _path_join(path, key), | ||
'value': appended_text, | ||
}, pointer_cls=self.pointer_cls)) | ||
else: | ||
self._item_replaced(path, key, dst) | ||
else: | ||
self._item_replaced(path, key, dst) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic flow is incorrect - there's an unnecessary else:
block at line 1018 that creates unreachable code. The else:
clause at line 1031 will never execute because it's nested inside the outer else:
block, making the string append detection logic unreachable in most cases.
Copilot uses AI. Check for mistakes.
raise JsonPatchConflict("Cannot append to root document") | ||
|
||
try: | ||
if isinstance(subobj[part], basestring): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The append operation should validate that the 'value' parameter is a string before attempting concatenation. Currently, if 'value' is not a string, the +=
operation could succeed but produce unexpected results (e.g., concatenating a list to a string).
if isinstance(subobj[part], basestring): | |
if isinstance(subobj[part], basestring): | |
if not isinstance(self.operation['value'], basestring): | |
raise JsonPatchConflict("Cannot append non-string value to string") |
Copilot uses AI. Check for mistakes.
Summary
This PR adds a new append operation to python-json-patch for efficient text streaming in chat applications. When
streaming text character-by-character or word-by-word, the standard replace operation requires sending the entire string
with each update. The new append operation only sends the incremental text, significantly reducing payload size and
improving performance.
This method is used by official ChatGPT and is an implementation optimized for chat.
Key Features
Implementation Details
AppendOperation class: New operation type that appends text to strings at specified JSON paths
{"op": "append", "path": "/message/content", "value": "Hello"}
Optional activation: The append operation is disabled by default for RFC 6902 compliance
API Changes
All functions now accept an optional use_append_ops parameter:
Performance
The demo script shows append operations are ~2.8x faster than replace operations for streaming scenarios.
Backward Compatibility