Skip to content

feat: enhance DataFrame Operations component with contains filter and modern UI#8838

Merged
edwinjosechittilappilly merged 6 commits into
mainfrom
feature/dataframe-operations-enhancements
Jul 9, 2025
Merged

feat: enhance DataFrame Operations component with contains filter and modern UI#8838
edwinjosechittilappilly merged 6 commits into
mainfrom
feature/dataframe-operations-enhancements

Conversation

@rodrigosnader
Copy link
Copy Markdown
Contributor

@rodrigosnader rodrigosnader commented Jul 2, 2025

Summary

This PR enhances the DataFrame Operations component with several key improvements:

"Contains" Filter: Added partial string matching capability for filtering DataFrame rows
Modern UI: Updated to use SortableListInput with icons for consistent design with Data Operations component
Extended Filter Operators: Now supports 7 operators (equals, not equals, contains, starts with, ends with, greater than, less than)
Bug Fixes: Fixed deselection handling and dynamic field visibility issues
Comprehensive Testing: Added 25 tests covering all operations and edge cases

Key Changes

🎯 New "Contains" Filter

  • Users can now filter rows where values contain a substring (e.g., filter emails containing "gmail")
  • Smart type conversion for numeric comparisons
  • Handles edge cases like missing values and mixed data types

🎨 Modern UI Consistency

  • Main operation selector now uses SortableListInput with icons
  • Matches the modern design pattern established by Data Operations component
  • Sub-operations (like filter operators) remain as DropdownInput for usability

🐛 Bug Fixes

  • Fixed "unhashable type: list" error when deselecting operations
  • Fixed dynamic field persistence - fields now properly hide when operations are deselected
  • Improved placeholder text from "Select DataFrame Operation" to "Select Operation"

✅ Comprehensive Testing

  • 25 test cases covering basic operations, all filter operators, edge cases, dynamic UI, and data types
  • Integration tests verifying all operators work correctly together
  • Edge case handling for empty DataFrames, invalid inputs, and deselection scenarios

Test Results

========================= 25 passed, 2 warnings in 0.07s =========================

All tests pass, confirming the component works reliably with the new enhancements.

Test plan

  • Verify "contains" filter works for partial string matching
  • Test all 7 filter operators with various data types
  • Confirm modern UI matches Data Operations component style
  • Validate deselection handling doesn't cause errors
  • Check dynamic fields hide/show correctly
  • Run full test suite (25/25 tests passing)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Enhanced DataFrame operation selection with a sortable list and icons for improved usability.
    • Added support for multiple filter operators, including equals, not equals, contains, starts with, ends with, greater than, and less than, for more flexible DataFrame filtering.
  • Bug Fixes

    • Improved handling of empty or invalid operation selections and edge cases to prevent errors.
  • Tests

    • Expanded and reorganized test coverage for DataFrame operations, filter operators, UI behavior, and error handling.

… modern UI

- Add "contains" filter operator for partial string matching in DataFrame filters
- Update UI to use SortableListInput with icons for consistent modern design
- Add 7 filter operators: equals, not equals, contains, starts with, ends with, greater than, less than
- Fix deselection handling to prevent "unhashable type: list" errors
- Improve dynamic field visibility when operations are deselected
- Add comprehensive test suite with 25 tests covering all operations and edge cases
- Update placeholder text from "Select DataFrame Operation" to "Select Operation"

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 2, 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 DataFrame operations component was updated to use a sortable list input for selecting operations, allowing richer metadata and icons per operation. Filtering now supports multiple operators, and dynamic UI logic was revised accordingly. The test suite was comprehensively rewritten to cover all new behaviors, edge cases, and UI dynamics.

Changes

File(s) Change Summary
src/backend/base/langflow/components/processing/dataframe_operations.py Changed operation input to SortableListInput with metadata, added filter_operator input, expanded filtering logic, updated UI logic.
src/backend/tests/unit/components/processing/test_dataframe_operations.py Rewrote and expanded tests: added classes for basic operations, filters, edge cases, dynamic UI, data types, and integration tests.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant DataFrameOperationsComponent
    participant Pandas

    User->>UI: Selects DataFrame operation (SortableListInput)
    UI->>DataFrameOperationsComponent: Sends selected operation and parameters
    DataFrameOperationsComponent->>DataFrameOperationsComponent: update_build_config (show/hide fields)
    DataFrameOperationsComponent->>Pandas: perform_operation (with selected operator/filter)
    Pandas-->>DataFrameOperationsComponent: Returns modified DataFrame
    DataFrameOperationsComponent-->>UI: Returns result
    UI-->>User: Displays updated DataFrame
Loading

Possibly related PRs

Suggested labels

size:M, lgtm

Suggested reviewers

  • rodrigosnader
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/dataframe-operations-enhancements

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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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.

Documentation and Community

  • 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.

@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Jul 2, 2025
@github-actions github-actions Bot added the enhancement New feature or request label Jul 2, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 2, 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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e280932 and 46c12f9.

📒 Files selected for processing (2)
  • src/backend/base/langflow/components/processing/dataframe_operations.py (6 hunks)
  • src/backend/tests/unit/components/processing/test_dataframe_operations.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
`src/backend/base/langflow/components/**/*.py`: Add new backend components to th...

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

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

List of files the instruction was applied to:

  • src/backend/base/langflow/components/processing/dataframe_operations.py
`src/backend/**/*.py`: Run make format_backend to format Python code early and often Run make lint to check for linting issues in backend Python code

src/backend/**/*.py: Run make format_backend to format Python code early and often
Run make lint to check for linting issues in backend Python code

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

List of files the instruction was applied to:

  • src/backend/base/langflow/components/processing/dataframe_operations.py
  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/**/components/**/*.py`: In your Python component class, set the `icon` attribute to a string matching the frontend icon mapping exactly (case-sensitive).

src/backend/**/components/**/*.py: In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

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

List of files the instruction was applied to:

  • src/backend/base/langflow/components/processing/dataframe_operations.py
  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/tests/unit/components/**/*.py`: Mirror the component directory stru...

src/backend/tests/unit/components/**/*.py: Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Provide file_names_mapping in tests for backward compatibility version testing
Create comprehensive unit tests for all new components
Use the client fixture from conftest.py for FastAPI API endpoint tests
Test authenticated FastAPI endpoints using logged_in_headers in tests

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

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/tests/unit/**/*.py`: Use in-memory SQLite for database tests Test c...

src/backend/tests/unit/**/*.py: Use in-memory SQLite for database tests
Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs

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

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/tests/**/*.py`: Unit tests for backend code should be located in 's...

src/backend/tests/**/*.py: Unit tests for backend code should be located in 'src/backend/tests/' and organized by component subdirectory for component tests.
Test files should use the same filename as the component with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Skip client creation in tests by marking them with '@pytest.mark.noclient' when the 'client' fixture is not needed.
Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/...

{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py}: Each test should have a clear docstring explaining its purpose.
Complex test setups should be commented, and mock usage should be documented within the test code.
Expected behaviors should be explicitly stated in test docstrings or comments.
Create comprehensive unit tests for all new components.
Test both sync and async code paths in components.
Mock external dependencies appropriately in tests.
Test error handling and edge cases in components.
Validate input/output behavior in tests.
Test component initialization and configuration.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`{src/backend/tests/**/*.py,tests/**/*.py}`: Use '@pytest.mark.asyncio' for asyn...

{src/backend/tests/**/*.py,tests/**/*.py}: Use '@pytest.mark.asyncio' for async test functions.
Test queue operations in async tests using 'asyncio.Queue' and non-blocking put/get methods.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests.
Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Each test should ensure proper resource cleanup, especially in async fixtures using 'try/finally' and cleanup methods.
Test that operations respect timeout constraints and assert elapsed time is within tolerance.
Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
Use predefined JSON flows and utility functions for flow testing (e.g., 'create_flow', 'build_flow', 'get_build_events', 'consume_and_assert_stream').
Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Use 'MockLanguageModel' for testing language model components without external API calls.
Use 'anyio' and 'aiofiles' for async file operations in tests.
Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Test component configuration updates by asserting changes in build config dictionaries.
Test real-time event streaming endpoints by consuming NDJSON event streams and validating event structure.
Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Test webhook endpoints by posting payloads and asserting correct processing and status codes.
Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
🧠 Learnings (2)
src/backend/base/langflow/components/processing/dataframe_operations.py (1)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new components
src/backend/tests/unit/components/processing/test_dataframe_operations.py (12)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Create comprehensive unit tests for all new components
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Create comprehensive unit tests for all new components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/**/*.py : Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test component configuration updates by asserting changes in build config dictionaries.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Unit tests for backend code should be located in 'src/backend/tests/' and organized by component subdirectory for component tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Complex test setups should be commented, and mock usage should be documented within the test code.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Test files should use the same filename as the component with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test error handling and edge cases in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Validate input/output behavior in tests.
🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/base/langflow/components/processing/dataframe_operations.py

[failure] 169-173: Ruff (SIM108)
src/backend/base/langflow/components/processing/dataframe_operations.py:169:17: SIM108 Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block

🪛 Ruff (0.11.9)
src/backend/base/langflow/components/processing/dataframe_operations.py

169-173: Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block

(SIM108)

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

[error] 169-169: Ruff SIM108: Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block.

🔇 Additional comments (8)
src/backend/base/langflow/components/processing/dataframe_operations.py (4)

44-63: LGTM! Nice UI modernization.

The migration to SortableListInput with icons enhances the user experience while maintaining single-selection behavior through limit=1. The icon choices are intuitive for each operation.


78-87: Excellent addition of filter operators.

The comprehensive set of filter operators enables powerful DataFrame filtering capabilities. Setting the default to "equals" ensures backward compatibility for existing workflows.


212-222: Good handling of the new input format.

The implementation correctly extracts the operation from the SortableListInput format and gracefully handles empty selections by returning the original DataFrame unchanged.


248-283: Excellent implementation of comprehensive filter operators!

The enhanced filtering logic is well-designed with:

  • Smart numeric conversion that falls back to string comparison
  • Proper handling of missing values using na=False in string operations
  • Robust error handling for type mismatches
  • Consistent behavior across all operators

This is a significant improvement to the component's functionality.

src/backend/tests/unit/components/processing/test_dataframe_operations.py (4)

7-24: Well-structured test fixtures.

The sample DataFrame provides realistic test data with good variety in data types and values, which is essential for testing all the filter operators effectively.


115-208: Comprehensive filter operator test coverage!

Excellent test suite for all filter operators with well-chosen test data and thorough assertions. The special callout for the "contains" filter appropriately highlights the PR's main feature.


210-265: Excellent edge case coverage.

The tests thoroughly cover important edge cases including empty selections, invalid formats, and error conditions. Using pytest.raises for the KeyError test is the correct approach.


389-423: Well-designed integration test.

The comprehensive test of all filter operators on a single dataset provides excellent verification that all operators work correctly. The parameterized test cases with clear failure messages make debugging easy.

Comment on lines 166 to +180
if field_name == "operation":
if field_value == "Filter":
# Handle SortableListInput format
if isinstance(field_value, list):
if len(field_value) > 0:
operation_name = field_value[0].get("name", "")
else:
# Handle empty selection (user deselected)
operation_name = ""
else:
operation_name = field_value or ""

# If no operation selected, all dynamic fields stay hidden (already set to False above)
if not operation_name:
return build_config

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

Apply the suggested style improvement to fix the pipeline failure.

The logic is correct, but the static analysis tool recommends using a ternary operator for better conciseness.

Apply this diff to resolve the Ruff style check failure:

-            if isinstance(field_value, list):
-                if len(field_value) > 0:
-                    operation_name = field_value[0].get("name", "")
-                else:
-                    # Handle empty selection (user deselected)
-                    operation_name = ""
+            if isinstance(field_value, list):
+                operation_name = field_value[0].get("name", "") if len(field_value) > 0 else ""
📝 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 == "operation":
if field_value == "Filter":
# Handle SortableListInput format
if isinstance(field_value, list):
if len(field_value) > 0:
operation_name = field_value[0].get("name", "")
else:
# Handle empty selection (user deselected)
operation_name = ""
else:
operation_name = field_value or ""
# If no operation selected, all dynamic fields stay hidden (already set to False above)
if not operation_name:
return build_config
if field_name == "operation":
# Handle SortableListInput format
if isinstance(field_value, list):
operation_name = field_value[0].get("name", "") if len(field_value) > 0 else ""
else:
operation_name = field_value or ""
# If no operation selected, all dynamic fields stay hidden (already set to False above)
if not operation_name:
return build_config
🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 169-173: Ruff (SIM108)
src/backend/base/langflow/components/processing/dataframe_operations.py:169:17: SIM108 Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block

🪛 Ruff (0.11.9)

169-173: Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block

(SIM108)

🪛 GitHub Actions: Ruff Style Check

[error] 169-169: Ruff SIM108: Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block.

🤖 Prompt for AI Agents
In src/backend/base/langflow/components/processing/dataframe_operations.py
around lines 166 to 180, replace the multi-line if-else block that assigns
operation_name based on field_value with a single-line ternary expression to
improve conciseness and fix the Ruff style check failure. Use a ternary operator
to assign operation_name to field_value[0].get("name", "") if field_value is a
non-empty list, otherwise assign an empty string or field_value or empty string
accordingly.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 2, 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: 0

🧹 Nitpick comments (1)
src/backend/base/langflow/components/processing/dataframe_operations.py (1)

168-173: Simplify operation name extraction with ternary operator.

The logic is correct but can be simplified as suggested by static analysis.

-            if isinstance(field_value, list):
-                if len(field_value) > 0:
-                    operation_name = field_value[0].get("name", "")
-                else:
-                    # Handle empty selection (user deselected)
-                    operation_name = ""
+            if isinstance(field_value, list):
+                operation_name = field_value[0].get("name", "") if len(field_value) > 0 else ""
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e280932 and 46c12f9.

📒 Files selected for processing (2)
  • src/backend/base/langflow/components/processing/dataframe_operations.py (6 hunks)
  • src/backend/tests/unit/components/processing/test_dataframe_operations.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
`src/backend/base/langflow/components/**/*.py`: Add new backend components to th...

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

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

List of files the instruction was applied to:

  • src/backend/base/langflow/components/processing/dataframe_operations.py
`src/backend/**/*.py`: Run make format_backend to format Python code early and often Run make lint to check for linting issues in backend Python code

src/backend/**/*.py: Run make format_backend to format Python code early and often
Run make lint to check for linting issues in backend Python code

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

List of files the instruction was applied to:

  • src/backend/base/langflow/components/processing/dataframe_operations.py
  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/**/components/**/*.py`: In your Python component class, set the `icon` attribute to a string matching the frontend icon mapping exactly (case-sensitive).

src/backend/**/components/**/*.py: In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

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

List of files the instruction was applied to:

  • src/backend/base/langflow/components/processing/dataframe_operations.py
  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/tests/unit/components/**/*.py`: Mirror the component directory stru...

src/backend/tests/unit/components/**/*.py: Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Provide file_names_mapping in tests for backward compatibility version testing
Create comprehensive unit tests for all new components
Use the client fixture from conftest.py for FastAPI API endpoint tests
Test authenticated FastAPI endpoints using logged_in_headers in tests

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

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/tests/unit/**/*.py`: Use in-memory SQLite for database tests Test c...

src/backend/tests/unit/**/*.py: Use in-memory SQLite for database tests
Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs

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

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`src/backend/tests/**/*.py`: Unit tests for backend code should be located in 's...

src/backend/tests/**/*.py: Unit tests for backend code should be located in 'src/backend/tests/' and organized by component subdirectory for component tests.
Test files should use the same filename as the component with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Skip client creation in tests by marking them with '@pytest.mark.noclient' when the 'client' fixture is not needed.
Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/...

{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py}: Each test should have a clear docstring explaining its purpose.
Complex test setups should be commented, and mock usage should be documented within the test code.
Expected behaviors should be explicitly stated in test docstrings or comments.
Create comprehensive unit tests for all new components.
Test both sync and async code paths in components.
Mock external dependencies appropriately in tests.
Test error handling and edge cases in components.
Validate input/output behavior in tests.
Test component initialization and configuration.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
`{src/backend/tests/**/*.py,tests/**/*.py}`: Use '@pytest.mark.asyncio' for asyn...

{src/backend/tests/**/*.py,tests/**/*.py}: Use '@pytest.mark.asyncio' for async test functions.
Test queue operations in async tests using 'asyncio.Queue' and non-blocking put/get methods.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests.
Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Each test should ensure proper resource cleanup, especially in async fixtures using 'try/finally' and cleanup methods.
Test that operations respect timeout constraints and assert elapsed time is within tolerance.
Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
Use predefined JSON flows and utility functions for flow testing (e.g., 'create_flow', 'build_flow', 'get_build_events', 'consume_and_assert_stream').
Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Use 'MockLanguageModel' for testing language model components without external API calls.
Use 'anyio' and 'aiofiles' for async file operations in tests.
Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Test component configuration updates by asserting changes in build config dictionaries.
Test real-time event streaming endpoints by consuming NDJSON event streams and validating event structure.
Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Test webhook endpoints by posting payloads and asserting correct processing and status codes.
Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/processing/test_dataframe_operations.py
🧠 Learnings (2)
src/backend/base/langflow/components/processing/dataframe_operations.py (1)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new components
src/backend/tests/unit/components/processing/test_dataframe_operations.py (10)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Create comprehensive unit tests for all new components
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Create comprehensive unit tests for all new components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/**/*.py : Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Unit tests for backend code should be located in 'src/backend/tests/' and organized by component subdirectory for component tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test component configuration updates by asserting changes in build config dictionaries.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test error handling and edge cases in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Validate input/output behavior in tests.
🧬 Code Graph Analysis (1)
src/backend/base/langflow/components/processing/dataframe_operations.py (3)
src/backend/tests/unit/components/processing/test_dataframe_operations.py (1)
  • component (21-23)
src/backend/base/langflow/inputs/inputs.py (2)
  • SortableListInput (535-545)
  • DropdownInput (467-491)
src/backend/base/langflow/schema/dataframe.py (1)
  • DataFrame (11-206)
🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/base/langflow/components/processing/dataframe_operations.py

[failure] 169-173: Ruff (SIM108)
src/backend/base/langflow/components/processing/dataframe_operations.py:169:17: SIM108 Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block

🪛 Ruff (0.11.9)
src/backend/base/langflow/components/processing/dataframe_operations.py

169-173: Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block

(SIM108)

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

[error] 169-169: Ruff SIM108: Use ternary operator operation_name = field_value[0].get("name", "") if len(field_value) > 0 else "" instead of if-else-block.

🔇 Additional comments (8)
src/backend/base/langflow/components/processing/dataframe_operations.py (4)

1-1: LGTM!

The pandas import is necessary for the new filtering functionality that uses pd.to_numeric.


44-63: UI modernization looks good!

The change from DropdownInput to SortableListInput with icon metadata aligns well with the PR objectives. The limit=1 ensures single selection behavior is maintained.


212-221: Good defensive programming!

The early return when no operation is selected properly handles the deselection case and prevents potential errors downstream.


247-283: Excellent implementation of the enhanced filtering functionality!

The filter method now supports all the required operators with smart type conversion and proper edge case handling:

  • Numeric comparisons attempt type conversion with fallback to string comparison
  • String operations properly handle missing values with na=False
  • The fallback to equals operator provides a safe default

This implementation fully addresses the PR objectives for the contains filter and other operators.

src/backend/tests/unit/components/processing/test_dataframe_operations.py (4)

7-24: Well-structured test fixtures!

The fixtures provide comprehensive test data and proper component initialization. The sample DataFrame includes various data types (strings, numbers, emails) which enables thorough testing of all filter operators.


115-208: Excellent comprehensive test coverage for all filter operators!

The test suite thoroughly covers all 7 filter operators mentioned in the PR objectives:

  • equals, not equals
  • contains (the main new feature)
  • starts with, ends with
  • greater than, less than

Each operator is tested with appropriate data and assertions verify the expected behavior.


210-265: Thorough edge case testing!

The edge case tests properly verify the bug fixes mentioned in the PR objectives:

  • Empty selection handling (fixes the "unhashable type: list" error)
  • Proper error handling for non-existent columns
  • Graceful handling of filters with no matches

This ensures the component is robust against various user inputs.


389-423: Excellent integration test!

The comprehensive integration test verifies all filter operators work correctly together on the same dataset with clear test cases and expected results. This provides confidence that the implementation works end-to-end.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 9, 2025
Copy link
Copy Markdown
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly left a comment

Choose a reason for hiding this comment

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

LGTM.

Copy link
Copy Markdown
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly left a comment

Choose a reason for hiding this comment

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

LGTM.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jul 9, 2025
@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator

fixing ruff errors soon

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 9, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 9, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 9, 2025
@edwinjosechittilappilly edwinjosechittilappilly added this pull request to the merge queue Jul 9, 2025
Merged via the queue into main with commit e0400f2 Jul 9, 2025
66 checks passed
@edwinjosechittilappilly edwinjosechittilappilly deleted the feature/dataframe-operations-enhancements branch July 9, 2025 22:03
smatiolids pushed a commit to smatiolids/langflow-dev that referenced this pull request Jul 10, 2025
… modern UI (langflow-ai#8838)

* feat: enhance DataFrame Operations component with contains filter and modern UI

- Add "contains" filter operator for partial string matching in DataFrame filters
- Update UI to use SortableListInput with icons for consistent modern design
- Add 7 filter operators: equals, not equals, contains, starts with, ends with, greater than, less than
- Fix deselection handling to prevent "unhashable type: list" errors
- Improve dynamic field visibility when operations are deselected
- Add comprehensive test suite with 25 tests covering all operations and edge cases
- Update placeholder text from "Select DataFrame Operation" to "Select Operation"

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* Update dataframe_operations.py

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants