refactor(tests): parameterize template tests and update timeout use#9224
Conversation
…asyncio.wait_for calls Updated the validate_flow_execution function to directly use the client.post and client.get methods with a timeout parameter, improving code readability and maintainability. This change eliminates redundant timeout handling while ensuring consistent timeout values across API calls.
Refactored the template tests in `test_starter_projects.py` to utilize parameterization for better readability and maintainability. Introduced helper functions to retrieve template files and disabled tracing for all tests. Updated individual test methods to validate JSON structure, flow execution, and endpoint validation, ensuring comprehensive coverage of template functionality. This change streamlines the testing process and enhances the robustness of the test suite.
|
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 WalkthroughThis change systematically updates the import paths, module metadata, and code hashes in multiple JSON starter project files, migrating all references from the Changes
Sequence Diagram(s)Omitted due to the nature of the changes (namespace refactoring and metadata updates only). Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
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: 8
🔭 Outside diff range comments (10)
src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (3)
904-921: Stale imports insidePromptComponent.codeblockThe embedded code still imports from the
langflow.*namespace, contradicting the rest of the migration.-from langflow.base.prompts.api_utils import process_prompt_template -from langflow.custom.custom_component.component import Component -from langflow.inputs.inputs import DefaultPromptField -from langflow.io import MessageTextInput, Output, PromptInput -from langflow.schema.message import Message -from langflow.template.utils import update_template_values +from lfx.base.prompts.api_utils import process_prompt_template +from lfx.custom.custom_component.component import Component +from lfx.inputs.inputs import DefaultPromptField +from lfx.io import MessageTextInput, Output, PromptInput +from lfx.schema.message import Message +from lfx.template.utils import update_template_valuesFailing to adjust these will raise
ModuleNotFoundErroronce the old package is gone.
880-883: Updatemodulereferences tolfxnamespace in all starter project JSONsI ran a grep and found 26 leftover
"module": "langflow…"entries across 17 starter project files underinitial_setup/starter_projects. Each must be updated to the newlfxnamespace and itscode_hashregenerated:Example diffs:
- "module": "langflow.components.prompts.prompt.PromptComponent" + "module": "lfx.components.prompts.prompt.PromptComponent"- "module": "langflow.components.data.file.FileComponent" + "module": "lfx.components.data.file.FileComponent"Impacted files (with first occurrence line numbers):
- Basic Prompting.json:410
- Twitter Thread Generator.json:1614
- Text Sentiment Analysis.json:2305
- Vector Store RAG.json:620
- SaaS Pricing.json:120
- SEO Keyword Generator.json:123, 428
- Sequential Tasks Agents.json:1452, 1590, 1731
- Research Agent.json:320, 779, 994, 1126
- Memory Chatbot.json:802
- Invoice Summarizer.json:175
- Image Sentiment Analysis.json:882
- Instagram Copywriter.json:619, 908, 1372
- Meeting Summary.json:474, 1546
- Document Q&A.json:789, 1240
- Blog Writer.json:181
- Custom Component Generator.json:567
You can bulk-find files with:
rg -l '"module": "langflow' src/backend/base/langflow/initial_setup/starter_projectsAfter updating each
"module"entry, run your code-hash generator (e.g. vialangflow initial_setup) to populate the newcode_hashvalues.
1324-1340: Migrate ParserComponent imports to lfx namespaceIn src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json, under the
template.code.valueforParserComponent(around lines 1324–1340), update the import statements:-from langflow.custom import Component -from langflow.io import ( +from lfx.custom import Component +from lfx.io import ( BoolInput, HandleInput, MessageTextInput, MultilineInput, Output, TabInput, ) -from langflow.schema import Data, DataFrame -from langflow.schema.message import Message +from lfx.schema import Data, DataFrame +from lfx.schema.message import MessageThere are no
moduleorcode_hashfields for this component in the JSON, so no further metadata updates are needed.src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (1)
1370-1410: Placeholder API keys bypass validation
The default value"OPENAI_API_KEY"(and equivalents for other providers) is truthy, so the missing-key guard is never triggered. Users will hit runtime auth failures instead of the early, explicit error you intended.- if provider == "OpenAI": - if not self.api_key: + if provider == "OpenAI": + if not self.api_key or self.api_key.strip() == "OPENAI_API_KEY": msg = "OpenAI API key is required when using OpenAI provider" raise ValueError(msg)Repeat the same pattern for Anthropic (
"ANTHROPIC_API_KEY") and Google ("GOOGLE_API_KEY") branches to ensure consistent validation.src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (2)
1239-1241: Inconsistent metadata – FileComponent still points to the old namespace
"module": "langflow.components.data.file.FileComponent"was missed. This breaks lazy-loading and code-preview in the UI.- "module": "langflow.components.data.file.FileComponent" + "module": "lfx.components.data.file.FileComponent"
788-790: PromptComponent metadata & embedded code still uselangflow.*
- Metadata module path:
- "module": "langflow.components.prompts.prompt.PromptComponent" + "module": "lfx.components.prompts.prompt.PromptComponent"
- Embedded code (lines 850-851) imports:
from langflow.*→ should befrom lfx.*Please update both to avoid runtime import errors.
src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json (2)
540-620: Invalidisinstanceusage with union-types → raisesTypeErrorat runtime
isinstance(x, Message | Data | DataFrame | str)(and the similar checks below) is not allowed prior to Python 3.12 – it raises
TypeError: isinstance() arg 2 must be a type or tuple of types.
Use a tuple instead.- if isinstance(item, Message | Data | DataFrame | str) for item in self.input_value + if isinstance(item, (Message, Data, DataFrame, str)) for item in self.input_value … - if not isinstance( - self.input_value, - Message | Data | DataFrame | str | list | Generator | type(None), - ): + if not isinstance( + self.input_value, + (Message, Data, DataFrame, str, list, Generator, type(None)), + ):Failing to fix this will break all flows using Chat Output.
1780-1810: Missing public helperget_component_toolkitThe new code in
AgentComponent._get_tools()does:from lfx.custom.custom_component.component import get_component_toolkit … component_toolkit = get_component_toolkit()However, grep shows only a private function
_get_component_toolkit()is defined and used across the repo:• src/backend/base/langflow/custom/custom_component/component.py:61 defines
_get_component_toolkit()
• Other imports inagent.pyandrun_flow.pyall reference_get_component_toolkitThis mismatch will raise
ImportErrorat runtime.Please update one of the following:
- In
component.py, export the public alias:get_component_toolkit = _get_component_toolkit- Or change all imports in
AgentComponent(and elsewhere) to use_get_component_toolkit.src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json (1)
1030-1055:isinstance()used with union operators breaks at runtimeInside
ChatOutput._validate_inputthe following pattern is repeated:isinstance(item, Message | Data | DataFrame | str)and later
isinstance(self.input_value, Message | Data | DataFrame | str | list | Generator | type(None))
isinstancedoes not accept the PEP-604|union syntax – it raises
TypeError: isinstance() argument 2 cannot be a union. Replace the union with a tuple of types:- isinstance(item, Message | Data | DataFrame | str) + isinstance(item, (Message, Data, DataFrame, str)) - isinstance( - self.input_value, - Message | Data | DataFrame | str | list | Generator | type(None), - ) + isinstance( + self.input_value, + (Message, Data, DataFrame, str, list, Generator, type(None)), + )This is a hard-error that prevents the component from working.
src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json (1)
520-600: Fix invalid use of PEP-604 unions inisinstance
ChatOutput._validate_input()callsisinstance(item, Message | Data | DataFrame | str) ... isinstance(self.input_value, Message | Data | DataFrame | str | list | Generator | type(None))
isinstance/issubclasscannot receive a PEP-604 union; passing one raises
TypeError: isinstance() argument 2 cannot be a union.- if isinstance(item, Message | Data | DataFrame | str) + if isinstance(item, (Message, Data, DataFrame, str)) - if not isinstance( - self.input_value, - Message | Data | DataFrame | str | list | Generator | type(None), - ): + if not isinstance( + self.input_value, + (Message, Data, DataFrame, str, list, Generator, type(None)), + ):Without this fix, every execution path that reaches these checks will crash, breaking the whole starter project.
🧹 Nitpick comments (15)
src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json (1)
258-258: Left-overlangflowreferences?Imports inside the code block have been switched to
lfx.*, 👍.
Make sure no straylangflow.names remain in this snippet (or any other snippet in the file); otherwise the template crashes when executed.Consider adding an alias layer (
lfx.__init__: import importlib, sys; sys.modules["langflow"]=importlib.import_module("lfx")) during the transition to avoid breaking existing user flows.src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json (3)
430-447: Docs URL still references the oldlangflowsite – update or drop.All imports have been migrated to
lfx.*, but thedocumentationstring inside the code still says
"https://docs.langflow.org/components-io#chat-input".
Either move the docs or point to the new location to avoid dead links.- documentation: str = "https://docs.langflow.org/components-io#chat-input" + # TODO: update once the new docs domain is live + documentation: str = "https://docs.lfx.ai/components-io#chat-input"
767-768: Minor:_validate_inputaccepts aGeneratorbutconvert_to_stringpasses it through unchanged.Down-stream components must be ready to handle a generator of unknown length.
If not, consider eagerly consuming or at least documenting the behaviour.
1311-1312: Three copies ofLanguageModelComponentare identical – prefer a shared template.Keeping identical code blobs in every starter flow is a maintenance burden; a single source of truth (importing the component class from
lfx) avoids silent drift.src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json (1)
561-562: Code block migrated tolfx– docs URL now misleadingThe component code now lives under the
lfxpackage, but itsdocumentationstring still points todocs.langflow.org. Update the URL (or add a redirect) to prevent broken “open in docs” links.- documentation: str = "https://docs.langflow.org/components-io#chat-input" + documentation: str = "https://docs.langflow.org/components-io#chat-input" # TODO: update once lfx docs domain is livesrc/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (2)
1339-1339: Minor design quirk in FileComponent :_base_inputsshadowing_base_inputs = deepcopy(BaseFileComponent.get_base_inputs())Defining a class variable with the same name as an attribute used in the base class can be confusing, and it permanently detaches the list from future upstream additions. Prefer a local temp variable (e.g.
_inputs) and keep the finalinputs = [...]source-of-truth, or callget_base_inputs()directly inside the list literal:- _base_inputs = deepcopy(BaseFileComponent.get_base_inputs()) - for input_item in _base_inputs: + _inputs = deepcopy(BaseFileComponent.get_base_inputs()) + for input_item in _inputs: ... - inputs = [*_base_inputs, BoolInput(...), IntInput(...)] + inputs = [*_inputs, BoolInput(...), IntInput(...)]Not critical, but improves clarity and maintainability.
1951-1951: Duplicate LanguageModel component stringSame observation as above for the second LanguageModel node. If both strings are identical, consider deduplicating to avoid drift.
src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (1)
560-620:convert_to_stringdiscards theclean_dataflag for single inputs
When the input is not alist/Generator, the helper is invoked without theclean_dataargument, leading to asymmetric behaviour.- return safe_convert(self.input_value) + return safe_convert(self.input_value, clean_data=self.clean_data)This keeps the output consistent with the list-handling branch.
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (1)
186-202: Embedded code still referencesdocs.langflow.org– branding driftThe snippet has been switched to
lfx.*imports but the documentation URL inside the class still points tohttps://docs.langflow.org/....
If the project is re-branding under thelfxnamespace, you may want to update the link to avoid confusing users.src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (1)
545-547: Optional: tighten the input-validation branch inChatOutputWhen
self.input_valueis aGenerator, the method returns the generator directly. Down-stream components often expect a plainstr; consider eagerly consuming / joining the generator here (or documenting that a generator can propagate).src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json (1)
820-870: Redundant / conflicting keys inpayloadconstruction
daysandtime_rangeare populated twice – first unconditionally, then conditionally.
This means:
- You always send
"days": self.dayseven when the topic is not"news".- The second assignment silently overwrites the first, adding cognitive overhead.
Consider building the dict only once, adding keys conditionally:
- "days": self.days, - "time_range": self.time_range, + # optional parameters are appended belowand remove the unconditional entries.
This keeps the request body minimal and easier to reason about.src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json (2)
1211-1213: Mixedlangflow/lfximports insideSaveToFileComponentAlthough the component itself moved to
lfx.components.processing.save_file.SaveToFileComponent, itscodeblock still imports several services from thelangflownamespace:from langflow.api.v2.files import upload_user_file from langflow.services.auth.utils import create_user_longterm_token from langflow.services.database.models.user.crud import get_user_by_idIf the intention is a complete namespace migration, these cross-package references will re-introduce the old dependency chain. Either:
- Keep the component under the
langflowpackage until all helpers are available underlfx, or- Expose equivalent helpers inside
lfxand update the imports accordingly.Otherwise this starter will raise
ModuleNotFoundErrorwhen used from a pure-lfxenvironment.
268-286: Header still advertiseslangflowinstead oflfxIn
AgentQL.build_outputthe request header sets"X-TF-Request-Origin": "langflow",Consider updating this literal (or making it a constant) so analytics correctly reflect the new branding / package name.
src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json (2)
928-945: Align default timeout between code and templateThe
IntInputdefined inside the embeddedAPIRequestComponentcode setsvalue=30, but the surrounding JSON template below defines:"timeout": { ... "value": 5 }This mismatch makes the initial UI value (5 s) diverge from the component-internal default (30 s). Pick one constant to avoid confusing users and tests.
915-925: Hard-codingUser-Agentstring loses version context
headersdefault is now:value=[{"key": "User-Agent", "value": "Langflow/1.0"}]Consider deriving the value from an actual package
__version__(or dropping it) so downstream analytics/debugging can differentiate Langflow versions.Example:
- {"key": "User-Agent", "value": "Langflow/1.0"} + {"key": "User-Agent", "value": f"Langflow/{lfx.__version__}"}
… JSON files Modified the metadata section in multiple starter project JSON files to reflect updated code hashes and module paths, transitioning from 'lfx' to 'langflow' components. This change enhances consistency across the codebase and ensures that the correct modules are referenced for improved maintainability and clarity.
Modified the commands in the Makefile and CI workflows to include the `-n auto` option for pytest, enabling parallel test execution for the starter project template tests. This change enhances test performance and efficiency across the codebase.
Deleted the news-aggregated.json file
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (52.72%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #9224 +/- ##
==========================================
- Coverage 52.72% 52.72% -0.01%
==========================================
Files 634 634
Lines 43605 43605
Branches 125 125
==========================================
- Hits 22992 22991 -1
- Misses 20563 20564 +1
Partials 50 50
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Yukiyukiyeah
left a comment
There was a problem hiding this comment.
Thank you very much for the refactor! I learned a lot
|
…angflow-ai#9224) * refactor: Simplify flow execution validation by removing unnecessary asyncio.wait_for calls Updated the validate_flow_execution function to directly use the client.post and client.get methods with a timeout parameter, improving code readability and maintainability. This change eliminates redundant timeout handling while ensuring consistent timeout values across API calls. * refactor: Enhance template tests for improved structure and validation Refactored the template tests in `test_starter_projects.py` to utilize parameterization for better readability and maintainability. Introduced helper functions to retrieve template files and disabled tracing for all tests. Updated individual test methods to validate JSON structure, flow execution, and endpoint validation, ensuring comprehensive coverage of template functionality. This change streamlines the testing process and enhances the robustness of the test suite. * refactor: Update project metadata and import paths in starter project JSON files Modified the metadata section in multiple starter project JSON files to reflect updated code hashes and module paths, transitioning from 'lfx' to 'langflow' components. This change enhances consistency across the codebase and ensures that the correct modules are referenced for improved maintainability and clarity. * chore: Update template test commands to utilize parallel execution Modified the commands in the Makefile and CI workflows to include the `-n auto` option for pytest, enabling parallel test execution for the starter project template tests. This change enhances test performance and efficiency across the codebase. * chore: Remove news-aggregated.json file Deleted the news-aggregated.json file * Update test_template_validation.py * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>



Refactored the template tests in
test_starter_projects.pyto utilize parameterization for better readability and maintainability. Introduced helper functions to retrieve template files and disabled tracing for all tests.Summary by CodeRabbit
lfxnamespace instead oflangflow, ensuring consistency across import paths and module references.