From 16935ec1981b064785409c2a20a4f98fdfaa0d90 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 31 Jul 2023 10:50:49 -0300 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=90=9B=20fix(flow-runner.mdx):=20fix?= =?UTF-8?q?=20broken=20link=20to=20langchain.schema=20module=20in=20import?= =?UTF-8?q?=20statement=20=F0=9F=90=9B=20fix(flow-runner.mdx):=20remove=20?= =?UTF-8?q?unnecessary=20focus=20annotations=20in=20code=20snippets=20?= =?UTF-8?q?=E2=9C=A8=20feat(flow-runner.mdx):=20add=20support=20for=20gett?= =?UTF-8?q?ing=20flow=20by=20name=20instead=20of=20id=20in=20build=20metho?= =?UTF-8?q?d=20=E2=9C=A8=20feat(flow-runner.mdx):=20add=20caution=20about?= =?UTF-8?q?=20unique=20flow=20names=20in=20version=200.4.0=20=E2=9C=A8=20f?= =?UTF-8?q?eat(flow-runner.mdx):=20add=20support=20for=20passing=20documen?= =?UTF-8?q?t=20parameter=20in=20build=20method=20=F0=9F=90=9B=20fix(flow-r?= =?UTF-8?q?unner.mdx):=20remove=20redundant=20Optional=20type=20hint=20for?= =?UTF-8?q?=20document=20parameter=20in=20build=20method=20=F0=9F=90=9B=20?= =?UTF-8?q?fix(flow-runner.mdx):=20remove=20empty=20line=20at=20the=20end?= =?UTF-8?q?=20of=20the=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/examples/flow-runner.mdx | 39 +++++++++++++++++------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/docs/examples/flow-runner.mdx b/docs/docs/examples/flow-runner.mdx index ddcee5f40..846a5b186 100644 --- a/docs/docs/examples/flow-runner.mdx +++ b/docs/docs/examples/flow-runner.mdx @@ -90,7 +90,7 @@ class FlowRunner(CustomComponent): ``` -Second, we will import _`Document`_ from the [*langchain.schema*](https://docs.langchain.com/docs/components/schema/) module. This will be the return type of the _`build`_ method. +Second, we will import _`Document`_ from the [_langchain.schema_](https://docs.langchain.com/docs/components/schema/) module. This will be the return type of the _`build`_ method. --- @@ -120,7 +120,7 @@ Now, let's add the [parameters](focus://11[20:55]) and the [return type](focus:/ --- -```python +```python focus=13:14 from langflow import CustomComponent from langchain.schema import Document @@ -133,9 +133,7 @@ class FlowRunner(CustomComponent): ... def build(self, flow_name: str, document: Document) -> Document: - # focus # List the flows - # focus flows = self.list_flows() ``` @@ -144,7 +142,7 @@ We can now start writing the _`build`_ method. Let's list available flows in "My --- -```python +```python focus=15:18 from langflow import CustomComponent from langchain.schema import Document @@ -159,17 +157,19 @@ class FlowRunner(CustomComponent): def build(self, flow_name: str, document: Document) -> Document: # List the flows flows = self.list_flows() - # focus # Get the flow that matches the selected name - # focus - flow = next(filter(lambda f: f.name == flow_name, flows)) + # You can also get the flow by id + # using self.get_flow(flow_id=flow_id) + flow = self.get_flow(flow_name=flow_name) ``` And retrieve a flow that matches the selected name (we'll make a dropdown input field for the user to choose among flow names). - From version 0.4.0, names are unique, which was not the case in previous versions. This might lead to unexpected results if using flows with the same name. + From version 0.4.0, names are unique, which was not the case in previous + versions. This might lead to unexpected results if using flows with the same + name. --- @@ -190,7 +190,9 @@ class FlowRunner(CustomComponent): # List the flows flows = self.list_flows() # Get the flow that matches the selected name - flow = next(filter(lambda f: f.name == flow_name, flows)) + # You can also get the flow by id + # using self.get_flow(flow_id=flow_id) + flow = self.get_flow(flow_name=flow_name) # focus # Load the flow # focus @@ -220,7 +222,9 @@ class FlowRunner(CustomComponent): # List the flows flows = self.list_flows() # Get the flow that matches the selected name - flow = next(filter(lambda f: f.name == flow_name, flows)) + # You can also get the flow by id + # using self.get_flow(flow_id=flow_id) + flow = self.get_flow(flow_name=flow_name) # Load the flow tweaks = {} flow = self.load_flow(flow.id, tweaks) @@ -255,11 +259,13 @@ class FlowRunner(CustomComponent): } - def build(self, flow_name: str, document: Optional[Document] = None) -> Document: + def build(self, flow_name: str, document: Document) -> Document: # List the flows flows = self.list_flows() # Get the flow that matches the selected name - flow = next(filter(lambda f: f.name == flow_name, flows)) + # You can also get the flow by id + # using self.get_flow(flow_id=flow_id) + flow = self.get_flow(flow_name=flow_name) # Load the flow tweaks = {} flow = self.load_flow(flow.id, tweaks) @@ -282,7 +288,6 @@ Finally, we can add field customizations through the _`build_config`_ method. He Done! This is what our script and custom component look like: -
- - -
\ No newline at end of file + + From 5c42683b40141cf263552af0c7460cd9322d429e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 31 Jul 2023 10:58:02 -0300 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9D=20docs(flow-runner.mdx):=20add?= =?UTF-8?q?=20example=20code=20for=20a=20Flow=20Runner=20custom=20componen?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ℹ️ The example code demonstrates how to create a custom component called "Flow Runner" that runs other flows using a document as input. The code includes the implementation of the `build_config` and `build` methods. ✨ feat(flow-runner.mdx): add example code for a Flow Runner custom component to provide a practical example for users to follow --- docs/docs/examples/flow-runner.mdx | 44 ++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/docs/docs/examples/flow-runner.mdx b/docs/docs/examples/flow-runner.mdx index 846a5b186..ffa4d2e2e 100644 --- a/docs/docs/examples/flow-runner.mdx +++ b/docs/docs/examples/flow-runner.mdx @@ -29,6 +29,48 @@ We will cover how to: - Load a flow using the _`load_flow`_ method. - Configure a dropdown input field using the _`options`_ parameter. +
+ +Example Code + +```python +from langflow import CustomComponent +from langchain.schema import Document + +class FlowRunner(CustomComponent): +display_name = "Flow Runner" +description = "Run other flows using a document as input." + + def build_config(self): + flows = self.list_flows() + flow_names = [f.name for f in flows] + return {"flow_name": {"options": flow_names, + "display_name": "Flow Name", + }, + "document": {"display_name": "Document"} + } + + + def build(self, flow_name: str, document: Document) -> Document: + # List the flows + flows = self.list_flows() + # Get the flow that matches the selected name + # You can also get the flow by id + # using self.get_flow(flow_id=flow_id) + flow = self.get_flow(flow_name=flow_name) + # Load the flow + tweaks = {} + flow = self.load_flow(flow.id, tweaks) + # Get the page_content from the document + page_content = document.page_content + # Use it in the flow + result = flow(page_content) + return Document(page_content=str(result)) + +``` + +
+ ```python @@ -282,8 +324,6 @@ Finally, we can add field customizations through the _`build_config`_ method. He Make sure that the field type is _`str`_ and _`options`_ values are strings. ---- - Done! This is what our script and custom component look like: From e03e306292b8b21b5593340384d79fe51de8065f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 31 Jul 2023 11:46:23 -0300 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9D=20docs(flow-runner.mdx):=20fix?= =?UTF-8?q?=20typo=20in=20line=20141,=20"looks"=20instead=20of=20"look=20l?= =?UTF-8?q?ike"=20=F0=9F=93=9D=20docs(flow-runner.mdx):=20remove=20extra?= =?UTF-8?q?=20blank=20lines=20in=20code=20examples=20for=20better=20readab?= =?UTF-8?q?ility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/examples/flow-runner.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/docs/examples/flow-runner.mdx b/docs/docs/examples/flow-runner.mdx index ffa4d2e2e..f762c38c3 100644 --- a/docs/docs/examples/flow-runner.mdx +++ b/docs/docs/examples/flow-runner.mdx @@ -76,6 +76,7 @@ description = "Run other flows using a document as input." ```python from langflow import CustomComponent + class MyComponent(CustomComponent): display_name = "Custom Component" description = "This is a custom component" @@ -95,6 +96,7 @@ The typical structure of a Custom Component is composed of _`display_name`_ and ```python from langflow import CustomComponent + # focus class FlowRunner(CustomComponent): # focus @@ -141,6 +143,7 @@ from langflow import CustomComponent # focus from langchain.schema import Document + class FlowRunner(CustomComponent): display_name = "Flow Runner" description = "Run other flows using a document as input." @@ -326,7 +329,7 @@ Finally, we can add field customizations through the _`build_config`_ method. He -Done! This is what our script and custom component look like: +Done! This is what our script and custom component looks like:
Date: Mon, 31 Jul 2023 11:48:17 -0300 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=93=9D=20docs(custom.mdx):=20fix=20fo?= =?UTF-8?q?rmatting=20and=20typos=20in=20the=20CustomComponent=20class=20d?= =?UTF-8?q?ocumentation=20=F0=9F=94=80=20docs(custom.mdx):=20merge=20chang?= =?UTF-8?q?es=20from=20the=20CustomComponent=20class=20documentation=20?= =?UTF-8?q?=F0=9F=93=9D=20docs(custom.mdx):=20improve=20readability=20and?= =?UTF-8?q?=20formatting=20in=20the=20CustomComponent=20class=20documentat?= =?UTF-8?q?ion=20=F0=9F=94=80=20docs(custom.mdx):=20merge=20changes=20from?= =?UTF-8?q?=20the=20CustomComponent=20class=20documentation=20=F0=9F=93=9D?= =?UTF-8?q?=20docs(custom.mdx):=20update=20CustomComponent=20class=20docum?= =?UTF-8?q?entation=20with=20additional=20methods=20and=20descriptions=20?= =?UTF-8?q?=F0=9F=94=80=20docs(custom.mdx):=20merge=20changes=20from=20the?= =?UTF-8?q?=20CustomComponent=20class=20documentation=20=F0=9F=93=9D=20doc?= =?UTF-8?q?s(custom.mdx):=20update=20CustomComponent=20class=20documentati?= =?UTF-8?q?on=20with=20corrected=20method=20names=20and=20descriptions=20?= =?UTF-8?q?=F0=9F=94=80=20docs(custom.mdx):=20merge=20changes=20from=20the?= =?UTF-8?q?=20CustomComponent=20class=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/components/custom.mdx | 73 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/docs/docs/components/custom.mdx b/docs/docs/components/custom.mdx index f7f0617d4..8fbb82163 100644 --- a/docs/docs/components/custom.mdx +++ b/docs/docs/components/custom.mdx @@ -20,33 +20,34 @@ For an in-depth explanation of custom components, their rules, and applications, - **Code:** The Python code to define the component. - ## The CustomComponent Class The CustomComponent class serves as the foundation for creating custom components. By inheriting this class, users can create new, configurable components, tailored to their specific requirements. **Methods** -- **build**: This method is required within a Custom Component class. It defines the component's functionality and specifies how it processes input data to produce output data. This method is called when the component is built (i.e., when you click the *Build* ⚡ button in the canvas). +- **build**: This method is required within a Custom Component class. It defines the component's functionality and specifies how it processes input data to produce output data. This method is called when the component is built (i.e., when you click the _Build_ ⚡ button in the canvas). The type annotations of the _`build`_ instance method are used to create the fields of the component. - | Supported Types | - | --------------------------------------------------------- | - | _`str`_, _`int`_, _`float`_, _`bool`_, _`list`_, _`dict`_ | - | _`langchain.chains.base.Chain`_ | - | _`langchain.PromptTemplate`_ | - | _`langchain.llms.base.BaseLLM`_ | - | _`langchain.Tool`_ | - | _`langchain.document_loaders.base.BaseLoader`_ | - | _`langchain.schema.Document`_ | - | _`langchain.text_splitters.TextSplitter`_ | - | _`langchain.vectorstores.base.VectorStore`_ | - | _`langchain.embeddings.base.Embeddings`_ | - | _`langchain.schema.BaseRetriever`_ | + | Supported Types | + | --------------------------------------------------------- | + | _`str`_, _`int`_, _`float`_, _`bool`_, _`list`_, _`dict`_ | + | _`langchain.chains.base.Chain`_ | + | _`langchain.PromptTemplate`_ | + | _`langchain.llms.base.BaseLLM`_ | + | _`langchain.Tool`_ | + | _`langchain.document_loaders.base.BaseLoader`_ | + | _`langchain.schema.Document`_ | + | _`langchain.text_splitters.TextSplitter`_ | + | _`langchain.vectorstores.base.VectorStore`_ | + | _`langchain.embeddings.base.Embeddings`_ | + | _`langchain.schema.BaseRetriever`_ | - Unlike Langchain types, base Python types do not add a [handle](../guidelines/components) to the field by default. To add handles, use the _`input_types`_ key in the _`build_config`_ method. + Unlike Langchain types, base Python types do not add a + [handle](../guidelines/components) to the field by default. To add handles, + use the _`input_types`_ key in the _`build_config`_ method. - **build_config**: Used to define the configuration fields of the component (if applicable). It should always return a dictionary with specific keys representing the field names and corresponding configurations. This method is called when the code is processed (i.e., when you click _Check and Save_ in the code editor). It must follow the format described below: @@ -56,32 +57,30 @@ The CustomComponent class serves as the foundation for creating custom component Below are the available keys used to configure component fields: - | Key | Description | - | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | _`field_type: str`_ | The type of the field (can be any of the types supported by the _`build`_ method). | - | _`is_list: bool`_ | If the field can be a list of values, meaning that the user can manually add more inputs to the same field. | - | _`options: List[str]`_ | When defined, the field becomes a dropdown menu where a list of strings defines the options to be displayed. If the _`value`_ attribute is set to one of the options, that option becomes default. For this parameter to work, _`field_type`_ should invariably be _`str`_. | - | _`multiline: bool`_ | Defines if a string field opens a text editor. Useful for longer texts. | - | _`input_types: List[str]`_ | Used when you want a _`str`_ field to have connectable handles. | - | _`display_name: str`_ | Defines the name of the field. | - | _`advanced: bool`_ | Hide the field in the canvas view (displayed component settings only). Useful when a field is for advanced users. | - | _`password: bool`_ | To mask the input text. Useful to hide sensitive text (e.g. API keys). | - | _`required: bool`_ | Makes the field required. | - | _`info: str`_ | Adds a tooltip to the field. | - | _`file_types: List[str]`_ | This is a requirement if the _`field_type`_ is *file*. Defines which file types will be accepted. For example, *json*, *yaml* or *yml*. | - - + | Key | Description | + | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | _`field_type: str`_ | The type of the field (can be any of the types supported by the _`build`_ method). | + | _`is_list: bool`_ | If the field can be a list of values, meaning that the user can manually add more inputs to the same field. | + | _`options: List[str]`_ | When defined, the field becomes a dropdown menu where a list of strings defines the options to be displayed. If the _`value`_ attribute is set to one of the options, that option becomes default. For this parameter to work, _`field_type`_ should invariably be _`str`_. | + | _`multiline: bool`_ | Defines if a string field opens a text editor. Useful for longer texts. | + | _`input_types: List[str]`_ | Used when you want a _`str`_ field to have connectable handles. | + | _`display_name: str`_ | Defines the name of the field. | + | _`advanced: bool`_ | Hide the field in the canvas view (displayed component settings only). Useful when a field is for advanced users. | + | _`password: bool`_ | To mask the input text. Useful to hide sensitive text (e.g. API keys). | + | _`required: bool`_ | Makes the field required. | + | _`info: str`_ | Adds a tooltip to the field. | + | _`file_types: List[str]`_ | This is a requirement if the _`field_type`_ is _file_. Defines which file types will be accepted. For example, _json_, _yaml_ or _yml_. | - The CustomComponent class also provides helpful methods for specific tasks (e.g., to load and use other flows from the Langflow platform): - | Method Name | Description | - | -------------- | ------------------------------------------------------------- | - | _`list_flows`_ | Returns a list of Flow objects with an _`id`_ and a _`name`_. | - | _`load_flow`_ | Loads a flow from a given _`id`_. | - + | Method Name | Description | + | -------------- | ------------------------------------------------------------------- | + | _`list_flows`_ | Returns a list of Flow objects with an _`id`_ and a _`name`_. | + | _`get_flow`_ | Returns a Flow object. Parameters are _`flow_name`_ or _`flow_id`_. | + | _`load_flow`_ | Loads a flow from a given _`id`_. | Check out the [FlowRunner](../examples/flow-runner) example to understand how to call a flow from a custom component. - \ No newline at end of file +