diff --git a/src/backend/langflow/components/data/APIRequest.py b/src/backend/langflow/components/data/APIRequest.py index b9b3e2c51..a7cc2ac37 100644 --- a/src/backend/langflow/components/data/APIRequest.py +++ b/src/backend/langflow/components/data/APIRequest.py @@ -14,7 +14,7 @@ class APIRequest(CustomComponent): output_types: list[str] = ["Record"] documentation: str = "https://docs.langflow.org/components/utilities#api-request" field_config = { - "url": {"display_name": "URL", "info": "The URL to make the request to."}, + "urls": {"display_name": "URLs", "info": "The URLs to make the request to."}, "method": { "display_name": "Method", "info": "The HTTP method to use.", @@ -116,4 +116,5 @@ class APIRequest(CustomComponent): for u, rec in zip(urls, bodies) ] ) + self.status = results return results diff --git a/src/backend/langflow/components/experimental/ExtractDataFromRecord.py b/src/backend/langflow/components/experimental/ExtractDataFromRecord.py index 926ec025a..55a48f6c1 100644 --- a/src/backend/langflow/components/experimental/ExtractDataFromRecord.py +++ b/src/backend/langflow/components/experimental/ExtractDataFromRecord.py @@ -9,9 +9,39 @@ class ExtractKeyFromRecordComponent(CustomComponent): field_config = { "record": {"display_name": "Record"}, + "keys": { + "display_name": "Keys", + "info": "The keys to extract from the record.", + "input_types": [], + }, + "silent_error": { + "display_name": "Silent Errors", + "info": "If True, errors will not be raised.", + "advanced": True, + }, } - def build(self, record: Record, key: str, silent_error: bool = True) -> dict: - data = getattr(record, key) - self.status = data - return data + def build( + self, record: Record, keys: list[str], silent_error: bool = True + ) -> Record: + """ + Extracts the keys from a record. + + Args: + record (Record): The record from which to extract the keys. + keys (list[str]): The keys to extract from the record. + silent_error (bool): If True, errors will not be raised. + + Returns: + dict: The extracted keys. + """ + extracted_keys = {} + for key in keys: + try: + extracted_keys[key] = getattr(record, key) + except AttributeError: + if not silent_error: + raise KeyError(f"The key '{key}' does not exist in the record.") + return_record = Record(data=extracted_keys) + self.status = return_record + return return_record diff --git a/src/backend/langflow/components/helpers/TextToRecord.py b/src/backend/langflow/components/helpers/TextToRecord.py index 96ac4ad51..396458c5e 100644 --- a/src/backend/langflow/components/helpers/TextToRecord.py +++ b/src/backend/langflow/components/helpers/TextToRecord.py @@ -1,98 +1,25 @@ -from typing import Any, Optional - from langflow import CustomComponent from langflow.schema import Record -from langflow.template.field.base import TemplateField class TextToRecordComponent(CustomComponent): display_name = "Text to Record" - description = "A component to create a record from key-value pairs." - field_order = ["mode", "keys", "n_keys"] + description = "A component to create a record from Text." beta: bool = True - def set_key_template(self, build_config, field_value): - keys_template = TemplateField( - name="n_keys" if field_value == "Number" else "keys", - field_type="dict" if field_value == "Number" else "str", - is_list=False if field_value == "Number" else True, - display_name="Keys", - info=( - "The Number of keys to use for the record." - if field_value == "Number" - else "The keys to use for the record." - ), - input_types=["Text"], - ) - build_config["keys"] = keys_template.to_dict() - - def set_n_keys(self, build_config, field_name, field_value): - if int(field_value) == 0: - keep = ["n_keys", "code"] - for key in build_config.copy(): - if key in keep: - continue - del build_config[key] - build_config[field_name]["value"] = int(field_value) - - # Add new fields depending on the field value - for i in range(int(field_value)): - field = TemplateField( - name=f"Key and Value {i}", - field_type="dict", - display_name="", - info="The key for the record.", - input_types=["Text"], - ) - build_config[field.name] = field.to_dict() - - def set_keys_template(self, build_config, field_value): - for key in build_config.copy(): - if key == "keys": - continue - del build_config[key] - for i in range(int(field_value)): - field = TemplateField( - name=f"Key and Value {i}", - field_type="dict", - display_name="", - info="The key for the record.", - input_types=["Text"], - ) - build_config[field.name] = field.to_dict() - - def update_build_config( - self, - build_config: dict, - field_value: Any, - field_name: Optional[str] = None, - ): - if field_name == "mode": - build_config["mode"]["value"] = field_value - self.set_key_template(build_config, field_value) - if field_value is None: - return - if field_name == "n_keys": - self.set_n_keys(build_config, field_name, field_value) - elif field_name == "keys": - self.set_keys_template(build_config, field_value) - return build_config - def build_config(self): return { - "mode": { - "display_name": "Mode", - "options": ["Text", "Number"], - "info": "The mode to use for creating the record.", - "real_time_refresh": True, - "input_types": [], - }, + "data": { + "display_name": "Data", + "info": "The data to convert to a record.", + "input_types": ["Text"], + } } - def build(self, mode: str, **kwargs) -> Record: - if mode == "Text": - data = kwargs - else: - data = {k: v for key, d in kwargs.items() for k, v in d.items() if key not in ["mode", "n_keys", "keys"]} - record = Record(data=data) - return record + def build( + self, + data: dict, + ) -> Record: + return_record = Record(data=data) + self.status = return_record + return return_record diff --git a/src/backend/langflow/components/helpers/UpdateRecord.py b/src/backend/langflow/components/helpers/UpdateRecord.py new file mode 100644 index 000000000..92c2bae54 --- /dev/null +++ b/src/backend/langflow/components/helpers/UpdateRecord.py @@ -0,0 +1,38 @@ +from langflow import CustomComponent +from langflow.schema import Record + + +class UpdateRecordComponent(CustomComponent): + display_name = "Update Record" + description = "Updates a record with new data." + + def build_config(self): + return { + "record": { + "display_name": "Record", + "info": "The record to update.", + }, + "new_data": { + "display_name": "New Data", + "info": "The new data to update the record with.", + }, + } + + def build( + self, + record: Record, + new_data: dict, + ) -> Record: + """ + Updates a record with new data. + + Args: + record (Record): The record to update. + new_data (dict): The new data to update the record with. + + Returns: + Record: The updated record. + """ + record.data.update(new_data) + self.status = record + return record diff --git a/src/backend/langflow/helpers/record.py b/src/backend/langflow/helpers/record.py index 214215800..d7b1d2b06 100644 --- a/src/backend/langflow/helpers/record.py +++ b/src/backend/langflow/helpers/record.py @@ -30,5 +30,5 @@ def records_to_text(template: str, records: list[Record]) -> str: records = [records] # Check if there are any format strings in the template - formated_records = [template.format(**record.data) for record in records] + formated_records = [template.format(data=record.data, **record.data) for record in records] return "\n".join(formated_records) diff --git a/src/frontend/src/components/keypairListComponent/index.tsx b/src/frontend/src/components/keypairListComponent/index.tsx index 4c09cc802..fcd35e01e 100644 --- a/src/frontend/src/components/keypairListComponent/index.tsx +++ b/src/frontend/src/components/keypairListComponent/index.tsx @@ -54,7 +54,6 @@ export default function KeypairListComponent({ return (