Skip to content

feat: Adding new operations to the Data Operations component#9297

Closed
Empreiteiro wants to merge 0 commit into
langflow-ai:mainfrom
Empreiteiro:main
Closed

feat: Adding new operations to the Data Operations component#9297
Empreiteiro wants to merge 0 commit into
langflow-ai:mainfrom
Empreiteiro:main

Conversation

@Empreiteiro
Copy link
Copy Markdown
Collaborator

@Empreiteiro Empreiteiro commented Aug 4, 2025

This PR enhances the DataOperationsComponent by introducing two new powerful operations:

JSON Path: Allows extracting values from nested JSON structures using path expressions, enabling more flexible data selection.

JSON Query: Integrates jq to support advanced JSON queries, including filters, projections, and transformations.

Additional improvements:

Input handling and validations for both new operations.

Enhanced error messages and logs for better debugging.

Extended UI field visibility logic in update_build_config to support dynamic path selection from JSON.

These updates significantly expand the component's capabilities for parsing, transforming, and querying structured JSON data.

Summary by CodeRabbit

  • New Features

    • Added advanced JSON querying and path extraction capabilities, including support for JSON path extraction and JSON query operations.
    • Enabled recursive removal and renaming of keys within nested JSON structures.
    • UI now dynamically updates selectable JSON paths based on the uploaded JSON structure.
  • Bug Fixes

    • Improved error handling for invalid JSON input during operations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 4, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The DataOperationsComponent class was enhanced to support advanced JSON manipulation, including recursive key removal/renaming, JSON path extraction, and jq-based JSON querying. New methods and static helpers enable these operations, and the component's configuration logic dynamically updates UI options based on parsed JSON structure, with improved error handling and logging.

Changes

Cohort / File(s) Change Summary
DataOperationsComponent: Advanced JSON Operations
src/backend/base/langflow/components/processing/data_operations.py
Added recursive helpers for extracting JSON paths, removing/renaming keys; introduced jq-based JSON query/path extraction methods; updated configuration and dispatch logic to support these new operations; improved error handling and logging.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DataOperationsComponent
    participant jq Library

    User->>DataOperationsComponent: Selects "JSON Query" or "JSON Path" operation
    DataOperationsComponent->>DataOperationsComponent: Parse and repair JSON input
    DataOperationsComponent->>jq Library: Execute jq query/path extraction
    jq Library-->>DataOperationsComponent: Return query/path result
    DataOperationsComponent-->>User: Return processed data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Suggested labels

size:M, lgtm

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Aug 4, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🔭 Outside diff range comments (2)
src/backend/base/langflow/components/processing/data_operations.py (2)

271-279: Remove duplicate method definition.

There are two identical definitions of operation_exception. The second definition (lines 275-279) will override the first one (lines 271-274).

Remove the duplicate:

-def operation_exception(self, operations: list[str]) -> None:
-    msg = f"{operations} operations are not supported in combination with each other."
-    raise ValueError(msg)
-
 def operation_exception(self, operations: list[str]) -> None:
     """Raise exception for incompatible operations."""
     msg = f"{operations} operations are not supported in combination with each other."
     raise ValueError(msg)

387-393: Remove duplicate method definition.

There are two identical definitions of compare_values. The second definition (lines 416-421) will override the first one (lines 387-393).

Remove the duplicate at lines 416-421:

-def compare_values(self, item_value: Any, filter_value: str, operator: str) -> bool:
-    comparison_func = OPERATORS.get(operator)
-    if comparison_func:
-        return comparison_func(item_value, filter_value)
-    return False
-

Also applies to: 416-421

🧹 Nitpick comments (2)
src/backend/base/langflow/components/processing/data_operations.py (2)

82-95: Consider documenting the list handling limitation.

The path extraction only examines the first element of arrays. While this is reasonable for homogeneous lists, it could miss paths in heterogeneous arrays where elements have different structures.

Add a docstring to clarify this behavior:

 @staticmethod
 def extract_all_paths(obj, path=""):
+    """Extract all possible JSON paths from an object.
+    
+    Note: For arrays, only the first element is examined to extract paths.
+    """
     paths = []

227-231: Consider handling missing jq dependency gracefully.

The jq import inside the method suggests it might be an optional dependency. Consider adding explicit error handling for when it's not installed.

 def json_query(self) -> Data:
     import json
 
-    import jq
+    try:
+        import jq
+    except ImportError as e:
+        msg = "The 'jq' library is required for JSON Query operations. Please install it with: pip install jq"
+        raise ImportError(msg) from e
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 087c1a2 and f83c665.

📒 Files selected for processing (1)
  • src/backend/base/langflow/components/processing/data_operations.py (14 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/backend/base/langflow/components/**/*.py

📄 CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

src/backend/base/langflow/components/**/*.py: Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/
Implement async component methods using async def and await for asynchronous operations
Use asyncio.create_task for background work in async components and ensure proper cleanup on cancellation
Use asyncio.Queue for non-blocking queue operations in async components and handle timeouts appropriately

Files:

  • src/backend/base/langflow/components/processing/data_operations.py
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/base/langflow/components/processing/data_operations.py
src/backend/**/components/**/*.py

📄 CodeRabbit Inference Engine (.cursor/rules/icons.mdc)

In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

Files:

  • src/backend/base/langflow/components/processing/data_operations.py
🧠 Learnings (4)
📚 Learning: applies to src/backend/base/langflow/components/**/__init__.py : update __init__.py with alphabetica...
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-07-18T18:25:54.486Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new components

Applied to files:

  • src/backend/base/langflow/components/processing/data_operations.py
📚 Learning: applies to src/backend/base/langflow/components/**/*.py : add new backend components to the appropri...
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-07-18T18:25:54.486Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/

Applied to files:

  • src/backend/base/langflow/components/processing/data_operations.py
📚 Learning: applies to src/backend/tests/**/*.py : test flows using predefined json data and utility functions s...
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-07-21T14:16:14.125Z
Learning: Applies to src/backend/tests/**/*.py : Test flows using predefined JSON data and utility functions such as 'create_flow', 'build_flow', 'get_build_events', and 'consume_and_assert_stream' in backend Python tests.

Applied to files:

  • src/backend/base/langflow/components/processing/data_operations.py
📚 Learning: when implementing a new component icon in langflow, ensure the icon name is clear, recognizable, and...
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/icons.mdc:0-0
Timestamp: 2025-06-23T12:46:52.420Z
Learning: When implementing a new component icon in Langflow, ensure the icon name is clear, recognizable, and used consistently across both backend (Python 'icon' attribute) and frontend (React/TypeScript mapping).

Applied to files:

  • src/backend/base/langflow/components/processing/data_operations.py
🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/base/langflow/components/processing/data_operations.py

[failure] 152-152: Ruff (E501)
src/backend/base/langflow/components/processing/data_operations.py:152:121: E501 Line too long (135 > 120)


[failure] 254-254: Ruff (B904)
src/backend/base/langflow/components/processing/data_operations.py:254:13: B904 Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling


[failure] 252-252: Ruff (BLE001)
src/backend/base/langflow/components/processing/data_operations.py:252:16: BLE001 Do not catch blind exception: Exception


[failure] 248-248: Ruff (EM101)
src/backend/base/langflow/components/processing/data_operations.py:248:34: EM101 Exception must not use a string literal, assign to variable first


[failure] 248-248: Ruff (TRY003)
src/backend/base/langflow/components/processing/data_operations.py:248:23: TRY003 Avoid specifying long messages outside the exception class


[failure] 245-245: Ruff (EM101)
src/backend/base/langflow/components/processing/data_operations.py:245:34: EM101 Exception must not use a string literal, assign to variable first


[failure] 245-245: Ruff (TRY003)
src/backend/base/langflow/components/processing/data_operations.py:245:23: TRY003 Avoid specifying long messages outside the exception class


[failure] 239-242: Ruff (SIM108)
src/backend/base/langflow/components/processing/data_operations.py:239:13: SIM108 Use ternary operator jq_input = data_json["data"] if isinstance(data_json, dict) and "data" in data_json else data_json instead of if-else-block


[failure] 233-233: Ruff (EM101)
src/backend/base/langflow/components/processing/data_operations.py:233:30: EM101 Exception must not use a string literal, assign to variable first


[failure] 233-233: Ruff (TRY003)
src/backend/base/langflow/components/processing/data_operations.py:233:19: TRY003 Avoid specifying long messages outside the exception class

🪛 GitHub Actions: Ruff Style Check
src/backend/base/langflow/components/processing/data_operations.py

[error] 152-152: Ruff E501: Line too long (135 > 120).

🔇 Additional comments (3)
src/backend/base/langflow/components/processing/data_operations.py (3)

4-5: LGTM! Good choice for JSON repair functionality.

The addition of json_repair import is appropriate for handling malformed JSON input in the new JSON query operations.


96-118: Excellent implementation of recursive operations!

The recursive helper methods for removing and renaming keys are well-designed:

  • Properly handle nested dictionaries and lists
  • Maintain immutability by creating new objects
  • The rename_keys_recursive correctly handles missing keys with dict.get()

121-139: Good configuration for single operation selection.

The limit=1 on SortableListInput ensures only one operation can be selected at a time, which correctly aligns with the execution logic in as_data() method.

name="filter_key",
display_name="Filter Key",
info="Key to filter by.",
info="Name of the key containing the list to filter. It must be a top-level key in the JSON and its value must be a list.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix line length violation.

Line exceeds 120 character limit (135 characters).

Break the line to comply with style guide:

-            info="Name of the key containing the list to filter. It must be a top-level key in the JSON and its value must be a list.",
+            info=("Name of the key containing the list to filter. "
+                  "It must be a top-level key in the JSON and its value must be a list."),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
info="Name of the key containing the list to filter. It must be a top-level key in the JSON and its value must be a list.",
info=("Name of the key containing the list to filter. "
"It must be a top-level key in the JSON and its value must be a list."),
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 152-152: Ruff (E501)
src/backend/base/langflow/components/processing/data_operations.py:152:121: E501 Line too long (135 > 120)

🪛 GitHub Actions: Ruff Style Check

[error] 152-152: Ruff E501: Line too long (135 > 120).

🤖 Prompt for AI Agents
In src/backend/base/langflow/components/processing/data_operations.py at line
152, the string assigned to the info parameter exceeds the 120 character limit.
Break this long string into multiple concatenated strings or split it across
lines to ensure no single line exceeds 120 characters, maintaining readability
and compliance with the style guide.

Comment on lines +227 to +255
def json_query(self) -> Data:
import json

import jq

if not self.query or not self.query.strip():
raise ValueError("JSON Query is required and cannot be blank.")
raw_data = self.get_data_dict()
try:
input_str = json.dumps(raw_data)
repaired = repair_json(input_str)
data_json = json.loads(repaired)
if isinstance(data_json, dict) and "data" in data_json:
jq_input = data_json["data"]
else:
jq_input = data_json
results = jq.compile(self.query).input(jq_input).all()
if not results:
raise ValueError("No result from JSON query.")
result = results[0] if len(results) == 1 else results
if result is None or result == "None":
raise ValueError("JSON query returned null/None. Check if the path exists in your data.")
if isinstance(result, dict):
return Data(data=result)
return Data(data={"result": result})
except Exception as e:
logger.error(f"JSON Query failed: {e}")
raise ValueError(f"JSON Query error: {e}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve exception handling in json_query method.

The exception handling needs improvement based on static analysis findings:

  1. Avoid catching broad Exception - be more specific
  2. Use raise from to preserve exception chain
  3. Consider extracting error messages to variables

Apply these improvements:

 def json_query(self) -> Data:
     import json
 
     import jq
 
     if not self.query or not self.query.strip():
-        raise ValueError("JSON Query is required and cannot be blank.")
+        msg = "JSON Query is required and cannot be blank."
+        raise ValueError(msg)
     raw_data = self.get_data_dict()
     try:
         input_str = json.dumps(raw_data)
         repaired = repair_json(input_str)
         data_json = json.loads(repaired)
         if isinstance(data_json, dict) and "data" in data_json:
             jq_input = data_json["data"]
         else:
             jq_input = data_json
         results = jq.compile(self.query).input(jq_input).all()
         if not results:
-            raise ValueError("No result from JSON query.")
+            msg = "No result from JSON query."
+            raise ValueError(msg)
         result = results[0] if len(results) == 1 else results
         if result is None or result == "None":
-            raise ValueError("JSON query returned null/None. Check if the path exists in your data.")
+            msg = "JSON query returned null/None. Check if the path exists in your data."
+            raise ValueError(msg)
         if isinstance(result, dict):
             return Data(data=result)
         return Data(data={"result": result})
-    except Exception as e:
+    except (json.JSONDecodeError, jq.JQError, ValueError) as e:
         logger.error(f"JSON Query failed: {e}")
-        raise ValueError(f"JSON Query error: {e}")
+        raise ValueError(f"JSON Query error: {e}") from e
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def json_query(self) -> Data:
import json
import jq
if not self.query or not self.query.strip():
raise ValueError("JSON Query is required and cannot be blank.")
raw_data = self.get_data_dict()
try:
input_str = json.dumps(raw_data)
repaired = repair_json(input_str)
data_json = json.loads(repaired)
if isinstance(data_json, dict) and "data" in data_json:
jq_input = data_json["data"]
else:
jq_input = data_json
results = jq.compile(self.query).input(jq_input).all()
if not results:
raise ValueError("No result from JSON query.")
result = results[0] if len(results) == 1 else results
if result is None or result == "None":
raise ValueError("JSON query returned null/None. Check if the path exists in your data.")
if isinstance(result, dict):
return Data(data=result)
return Data(data={"result": result})
except Exception as e:
logger.error(f"JSON Query failed: {e}")
raise ValueError(f"JSON Query error: {e}")
def json_query(self) -> Data:
import json
import jq
if not self.query or not self.query.strip():
msg = "JSON Query is required and cannot be blank."
raise ValueError(msg)
raw_data = self.get_data_dict()
try:
input_str = json.dumps(raw_data)
repaired = repair_json(input_str)
data_json = json.loads(repaired)
if isinstance(data_json, dict) and "data" in data_json:
jq_input = data_json["data"]
else:
jq_input = data_json
results = jq.compile(self.query).input(jq_input).all()
if not results:
msg = "No result from JSON query."
raise ValueError(msg)
result = results[0] if len(results) == 1 else results
if result is None or result == "None":
msg = "JSON query returned null/None. Check if the path exists in your data."
raise ValueError(msg)
if isinstance(result, dict):
return Data(data=result)
return Data(data={"result": result})
except (json.JSONDecodeError, jq.JQError, ValueError) as e:
logger.error(f"JSON Query failed: {e}")
raise ValueError(f"JSON Query error: {e}") from e
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 254-254: Ruff (B904)
src/backend/base/langflow/components/processing/data_operations.py:254:13: B904 Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling


[failure] 252-252: Ruff (BLE001)
src/backend/base/langflow/components/processing/data_operations.py:252:16: BLE001 Do not catch blind exception: Exception


[failure] 248-248: Ruff (EM101)
src/backend/base/langflow/components/processing/data_operations.py:248:34: EM101 Exception must not use a string literal, assign to variable first


[failure] 248-248: Ruff (TRY003)
src/backend/base/langflow/components/processing/data_operations.py:248:23: TRY003 Avoid specifying long messages outside the exception class


[failure] 245-245: Ruff (EM101)
src/backend/base/langflow/components/processing/data_operations.py:245:34: EM101 Exception must not use a string literal, assign to variable first


[failure] 245-245: Ruff (TRY003)
src/backend/base/langflow/components/processing/data_operations.py:245:23: TRY003 Avoid specifying long messages outside the exception class


[failure] 239-242: Ruff (SIM108)
src/backend/base/langflow/components/processing/data_operations.py:239:13: SIM108 Use ternary operator jq_input = data_json["data"] if isinstance(data_json, dict) and "data" in data_json else data_json instead of if-else-block


[failure] 233-233: Ruff (EM101)
src/backend/base/langflow/components/processing/data_operations.py:233:30: EM101 Exception must not use a string literal, assign to variable first


[failure] 233-233: Ruff (TRY003)
src/backend/base/langflow/components/processing/data_operations.py:233:19: TRY003 Avoid specifying long messages outside the exception class

🤖 Prompt for AI Agents
In src/backend/base/langflow/components/processing/data_operations.py around
lines 227 to 255, the json_query method currently catches a broad Exception
which is not recommended. Refine the exception handling by catching more
specific exceptions related to JSON processing and jq compilation/execution. Use
'raise from' when re-raising exceptions to preserve the original traceback.
Also, extract the error message into a variable before logging and raising the
new ValueError to improve clarity and maintainability.

Comment on lines 472 to 402
if field_name == "mapped_json_display":
try:
parsed_json = json.loads(field_value)
keys = DataOperationsComponent.extract_all_paths(parsed_json)
build_config["selected_key"]["options"] = keys
build_config["selected_key"]["show"] = True
except Exception as e:
logger.error(f"Error parsing mapped JSON: {e}")
build_config["selected_key"]["show"] = False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve exception handling specificity.

The generic exception handling could be more specific to provide better error messages.

         if field_name == "mapped_json_display":
             try:
                 parsed_json = json.loads(field_value)
                 keys = DataOperationsComponent.extract_all_paths(parsed_json)
                 build_config["selected_key"]["options"] = keys
                 build_config["selected_key"]["show"] = True
-            except Exception as e:
-                logger.error(f"Error parsing mapped JSON: {e}")
+            except json.JSONDecodeError as e:
+                logger.error(f"Invalid JSON format: {e}")
+                build_config["selected_key"]["show"] = False
+            except Exception as e:
+                logger.error(f"Unexpected error parsing mapped JSON: {e}")
                 build_config["selected_key"]["show"] = False
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if field_name == "mapped_json_display":
try:
parsed_json = json.loads(field_value)
keys = DataOperationsComponent.extract_all_paths(parsed_json)
build_config["selected_key"]["options"] = keys
build_config["selected_key"]["show"] = True
except Exception as e:
logger.error(f"Error parsing mapped JSON: {e}")
build_config["selected_key"]["show"] = False
if field_name == "mapped_json_display":
try:
parsed_json = json.loads(field_value)
keys = DataOperationsComponent.extract_all_paths(parsed_json)
build_config["selected_key"]["options"] = keys
build_config["selected_key"]["show"] = True
except json.JSONDecodeError as e:
logger.error(f"Invalid JSON format: {e}")
build_config["selected_key"]["show"] = False
except Exception as e:
logger.error(f"Unexpected error parsing mapped JSON: {e}")
build_config["selected_key"]["show"] = False
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/processing/data_operations.py around
lines 472 to 481, the current exception handling uses a generic Exception catch
which is too broad. Refine the except block to catch specific exceptions related
to JSON parsing, such as json.JSONDecodeError, to provide more precise error
handling and clearer log messages. Adjust the logger.error call accordingly to
reflect the specific error caught.

Comment on lines +484 to +498
def json_path(self) -> Data:
try:
if not self.data or not self.selected_key:
raise ValueError("Missing input data or selected key.")
input_payload = self.data[0].data if isinstance(self.data, list) else self.data.data
compiled = jq.compile(self.selected_key)
result = compiled.input(input_payload).first()
if isinstance(result, dict):
return Data(data=result)
return Data(data={"result": result})
except Exception as e:
self.status = f"Error: {e!s}"
self.log(self.status)
return Data(data={"error": str(e)})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add missing jq import and improve error handling.

The method uses jq module but doesn't import it. Also, exception handling could be more specific.

 def json_path(self) -> Data:
+    import jq
+    
     try:
         if not self.data or not self.selected_key:
             raise ValueError("Missing input data or selected key.")
         input_payload = self.data[0].data if isinstance(self.data, list) else self.data.data
         compiled = jq.compile(self.selected_key)
         result = compiled.input(input_payload).first()
         if isinstance(result, dict):
             return Data(data=result)
         return Data(data={"result": result})
-    except Exception as e:
+    except jq.JQError as e:
+        self.status = f"Invalid jq expression: {e!s}"
+        self.log(self.status)
+        return Data(data={"error": str(e)})
+    except Exception as e:
         self.status = f"Error: {e!s}"
         self.log(self.status)
         return Data(data={"error": str(e)})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def json_path(self) -> Data:
try:
if not self.data or not self.selected_key:
raise ValueError("Missing input data or selected key.")
input_payload = self.data[0].data if isinstance(self.data, list) else self.data.data
compiled = jq.compile(self.selected_key)
result = compiled.input(input_payload).first()
if isinstance(result, dict):
return Data(data=result)
return Data(data={"result": result})
except Exception as e:
self.status = f"Error: {e!s}"
self.log(self.status)
return Data(data={"error": str(e)})
def json_path(self) -> Data:
import jq
try:
if not self.data or not self.selected_key:
raise ValueError("Missing input data or selected key.")
input_payload = self.data[0].data if isinstance(self.data, list) else self.data.data
compiled = jq.compile(self.selected_key)
result = compiled.input(input_payload).first()
if isinstance(result, dict):
return Data(data=result)
return Data(data={"result": result})
except jq.JQError as e:
self.status = f"Invalid jq expression: {e!s}"
self.log(self.status)
return Data(data={"error": str(e)})
except Exception as e:
self.status = f"Error: {e!s}"
self.log(self.status)
return Data(data={"error": str(e)})
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/processing/data_operations.py around
lines 484 to 498, the jq module is used but not imported, causing a NameError.
Add an import statement for jq at the top of the file. Also, refine the
exception handling by catching specific exceptions related to jq compilation and
execution instead of a broad Exception to improve error clarity and handling.

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant