feat(database): add noop mode with config flag and update related tests#9054
Conversation
…less sessions - Added `use_noop_session` fixture to facilitate testing without a database. - Expanded `TestAgentComponent` with new tests for agent responses using the Calculator tool and validation across all OpenAI and Anthropic models. - Updated `test_component.py` to include tests for message sending without a database, ensuring proper event handling and message integrity. - Refactored existing tests for clarity and consistency.
…rdown_superuser functions - Updated user retrieval in both functions to handle different result types from the database query, ensuring robustness against unexpected return values. - Added checks for `first()` method and list type to improve error handling and maintainability.
- Introduced `use_noop_database` configuration option to disable all database operations, controlled by the `LANGFLOW_USE_NOOP_DATABASE` environment variable. - Updated the `use_noop_session` fixture to reflect the new environment variable for testing without a database.
- Added NoopSession class to provide a no-operation database session, allowing for testing and operation without a real database connection. - Updated DatabaseService to utilize NoopSession when the `use_noop_database` setting is enabled, ensuring all database operations are disabled in this mode. - Enhanced error handling and logging for session management, improving robustness in scenarios where the database is not in use.
- Changed import path for NoopSession from `langflow.services.database.service` to `langflow.services.database.session` in both `test_agent_component.py` and `test_component.py`. - This refactor improves code organization and aligns with recent changes in the project structure.
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughA no-operation (noop) database mode was introduced, controlled by a new configuration flag. When enabled, the system uses a stub session class that bypasses all database operations. The database service, settings, and utility functions were updated to support this mode. Tests and fixtures were added and updated to verify behavior with and without a real database. Changes
Sequence Diagram(s)sequenceDiagram
participant App
participant Settings
participant DatabaseService
participant NoopSession
participant AsyncSession
App->>Settings: Check use_noop_database flag
App->>DatabaseService: Request session (with_session)
alt use_noop_database is True
DatabaseService->>NoopSession: Create NoopSession
DatabaseService-->>App: Yield NoopSession
else
DatabaseService->>AsyncSession: Create AsyncSession
DatabaseService-->>App: Yield AsyncSession
end
App->>DatabaseService: Perform DB operations (add, commit, etc.)
Note right of NoopSession: All methods are no-ops
Suggested labels
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
src/backend/base/langflow/services/database/session.py (1)
1-53: NoopSession implementation needs interface consistency improvements.The implementation provides good async stubs for database operations, but there are interface compatibility concerns:
exec() method inconsistency: Returns an empty list, but real sessions return result objects with methods like
.first(). This forces defensive programming in other parts of the codebase.Missing result object interface: Consider implementing a
NoopResultclass that mimics the real session result interface.Consider implementing a more compatible interface:
+class NoopResult: + def first(self): + return None + + def all(self): + return [] + + def __iter__(self): + return iter([]) class NoopSession: # ... existing code ... async def exec(self, *args, **kwargs): # noqa: ARG002 - return [] + return NoopResult()This would eliminate the need for defensive programming in
utils.pyand provide better interface consistency.
🧹 Nitpick comments (1)
src/backend/tests/unit/custom/custom_component/test_component.py (1)
113-133: Well-structured test for NoopSession integration.The test correctly verifies Component's send_message behavior with NoopSession, properly mocking async methods and asserting expected calls. Consider removing the unused
monkeypatchparameter if it's not needed for consistency with other tests.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/backend/base/langflow/services/database/service.py(2 hunks)src/backend/base/langflow/services/database/session.py(1 hunks)src/backend/base/langflow/services/settings/base.py(1 hunks)src/backend/base/langflow/services/utils.py(2 hunks)src/backend/tests/conftest.py(2 hunks)src/backend/tests/unit/components/agents/test_agent_component.py(5 hunks)src/backend/tests/unit/custom/custom_component/test_component.py(5 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
src/backend/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/backend_development.mdc
src/backend/tests/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/testing.mdc
{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py}
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/testing.mdc
{src/backend/tests/**/*.py,tests/**/*.py}
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/testing.mdc
src/backend/tests/unit/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/backend_development.mdc
src/backend/**/*component*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/icons.mdc
src/backend/tests/unit/components/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/backend_development.mdc
src/backend/**/components/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/icons.mdc
🧠 Learnings (3)
src/backend/tests/conftest.py (11)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/**/*.py : Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to src/backend/tests/**/*.py : Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to src/backend/tests/**/*.py : Skip client creation in tests by marking them with '@pytest.mark.noclient' when the 'client' fixture is not needed.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use 'anyio' and 'aiofiles' for async file operations in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Mock external dependencies appropriately in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
src/backend/tests/unit/custom/custom_component/test_component.py (18)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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.849Z
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.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test both sync and async code paths in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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.849Z
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.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Mock external dependencies appropriately in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use 'MockLanguageModel' for testing language model components without external API calls.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
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.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test component initialization and configuration.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use predefined JSON flows and utility functions for flow testing (e.g., 'create_flow', 'build_flow', 'get_build_events', 'consume_and_assert_stream').
src/backend/tests/unit/components/agents/test_agent_component.py (21)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
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.464Z
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.849Z
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/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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.849Z
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/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
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.849Z
Learning: Applies to src/backend/tests/**/*.py : Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test both sync and async code paths in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Mock external dependencies appropriately in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use '@pytest.mark.asyncio' for async test functions.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use 'anyio' and 'aiofiles' for async file operations in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use 'MockLanguageModel' for testing language model components without external API calls.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test component initialization and configuration.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Test authenticated FastAPI endpoints using logged_in_headers in tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/tests/unit/**/*.py : Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
🧬 Code Graph Analysis (1)
src/backend/tests/unit/components/agents/test_agent_component.py (4)
src/backend/base/langflow/services/database/session.py (1)
NoopSession(1-52)src/backend/tests/base.py (2)
ComponentTestBaseWithClient(159-160)ComponentTestBaseWithoutClient(163-164)src/backend/base/langflow/components/tools/calculator.py (1)
CalculatorToolComponent(15-103)src/backend/base/langflow/components/agents/agent.py (1)
message_response(83-127)
🔇 Additional comments (15)
src/backend/base/langflow/services/settings/base.py (1)
129-132: Configuration field implementation looks good.The new
use_noop_databasesetting is properly defined with clear documentation and appropriate defaults. The environment variable mapping follows the established pattern.src/backend/base/langflow/services/database/service.py (2)
30-30: Good import addition.The import of
NoopSessionis properly placed and follows the existing import structure.
185-200: Conditional session logic is well implemented.The implementation correctly:
- Checks the configuration flag to determine session type
- Provides helpful warning when noop mode is enabled
- Maintains proper error handling for real database sessions
- Preserves the async context manager interface
The conditional logic ensures backward compatibility while adding the new no-op functionality.
src/backend/tests/conftest.py (2)
79-82: Appropriate blockbuster extensions for database operations.The additional blocking permissions for Alembic migration files and dotenv operations are reasonable and necessary for database setup during tests.
373-381: Well-implemented test fixture for noop mode.The fixture properly:
- Sets the environment variable to enable noop database mode
- Uses monkeypatch for proper test isolation
- Includes cleanup with
monkeypatch.undo()- Follows pytest fixture conventions
This will enable comprehensive testing of the noop database functionality.
src/backend/base/langflow/services/utils.py (1)
123-129: Consistent defensive programming pattern.The same defensive pattern is applied here as in the
get_or_create_super_userfunction, which maintains consistency in handling different session return types.src/backend/tests/unit/custom/custom_component/test_component.py (4)
2-2: LGTM! Imports are appropriate for the new tests.The added imports for
AsyncMock,patch,Component,Message, andNoopSessionare correctly used in the new test functions.Also applies to: 8-8, 11-12
31-31: Good practice: Added reason to xfail marker.Adding a reason to the xfail marker improves test documentation and maintainability.
84-85: Appropriate linting suppressions for unused arguments.The
# noqa: ARG002comments correctly suppress warnings for unused arguments that are required by the method signature but not used in these test implementations.Also applies to: 101-102
135-163: Good test coverage for AgentComponent with NoopSession.The test correctly verifies AgentComponent's send_message behavior, following the same pattern as the Component test. This ensures consistent behavior across different component types when using NoopSession.
src/backend/tests/unit/components/agents/test_agent_component.py (5)
3-3: LGTM! Imports support NoopSession testing.The added imports for
AsyncMock,patch, andNoopSessionare appropriately used in the new test methods.Also applies to: 18-18
26-26: Class rename follows testing conventions.The rename to
TestAgentComponentWithoutClientcorrectly aligns with the component testing pattern, inheriting fromComponentTestBaseWithoutClientas per the coding guidelines.
134-165: Verify agent_llm parameter value.The test sets
agent_llm=Nonewhilellm_type="OpenAI". This appears inconsistent with other tests whereagent_llm="OpenAI"is used for OpenAI models.Consider aligning with the pattern used in other tests:
- agent_llm=None, + agent_llm="OpenAI",
166-201: Well-structured comprehensive test for Anthropic models.The test excellently covers all Anthropic models with proper error handling and detailed failure reporting. The use of a dictionary to track failures per model with specific error messages is a great improvement over simple assertions.
216-216: Good improvements to error tracking and consistency.The changes improve the tests by:
- Using dictionaries for detailed failure tracking with specific error messages
- Adding exception handling to prevent cascading failures
- Making the code more consistent between test classes
- Properly setting
agent_llm="OpenAI"instead of NoneAlso applies to: 241-259
| result = await session.exec(stmt) | ||
| if hasattr(result, "first"): | ||
| user = result.first() | ||
| elif isinstance(result, list): | ||
| user = result[0] if result else None | ||
| else: | ||
| user = None |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Defensive programming for session compatibility.
The updated logic handles different possible return types from session.exec(), which suggests the NoopSession and real sessions might have different return interfaces. While this approach is robust, it indicates a potential inconsistency in the session interface.
Consider ensuring NoopSession.exec() returns a result object that behaves consistently with real sessions (i.e., has a .first() method) to maintain interface compatibility and avoid the need for this defensive code.
🤖 Prompt for AI Agents
In src/backend/base/langflow/services/utils.py around lines 32 to 38, the code
defensively checks the type of the result from session.exec() due to differing
interfaces between NoopSession and real sessions. To fix this, modify
NoopSession.exec() so it returns an object with a .first() method consistent
with real session results. This will unify the interface and allow removing the
type checks and conditional logic in this code.
| @pytest.mark.api_key_required | ||
| @pytest.mark.no_blockbuster | ||
| async def test_agent_component_with_calculator(self): | ||
| # Now you can access the environment variables | ||
| api_key = os.getenv("OPENAI_API_KEY") | ||
| tools = [CalculatorToolComponent().build_tool()] # Use the Calculator component as a tool | ||
| input_value = "What is 2 + 2?" | ||
|
|
||
| temperature = 0.1 | ||
|
|
||
| # Initialize the AgentComponent with mocked inputs | ||
| agent = AgentComponent( | ||
| tools=tools, | ||
| input_value=input_value, | ||
| api_key=api_key, | ||
| model_name="gpt-4.1-nano", | ||
| llm_type="OpenAI", | ||
| temperature=temperature, | ||
| _session_id=str(uuid4()), | ||
| ) | ||
|
|
||
| with ( | ||
| patch.object(NoopSession, "add", new_callable=AsyncMock) as mock_add, | ||
| patch.object(NoopSession, "commit", new_callable=AsyncMock) as mock_commit, | ||
| ): | ||
| response = await agent.message_response() | ||
| assert mock_add.called | ||
| assert mock_commit.called | ||
| assert "4" in response.data.get("text") | ||
|
|
There was a problem hiding this comment.
Fix invalid OpenAI model name.
The model name "gpt-4.1-nano" is not a valid OpenAI model. This will likely cause the test to fail when run with actual API credentials.
Replace with a valid model name from the available OpenAI models:
- model_name="gpt-4.1-nano",
+ model_name="gpt-4o-mini",📝 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.
| @pytest.mark.api_key_required | |
| @pytest.mark.no_blockbuster | |
| async def test_agent_component_with_calculator(self): | |
| # Now you can access the environment variables | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| tools = [CalculatorToolComponent().build_tool()] # Use the Calculator component as a tool | |
| input_value = "What is 2 + 2?" | |
| temperature = 0.1 | |
| # Initialize the AgentComponent with mocked inputs | |
| agent = AgentComponent( | |
| tools=tools, | |
| input_value=input_value, | |
| api_key=api_key, | |
| model_name="gpt-4.1-nano", | |
| llm_type="OpenAI", | |
| temperature=temperature, | |
| _session_id=str(uuid4()), | |
| ) | |
| with ( | |
| patch.object(NoopSession, "add", new_callable=AsyncMock) as mock_add, | |
| patch.object(NoopSession, "commit", new_callable=AsyncMock) as mock_commit, | |
| ): | |
| response = await agent.message_response() | |
| assert mock_add.called | |
| assert mock_commit.called | |
| assert "4" in response.data.get("text") | |
| @pytest.mark.api_key_required | |
| @pytest.mark.no_blockbuster | |
| async def test_agent_component_with_calculator(self): | |
| # Now you can access the environment variables | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| tools = [CalculatorToolComponent().build_tool()] # Use the Calculator component as a tool | |
| input_value = "What is 2 + 2?" | |
| temperature = 0.1 | |
| # Initialize the AgentComponent with mocked inputs | |
| agent = AgentComponent( | |
| tools=tools, | |
| input_value=input_value, | |
| api_key=api_key, | |
| - model_name="gpt-4.1-nano", | |
| + model_name="gpt-4o-mini", | |
| llm_type="OpenAI", | |
| temperature=temperature, | |
| _session_id=str(uuid4()), | |
| ) | |
| with ( | |
| patch.object(NoopSession, "add", new_callable=AsyncMock) as mock_add, | |
| patch.object(NoopSession, "commit", new_callable=AsyncMock) as mock_commit, | |
| ): | |
| response = await agent.message_response() | |
| assert mock_add.called | |
| assert mock_commit.called | |
| assert "4" in response.data.get("text") |
🤖 Prompt for AI Agents
In src/backend/tests/unit/components/agents/test_agent_component.py between
lines 104 and 133, the test uses an invalid OpenAI model name "gpt-4.1-nano"
which will cause failures. Replace "gpt-4.1-nano" with a valid OpenAI model name
such as "gpt-4" or "gpt-3.5-turbo" to ensure the test runs correctly with real
API credentials.
There was a problem hiding this comment.
There was a problem hiding this comment.
🧩 Analysis chain
@ogabrielluiz Thank you for the correction! I need to verify the current status of the GPT-4.1-nano model to provide accurate information.
🌐 Web query:
OpenAI GPT-4.1-nano model availability and documentation 2024 2025
💡 Result:
OpenAI introduced the GPT-4.1 series on April 14, 2025, comprising three models: GPT-4.1, GPT-4.1 mini, and GPT-4.1 nano. These models are designed to enhance coding capabilities, instruction following, and long-context comprehension, supporting up to 1 million tokens. (openai.com)
Availability:
-
API Access: All three models are available exclusively through OpenAI's API. (openai.com)
-
ChatGPT Integration: GPT-4.1 has been integrated into ChatGPT for Plus, Pro, and Team users since May 14, 2025. (help.openai.com)
-
Third-Party Platforms: The models are also accessible via platforms like GitHub Models and Azure OpenAI Service. (github.blog, ai.azure.com)
Documentation:
Comprehensive documentation for the GPT-4.1 series, including details on model performance, pricing, and usage guidelines, is available on OpenAI's official website. (openai.com)
For the most current information and updates, refer to OpenAI's official channels and documentation.
Citations:
- 1: https://openai.com/index/gpt-4-1/?utm_source=openai
- 2: https://openai.com/index/gpt-4-1/?utm_source=openai
- 3: https://help.openai.com/en/articles/9624314-model-release-notes/?utm_source=openai
- 4: https://github.blog/changelog/2025-04-14-gpt-4-1-mini-and-gpt-4-1-nano-are-now-generally-available-in-github-models?utm_source=openai
- 5: https://ai.azure.com/catalog/models/gpt-4.1-nano?utm_source=openai
- 6: https://openai.com/index/gpt-4-1/?utm_source=openai
🌐 Web query:
OpenAI models list GPT-4.1-nano current available models API 2025
💡 Result:
OpenAI has introduced a new family of AI models, including GPT-4.1, GPT-4.1 mini, and GPT-4.1 nano, all available exclusively through OpenAI's API. These models offer significant advancements in coding capabilities, long-context comprehension, and instruction following. Notably, GPT-4.1 supports context windows of up to 1 million tokens, enhancing its ability to process and understand extensive datasets. Additionally, these models operate at a reduced cost compared to previous versions, such as GPT-4.5. (reuters.com)
The GPT-4.1 family is designed to be more effective for powering AI agents, with improved performance in practical applications. OpenAI has announced plans to discontinue the GPT-4.5 preview in the API by July 2025, as the new models offer improved or similar performance. (reuters.com)
These models are currently accessible via OpenAI's API, providing developers with enhanced tools for building AI applications.
OpenAI's GPT-4.1 Models: Enhancements and Availability:
- OpenAI launches new GPT-4.1 models with improved coding, long context comprehension
- OpenAI promises new ChatGPT features this week - all the latest as Sam Altman says 'we've got a lot of good stuff for you'
Citations:
- 1: https://www.reuters.com/technology/artificial-intelligence/openai-launches-new-gpt-41-models-with-improved-coding-long-context-2025-04-14/?utm_source=openai
- 2: https://www.reuters.com/technology/artificial-intelligence/openai-launches-new-gpt-41-models-with-improved-coding-long-context-2025-04-14/?utm_source=openai
- 3: https://www.reuters.com/technology/artificial-intelligence/openai-launches-new-gpt-41-models-with-improved-coding-long-context-2025-04-14/?utm_source=openai
- 4: https://www.techradar.com/news/live/openai-chatgpt-announcements-april-2025?utm_source=openai
@ogabrielluiz You're absolutely right! I apologize for the incorrect assessment. Based on the current documentation, GPT-4.1-nano is indeed a valid OpenAI model.
According to the latest information from OpenAI's official sources:
- GPT-4.1-nano is part of the GPT-4.1 series introduced by OpenAI on April 14, 2025
- The GPT-4.1 family includes three models: GPT-4.1, GPT-4.1 mini, and GPT-4.1 nano
- All models are available exclusively through OpenAI's API
- They offer enhanced coding capabilities, instruction following, and long-context comprehension with support for up to 1 million tokens
- They're accessible via OpenAI's API, GitHub Models, and Azure OpenAI Service
The test code using model_name="gpt-4.1-nano" is correct and should work properly with valid API credentials. Thank you for the correction and for providing the documentation link!
✏️ Learnings added
Learnt from: ogabrielluiz
PR: langflow-ai/langflow#9054
File: src/backend/tests/unit/components/agents/test_agent_component.py:104-133
Timestamp: 2025-07-15T14:37:19.155Z
Learning: The GPT-4.1 series models (GPT-4.1, GPT-4.1 mini, and GPT-4.1 nano) are valid OpenAI models introduced on April 14, 2025, available exclusively through OpenAI's API with enhanced coding capabilities and 1 million token context support.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
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.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
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.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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.464Z
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/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
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.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test both sync and async code paths in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to src/backend/tests/**/*.py : Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
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.464Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Mock external dependencies appropriately in tests.
- Added an internal _NoopResult class to the NoopSession, providing methods `first()`, `all()`, and `one_or_none()` for better handling of no-operation results. - This enhancement improves the usability of NoopSession in testing scenarios by mimicking expected database query behaviors.
- Changed the log level from warning to info for the NOOP database session message in the DatabaseService class. - This adjustment enhances clarity in logging, indicating that all DB operations are disabled without implying an error condition.
- Reformatted the docstring for the custom_component_update function to enhance readability by breaking long lines into multiple lines. - This change improves documentation clarity, making it easier for developers to understand the function's purpose and behavior.
|
@coderabbitai review again, please |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain@ogabrielluiz I'll review this PR that introduces the noop database mode. Let me examine the implementation details first. 🏁 Script executed: Length of output: 25132 🏁 Script executed: Length of output: 7378 Excellent work on implementing the noop database mode! This is a well-structured enhancement that provides clean separation between database-enabled and database-disabled modes. Here's my comprehensive review: 🎯 Overall AssessmentThis implementation is well-designed and thoughtfully executed. The noop database mode provides valuable functionality for testing, demos, and scenarios where database operations need to be disabled. ✅ Strengths1. Comprehensive NoopSession Implementationclass NoopSession:
# Well-structured with nested classes for proper interface compliance
class NoopBind:
class NoopConnect:
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc, tb):
passThe 2. Clean Configuration Managementuse_noop_database: bool = False
"""If True, disables all database operations and uses a no-op session.
Controlled by LANGFLOW_USE_NOOP_DATABASE env variable."""Well-documented configuration with clear environment variable control. 3. Proper Context Management@asynccontextmanager
async def with_session(self):
if self.settings_service.settings.use_noop_database:
logger.info("Running with NOOP database session. All DB operations are disabled.")
yield NoopSession()
else:
async with AsyncSession(self.engine, expire_on_commit=False) as session:
# ... existing logicThe conditional logic is clean and includes helpful logging. 4. Robust Result Handlingclass _NoopResult:
def first(self):
return None
def all(self):
return []
def one_or_none(self):
return NoneThe 🔧 Minor Suggestions for Improvement1. Enhanced Error Handling in NoopSessionConsider adding optional validation to catch potential issues during development: async def execute(self, *args, **kwargs):
if self._debug_mode: # Optional debug flag
logger.debug(f"NoopSession.execute called with: {args}, {kwargs}")
return None2. More Comprehensive _NoopResult MethodsThe class _NoopResult:
def first(self):
return None
def all(self):
return []
def one_or_none(self):
return None
def scalar(self):
return None
def scalars(self):
return []
def fetchone(self):
return None
def fetchall(self):
return []3. Consider Adding Metrics/MonitoringFor production use, you might want to track noop operations: class NoopSession:
def __init__(self):
self._operation_count = 0
async def add(self, *args, **kwargs):
self._operation_count += 1
logger.debug(f"NoopSession: {self._operation_count} operations bypassed")🧪 Testing QualityThe test coverage is excellent: @pytest.mark.usefixtures("use_noop_session")
@pytest.mark.asyncio
async def test_send_message_without_database(monkeypatch):
with (
patch.object(NoopSession, "add", new_callable=AsyncMock) as mock_add,
patch.object(NoopSession, "commit", new_callable=AsyncMock) as mock_commit,
):
# ... test logic
assert mock_add.called
assert mock_commit.calledThe mocking strategy properly verifies that database operations are called even in noop mode. 🔍 Edge Cases Considered1. Utils Result HandlingThe updates to handle different return types from result = await session.exec(stmt)
if hasattr(result, 'first'):
user = result.first()
elif isinstance(result, list):
user = result[0] if result else None
else:
user = NoneThis properly handles both real SQLAlchemy results and noop results. 2. Session Context ManagementThe async context management is properly implemented to ensure compatibility with existing code. 🚀 Integration AssessmentThe implementation integrates seamlessly with the existing codebase:
📋 Final RecommendationThis PR is ready for merge. The implementation is solid, well-tested, and provides valuable functionality for testing and development scenarios. The noop database mode will be particularly useful for:
The code quality is high, the test coverage is comprehensive, and the feature is well-documented. Great work! 🎉 🧠 Learnings used |
- Introduced documentation for the new LANGFLOW_USE_NOOP_DATABASE environment variable, which allows users to enable a no-op database mode, avoiding database connections and operations. - This addition enhances the clarity of configuration options available for Langflow, aiding users in understanding how to run flows without a database.
- Removed the logging statement from the DatabaseService class and added it to the `set_use_noop_database` field validator in the Settings class. - This change centralizes the logging for the NOOP database session, improving code organization and ensuring that the message is logged whenever the setting is applied.
|
Build successful! ✅ |
|
Build successful! ✅ |
Summary by CodeRabbit