apify-haystack 0.0.1a2__tar.gz → 0.0.1a4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: apify_haystack
3
- Version: 0.0.1a2
3
+ Version: 0.0.1a4
4
4
  Summary: Apify-haystack integration
5
5
  Home-page: https://apify.com
6
6
  License: Apache-2.0
@@ -18,6 +18,9 @@ Classifier: Programming Language :: Python :: 3.10
18
18
  Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Topic :: Software Development :: Libraries
21
+ Requires-Dist: apify-client (>=1.7.1,<2.0.0)
22
+ Requires-Dist: haystack-ai (>=2.3.0,<3.0.0)
23
+ Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
21
24
  Project-URL: Changelog, https://github.com/apify/apify-haystack/blob/master/CHANGELOG.md
22
25
  Project-URL: Documentation, https://github.com/apify/apify-haystack
23
26
  Project-URL: Issue Tracker, https://github.com/apify/apify-haystack/issues
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "apify_haystack"
7
- version = "0.0.1a2"
7
+ version = "0.0.1a4"
8
8
  description = "Apify-haystack integration"
9
9
  authors = ["Apify Technologies s.r.o. <support@apify.com>"]
10
10
  homepage = "https://apify.com"
@@ -43,6 +43,9 @@ keywords = [
43
43
  # https://github.com/apify/apify-sdk-python/pull/154.
44
44
  [tool.poetry.dependencies]
45
45
  python = "^3.9"
46
+ apify-client = "^1.7.1"
47
+ haystack-ai = "^2.3.0"
48
+ python-dotenv = "^1.0.1"
46
49
 
47
50
  [tool.poetry.group.dev.dependencies]
48
51
  build = "~1.2.0"
@@ -54,7 +57,7 @@ ruff = "~0.5.0"
54
57
  setuptools = "~70.3.0" # setuptools are used by pytest, but not explicitly required
55
58
 
56
59
  [tool.ruff]
57
- line-length = 150
60
+ line-length = 120
58
61
 
59
62
  [tool.ruff.lint]
60
63
  select = ["ALL"]
@@ -110,6 +113,12 @@ indent-style = "space"
110
113
  "T20", # flake8-print
111
114
  "TRY301", # Abstract `raise` to an inner function
112
115
  ]
116
+ "**/{examples}/*" = [
117
+ "D", # Everything from the pydocstyle
118
+ "INP001", # File {filename} is part of an implicit namespace package, add an __init__.py
119
+ "T20", # flake8-print
120
+ ]
121
+
113
122
 
114
123
  [tool.ruff.lint.flake8-quotes]
115
124
  docstring-quotes = "double"
@@ -139,6 +148,10 @@ warn_return_any = true
139
148
  warn_unreachable = true
140
149
  warn_unused_ignores = true
141
150
 
151
+ [[tool.mypy.overrides]]
152
+ module = "haystack.*"
153
+ ignore_missing_imports = true
154
+
142
155
  [tool.mypy-sortedcollections]
143
156
  ignore_missing_imports = true
144
157
 
@@ -0,0 +1,7 @@
1
+ from importlib import metadata
2
+
3
+ __version__ = metadata.version("apify-haystack")
4
+
5
+ from apify_haystack.apify_dataset import ApifyDatasetFromActorCall, ApifyDatasetLoader
6
+
7
+ __all__ = ["ApifyDatasetLoader", "ApifyDatasetFromActorCall", "ApifyDatasetFromActorCall"]
@@ -0,0 +1,223 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import Callable
5
+
6
+ from apify_client import ApifyClient
7
+ from haystack import component
8
+ from haystack.dataclasses import Document
9
+
10
+ from apify_haystack.constants import HAYSTACK_ATTRIBUTE_USER_AGENT
11
+
12
+
13
+ @component
14
+ class ApifyDatasetLoader:
15
+ """Load datasets produced by the `Apify Actors`.
16
+
17
+ Actors are serverless functions that can be used to scrape, crawl, and extract data from the web.
18
+ For details, see https://docs.apify.com/platform/integrations/haystack
19
+
20
+ Example:
21
+ .. code-block:: python
22
+
23
+ from haystack import Document
24
+
25
+ from apify_haystack import ApifyDatasetLoader
26
+
27
+ def dataset_mapping_function(dataset_item):
28
+ return Document(content=dataset_item.get("text"), meta={"url": dataset_item.get("url")})
29
+
30
+ loader = ApifyDatasetLoader(dataset_id=dataset_id, dataset_mapping_function=dataset_mapping_function)
31
+ dataset = loader.run()
32
+ """
33
+
34
+ def __init__(
35
+ self,
36
+ dataset_id: str,
37
+ dataset_mapping_function: Callable[[dict], Document],
38
+ ) -> None:
39
+ """Initialize the Apify dataset loader.
40
+
41
+ Args:
42
+ dataset_id (str): The ID of the dataset on the Apify platform.
43
+ dataset_mapping_function (Callable): A function that takes a single (an Apify dataset item) and converts
44
+ it to an instance of the Document class.
45
+ """
46
+ self.dataset_id = dataset_id
47
+ self.dataset_mapping_function = dataset_mapping_function
48
+
49
+ # Add a custom user-agent to the httpx client for attribution purposes
50
+ self.client = ApifyClient()
51
+ if httpx_client := getattr(self.client.http_client, "httpx_client", None):
52
+ httpx_client.headers["user-agent"] += f"; {HAYSTACK_ATTRIBUTE_USER_AGENT}"
53
+
54
+ @component.output_types(documents=list[Document])
55
+ def run(self): # type: ignore[no-untyped-def] # noqa: ANN201
56
+ """Load datasets produced by the `Apify Actors`.
57
+
58
+ Type-hint note: the output is not type-hinted, otherwise linting complains
59
+ that `run` method is not haystack a component
60
+ """
61
+ dataset_items = self.client.dataset(self.dataset_id).list_items(clean=True).items
62
+ return {"documents": list(map(self.dataset_mapping_function, dataset_items))}
63
+
64
+
65
+ @component
66
+ class ApifyDatasetFromActorCall:
67
+ """Get Apify dataset by calling Apify Actor.
68
+
69
+ Perform call of Apify actor and load produced dataset.
70
+ For details, see https://docs.apify.com/platform/integrations/haystack
71
+
72
+ To use, you should have the ``apify-client`` python package installed,
73
+ and the environment variable ``APIFY_API_TOKEN`` set with your API key, or pass
74
+ `apify_api_token` as a named parameter to the constructor.
75
+ """
76
+
77
+ def __init__(
78
+ self,
79
+ actor_id: str,
80
+ dataset_mapping_function: Callable[[dict], Document],
81
+ run_input: dict,
82
+ *,
83
+ build: str | None = None,
84
+ memory_mbytes: int | None = None,
85
+ timeout_secs: int | None = None,
86
+ apify_api_token: str | None = None,
87
+ ) -> None:
88
+ """Initialize the Apify Actor loader.
89
+
90
+ Args:
91
+ actor_id (str): The ID or name of the Actor on the Apify platform.
92
+ run_input (Dict): The input object of the Actor that you're trying to run.
93
+ dataset_mapping_function (Callable): A function that takes a single
94
+ dictionary (an Apify dataset item) and converts it to an
95
+ instance of the Document class.
96
+ build (str, optional): Optionally specifies the actor build to run.
97
+ It can be either a build tag or build number.
98
+ memory_mbytes (int, optional): Optional memory limit for the run, in megabytes.
99
+ timeout_secs (int, optional): Optional timeout for the run, in seconds.
100
+ apify_api_token (str, optional): The API token for the Apify platform.
101
+ If not provided, it will be read from the environment
102
+ """
103
+ self.actor_id = actor_id
104
+ self.dataset_mapping_function = dataset_mapping_function
105
+ self.run_input = run_input
106
+ self.build = build
107
+ self.memory_mbytes = memory_mbytes
108
+ self.timeout_secs = timeout_secs
109
+
110
+ if not (apify_api_token := apify_api_token or os.getenv("APIFY_API_TOKEN")):
111
+ raise ValueError(
112
+ "Apify API token not found. Please provide Apify API token when initializing "
113
+ "ApifyDatasetCall, or set the environment variable APIFY_API_TOKEN."
114
+ )
115
+ # Add a custom user-agent to the httpx client for attribution purposes
116
+ self.client = ApifyClient(apify_api_token)
117
+
118
+ if httpx_client := getattr(self.client.http_client, "httpx_client", None):
119
+ httpx_client.headers["user-agent"] += f"; {HAYSTACK_ATTRIBUTE_USER_AGENT}"
120
+
121
+ @component.output_types(documents=list[Document])
122
+ def run(self): # type: ignore[no-untyped-def] # noqa: ANN201
123
+ """Run an Actor on the Apify platform and wait for results to be ready.
124
+
125
+ Type-hint note: the output is not type-hinted, otherwise linting complains
126
+ that `run` method is not haystack a component
127
+ """
128
+ if not (
129
+ actor_call := self.client.actor(self.actor_id).call(
130
+ run_input=self.run_input,
131
+ build=self.build,
132
+ memory_mbytes=self.memory_mbytes,
133
+ timeout_secs=self.timeout_secs,
134
+ )
135
+ ):
136
+ raise ValueError(f"No response found in the actor {self.actor_id} call")
137
+
138
+ if not (dataset_id := actor_call.get("defaultDatasetId")):
139
+ raise ValueError(f"No dataset found in the actor {self.actor_id} call response.")
140
+
141
+ loader = ApifyDatasetLoader(
142
+ dataset_id=dataset_id,
143
+ dataset_mapping_function=self.dataset_mapping_function,
144
+ )
145
+ return loader.run()
146
+
147
+
148
+ @component
149
+ class ApifyDatasetFromTaskCall:
150
+ """Get Apify dataset by calling Apify Task.
151
+
152
+ Perform call of Apify task and load produced dataset.
153
+ """
154
+
155
+ def __init__(
156
+ self,
157
+ task_id: str,
158
+ dataset_mapping_function: Callable[[dict], Document],
159
+ task_input: dict,
160
+ *,
161
+ build: str | None = None,
162
+ memory_mbytes: int | None = None,
163
+ timeout_secs: int | None = None,
164
+ apify_api_token: str | None = None,
165
+ ) -> None:
166
+ """Initialize the Apify Actor loader.
167
+
168
+ Args:
169
+ task_id (str): The ID or name of the Actor on the Apify platform.
170
+ task_input (Dict): The input object of the Actor that you're trying to run.
171
+ dataset_mapping_function (Callable): A function that takes a single
172
+ dictionary (an Apify dataset item) and converts it to an
173
+ instance of the Document class.
174
+ build (str, optional): Optionally specifies the actor build to run.
175
+ It can be either a build tag or build number.
176
+ memory_mbytes (int, optional): Optional memory limit for the run, in megabytes.
177
+ timeout_secs (int, optional): Optional timeout for the run, in seconds.
178
+ apify_api_token (str, optional): The API token for the Apify platform.
179
+ If not provided, it will be read from the environment
180
+ """
181
+ self.task_id = task_id
182
+ self.dataset_mapping_function = dataset_mapping_function
183
+ self.task_input = task_input
184
+ self.build = build
185
+ self.memory_mbytes = memory_mbytes
186
+ self.timeout_secs = timeout_secs
187
+
188
+ if not (apify_api_token := apify_api_token or os.getenv("APIFY_API_TOKEN")):
189
+ raise ValueError(
190
+ "Apify API token not found. Please provide Apify API token when initializing "
191
+ "ApifyDatasetCall, or set the environment variable APIFY_API_TOKEN."
192
+ )
193
+ # Add a custom user-agent to the httpx client for attribution purposes
194
+ self.client = ApifyClient(apify_api_token)
195
+
196
+ if httpx_client := getattr(self.client.http_client, "httpx_client", None):
197
+ httpx_client.headers["user-agent"] += f"; {HAYSTACK_ATTRIBUTE_USER_AGENT}"
198
+
199
+ @component.output_types(documents=list[Document])
200
+ def run(self): # type: ignore[no-untyped-def] # noqa: ANN201
201
+ """Run an Actor on the Apify platform and wait for results to be ready.
202
+
203
+ Type-hint note: the output is not type-hinted, otherwise linting complains
204
+ that `run` method is not haystack a component
205
+ """
206
+ if not (
207
+ actor_call := self.client.task(self.task_id).call(
208
+ task_input=self.task_input,
209
+ build=self.build,
210
+ memory_mbytes=self.memory_mbytes,
211
+ timeout_secs=self.timeout_secs,
212
+ )
213
+ ):
214
+ raise ValueError(f"No response found in the actor {self.task_id} call")
215
+
216
+ if not (dataset_id := actor_call.get("defaultDatasetId")):
217
+ raise ValueError(f"No dataset found in the actor {self.task_id} call response.")
218
+
219
+ loader = ApifyDatasetLoader(
220
+ dataset_id=dataset_id,
221
+ dataset_mapping_function=self.dataset_mapping_function,
222
+ )
223
+ return loader.run()
@@ -0,0 +1,2 @@
1
+ # A custom user-agent for attribution and monitoring purposes
2
+ HAYSTACK_ATTRIBUTE_USER_AGENT = "Origin/haystack"
@@ -0,0 +1,44 @@
1
+ """
2
+ Call Apify Actor and load a dataset to convert it to Haystack Documents.
3
+
4
+ This script demonstrates how to use Apify's Website Content Crawler to scrape text content from a specified website
5
+ and convert the scraped data into Haystack Documents.
6
+
7
+ For example, if you want to crawl and get text content from https://haystack.deepset.ai/, you can use this script
8
+ to call the Apify actor and retrieve the data in a structured format.
9
+
10
+ The script should produce the following output (an example of a single Document):
11
+ ......
12
+ Document(id=a617d376*****, content: 'Introduction to Haystack 2.x)
13
+ Haystack is an open-source framework fo...', meta: {'url': 'https://docs.haystack.deepset.ai/docs/intro'}
14
+ .....
15
+ """
16
+
17
+ from dotenv import load_dotenv
18
+ from haystack import Document
19
+
20
+ from apify_haystack import ApifyDatasetFromActorCall
21
+
22
+ # Sey APIFY-API-TOKEN here or load it from .env file
23
+ apify_token = "" or load_dotenv()
24
+
25
+ actor_id = "apify/website-content-crawler"
26
+ run_input = {
27
+ "maxCrawlPages": 3, # limit the number of pages to crawl
28
+ "startUrls": [{"url": "https://haystack.deepset.ai/"}],
29
+ }
30
+
31
+
32
+ def dataset_mapping_function(dataset_item: dict) -> Document:
33
+ return Document(content=dataset_item.get("text"), meta={"url": dataset_item.get("url")})
34
+
35
+
36
+ actor = ApifyDatasetFromActorCall(
37
+ actor_id=actor_id, run_input=run_input, dataset_mapping_function=dataset_mapping_function
38
+ )
39
+ print(f"Calling Apify actor {actor_id} ... crawling will take some time ...")
40
+ dataset = actor.run().get("documents")
41
+
42
+ print(f"Loaded {len(dataset)} documents from the Apify Actor {actor_id}:")
43
+ for d in dataset:
44
+ print(d)
@@ -0,0 +1,31 @@
1
+ """
2
+ Load a dataset from Apify and convert it to Haystack Documents.
3
+
4
+ This script demonstrates how to load a dataset from Apify and convert it into Haystack Documents.
5
+ Assuming you have run an Apify actor that scraped web pages from https://docs.haystack.deepset.ai/,
6
+ you can use the dataset ID to load the dataset and transform it into a structured format suitable for Haystack.
7
+
8
+ The script should produce the following output (an example of a single Document):
9
+ ......
10
+ Document(id=a617d376*****, content: 'Introduction to Haystack 2.x)
11
+ Haystack is an open-source framework fo...', meta: {'url': 'https://docs.haystack.deepset.ai/docs/intro'}
12
+ .....
13
+ """
14
+
15
+ from haystack import Document
16
+
17
+ from apify_haystack import ApifyDatasetLoader
18
+
19
+ dataset_id = "YOUR-DATASET-ID"
20
+
21
+
22
+ def dataset_mapping_function(dataset_item: dict) -> Document:
23
+ return Document(content=dataset_item.get("text"), meta={"url": dataset_item.get("url")})
24
+
25
+
26
+ loader = ApifyDatasetLoader(dataset_id=dataset_id, dataset_mapping_function=dataset_mapping_function)
27
+ dataset = loader.run().get("documents")
28
+
29
+ print(f"Loaded {len(dataset)} documents from Apify dataset {dataset_id}:")
30
+ for d in dataset:
31
+ print(d)
@@ -0,0 +1,84 @@
1
+ """
2
+ This script demonstrates how to extract content from a website using the Apify actor: Website Content Crawler.
3
+ The content is then cleaned, split into smaller chunks, embedded, and stored in the InMemoryDocumentStore.
4
+
5
+ After the pipeline is executed, the documents are retrieved from the document store using BM25 retrieval.
6
+
7
+ The script should produce the following output (an example of a single Document):
8
+ ......
9
+ Document(id=15a9f391a9f14871675826af8767bd3d2c81d7de1892fd9288b6be0dac26ea89, content: 'Get Started | Haystack
10
+ Haystack is an open-source Python framework that helps developers build LLM-p...',
11
+ meta: {'url': 'https://haystack.deepset.ai/overview/quick-start',
12
+ 'source_id': '2a7263cb668b8353749cc990f487a3feb7a7d7f3abe3e3af3a69772cdecc8200', 'page_number': 1,
13
+ 'split_id': 0, 'split_idx_start': 0, '_split_overlap': ......
14
+ .....
15
+ """
16
+
17
+ import os
18
+
19
+ from dotenv import load_dotenv
20
+ from haystack import Document, Pipeline
21
+ from haystack.components.embedders import OpenAIDocumentEmbedder
22
+ from haystack.components.preprocessors import DocumentCleaner, DocumentSplitter
23
+ from haystack.components.writers import DocumentWriter
24
+ from haystack.document_stores.in_memory import InMemoryDocumentStore
25
+ from haystack.utils.auth import Secret
26
+
27
+ from apify_haystack import ApifyDatasetFromActorCall
28
+
29
+ load_dotenv()
30
+
31
+ # Set APIFY-API-TOKEN here or use it from .env file
32
+ apify_token = "" or os.getenv("APIFY_API_TOKEN")
33
+ openai_api_key = "" or os.getenv("OPENAI_API_KEY")
34
+
35
+ actor_id = "apify/website-content-crawler"
36
+ run_input = {
37
+ "maxCrawlPages": 3, # limit the number of pages to crawl
38
+ "startUrls": [{"url": "https://haystack.deepset.ai/"}],
39
+ }
40
+
41
+
42
+ def dataset_mapping_function(dataset_item: dict) -> Document:
43
+ return Document(content=dataset_item.get("text"), meta={"url": dataset_item.get("url")})
44
+
45
+
46
+ document_loader = ApifyDatasetFromActorCall(
47
+ actor_id=actor_id, run_input=run_input, dataset_mapping_function=dataset_mapping_function
48
+ )
49
+
50
+ document_store = InMemoryDocumentStore()
51
+ print(f"Initialized InMemoryDocumentStore with {document_store.count_documents()} documents")
52
+
53
+ document_cleaner = DocumentCleaner()
54
+ document_splitter = DocumentSplitter(split_by="word", split_length=150, split_overlap=50)
55
+ document_embedder = OpenAIDocumentEmbedder(api_key=Secret.from_token(openai_api_key))
56
+ document_writer = DocumentWriter(document_store)
57
+
58
+ pipe = Pipeline()
59
+ pipe.add_component("document_loader", document_loader)
60
+ pipe.add_component("document_cleaner", document_cleaner)
61
+ pipe.add_component("document_splitter", document_splitter)
62
+ pipe.add_component("document_embedder", document_embedder)
63
+ pipe.add_component("document_writer", document_writer)
64
+
65
+ pipe.connect("document_loader", "document_cleaner")
66
+ pipe.connect("document_cleaner", "document_splitter")
67
+ pipe.connect("document_splitter", "document_embedder")
68
+ pipe.connect("document_embedder", "document_writer")
69
+
70
+ print(
71
+ "Running pipeline the Apify document_loader -> document_cleaner -> document_splitter "
72
+ "-> document_embedder -> document_writer"
73
+ )
74
+ print("Crawling will take some time ...")
75
+ print("You can visit https://console.apify.com/actors/runs to monitor the progress")
76
+
77
+ pipe.run({"document_loader": {}})
78
+
79
+ print(f"Added {document_store.count_documents()} to vector from Website Content Crawler")
80
+
81
+ print("\nRetrieving documents from the document store: query='Haystack'")
82
+ print("query='Haystack'\n")
83
+ for doc in document_store.bm25_retrieval("Haystack", top_k=1):
84
+ print(doc)
@@ -0,0 +1,111 @@
1
+ """
2
+ Retrieval-Augmented Generation (RAG)
3
+
4
+ This script demonstrates how to extract text content from a website, store it in a vector database, and use
5
+ it for question answering.
6
+
7
+ Steps involved:
8
+ - Load environment variables, including API keys.
9
+ - Define the Apify actor and its input parameters for web scraping.
10
+ - Initialize the Apify dataset loader to fetch and process the dataset.
11
+ - Set up the components for the RAG pipeline:
12
+ - Load documents from Apify and store their embeddings in the document store.
13
+ - Define a prompt template for the question-answering task.
14
+ - Build and connect the components in the pipeline.
15
+ - Run the pipeline to answer a sample question and print the response.
16
+
17
+ Expected output:
18
+ question: "What is haystack?"
19
+ ......
20
+ Haystack is an open-source framework for building production-ready LLM applications
21
+ ......
22
+ """
23
+
24
+ import os
25
+
26
+ from dotenv import load_dotenv
27
+ from haystack import Document, Pipeline
28
+ from haystack.components.builders import PromptBuilder
29
+ from haystack.components.embedders import OpenAIDocumentEmbedder, OpenAITextEmbedder
30
+ from haystack.components.generators import OpenAIGenerator
31
+ from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
32
+ from haystack.document_stores.in_memory import InMemoryDocumentStore
33
+ from haystack.utils.auth import Secret
34
+
35
+ from apify_haystack import ApifyDatasetFromActorCall
36
+
37
+ # Set APIFY-API-TOKEN here or use it from .env file
38
+ apify_token = "" or os.getenv("APIFY_API_TOKEN")
39
+ openai_api_key = "" or os.getenv("OPENAI_API_KEY")
40
+ load_dotenv()
41
+
42
+ actor_id = "apify/website-content-crawler"
43
+ run_input = {
44
+ "maxCrawlPages": 1, # limit the number of pages to crawl
45
+ "startUrls": [{"url": "https://haystack.deepset.ai/"}],
46
+ }
47
+
48
+
49
+ def dataset_mapping_function(dataset_item: dict) -> Document:
50
+ return Document(content=dataset_item.get("text"), meta={"url": dataset_item.get("url")})
51
+
52
+
53
+ apify_dataset_loader = ApifyDatasetFromActorCall(
54
+ actor_id=actor_id, run_input=run_input, dataset_mapping_function=dataset_mapping_function
55
+ )
56
+
57
+ # Components
58
+ document_store = InMemoryDocumentStore()
59
+
60
+ docs_embedder = OpenAIDocumentEmbedder(api_key=Secret.from_token(openai_api_key))
61
+ text_embedder = OpenAITextEmbedder(api_key=Secret.from_token(openai_api_key))
62
+ retriever = InMemoryEmbeddingRetriever(document_store)
63
+ generator = OpenAIGenerator(model="gpt-3.5-turbo")
64
+
65
+ # Load documents from Apify
66
+ docs = apify_dataset_loader.run()
67
+ embeddings = docs_embedder.run(docs.get("documents"))
68
+ document_store.write_documents(embeddings["documents"])
69
+
70
+ template = """
71
+ Given the following information, answer the question.
72
+
73
+ Context:
74
+ {% for document in documents %}
75
+ {{ document.content }}
76
+ {% endfor %}
77
+
78
+ Question: {{question}}
79
+ Answer:
80
+ """
81
+
82
+ prompt_builder = PromptBuilder(template=template)
83
+
84
+ # Add components to your pipeline
85
+ pipe = Pipeline()
86
+ pipe.add_component("embedder", text_embedder)
87
+ pipe.add_component("retriever", retriever)
88
+ pipe.add_component("prompt_builder", prompt_builder)
89
+ pipe.add_component("llm", generator)
90
+
91
+ # Now, connect the components to each other
92
+ pipe.connect("embedder.embedding", "retriever.query_embedding")
93
+ pipe.connect("retriever", "prompt_builder.documents")
94
+ pipe.connect("prompt_builder", "llm")
95
+
96
+ question = "What is haystack?"
97
+
98
+ response = pipe.run({"embedder": {"text": question}, "prompt_builder": {"question": question}})
99
+
100
+ print(f"question: {question}")
101
+ print(f"answer: {response['llm']['replies'][0]}")
102
+
103
+ # Other questions
104
+ examples = [
105
+ "Who created Haystack AI?",
106
+ "Are there any upcoming events or community talks?",
107
+ ]
108
+
109
+ for example in examples:
110
+ response = pipe.run({"embedder": {"text": example}, "prompt_builder": {"question": example}})
111
+ print(response["llm"]["replies"][0])
@@ -1,3 +0,0 @@
1
- from importlib import metadata
2
-
3
- __version__ = metadata.version("apify-haystack")