""" Module for creating the smart scraper """ from typing import Optional from pydantic import BaseModel from .base_graph import BaseGraph from .abstract_graph import AbstractGraph from ..nodes import ( FetchNode, GenerateAnswerCSVNode ) class CSVScraperGraph(AbstractGraph): """ A class representing a graph for extracting information from CSV files. Attributes: prompt (str): The prompt used to generate an answer. source (str): The source of the data, which can be either a CSV file or a directory containing multiple CSV files. config (dict): Additional configuration parameters needed by some nodes in the graph. Methods: __init__ (prompt: str, source: str, config: dict, schema: Optional[BaseModel] = None): Initializes the CSVScraperGraph with a prompt, source, and configuration. __init__ initializes the CSVScraperGraph class. It requires the user's prompt as input, along with the source of the data (which can be either a single CSV file or a directory containing multiple CSV files), and any necessary configuration parameters. Methods: _create_graph (): Creates the graph of nodes representing the workflow for web scraping. _create_graph generates the web scraping process workflow represented by a directed acyclic graph. This method is used internally to create the scraping pipeline without having to execute it immediately. The result is a BaseGraph instance containing nodes that fetch and process data from a source, and other helper functions. Methods: run () -> str: Executes the web scraping process and returns the answer to the prompt as a string. run runs the CSVScraperGraph class to extract information from a CSV file based on the user's prompt. It requires no additional arguments since all necessary data is stored within the class instance. The method fetches the relevant chunks of text or speech, generates an answer based on these chunks, and returns this answer as a string. """ def __init__(self, prompt: str, source: str, config: dict, schema: Optional[BaseModel] = None): """ Initializes the CSVScraperGraph with a prompt, source, and configuration. """ super().__init__(prompt, config, source, schema) self.input_key = "csv" if source.endswith("csv") else "csv_dir" def _create_graph(self): """ Creates the graph of nodes representing the workflow for web scraping. """ fetch_node = FetchNode( input="csv | csv_dir", output=["doc"], ) generate_answer_node = GenerateAnswerCSVNode( input="user_prompt & (relevant_chunks | doc)", output=["answer"], node_config={ "llm_model": self.llm_model, "additional_info": self.config.get("additional_info"), "schema": self.schema, } ) return BaseGraph( nodes=[ fetch_node, generate_answer_node, ], edges=[ (fetch_node, generate_answer_node) ], entry_point=fetch_node, graph_name=self.__class__.__name__ ) def run(self) -> str: """ Executes the web scraping process and returns the answer to the prompt. """ inputs = {"user_prompt": self.prompt, self.input_key: self.source} self.final_state, self.execution_info = self.graph.execute(inputs) return self.final_state.get("answer", "No answer found.")