apify-haystack 0.1.7__tar.gz → 0.1.8b2__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.
Files changed (25) hide show
  1. apify_haystack-0.1.8b2/CHANGELOG.md +88 -0
  2. apify_haystack-0.1.8b2/CONTRIBUTING.md +70 -0
  3. apify_haystack-0.1.8b2/PKG-INFO +166 -0
  4. apify_haystack-0.1.8b2/README.md +138 -0
  5. apify_haystack-0.1.8b2/pyproject.toml +220 -0
  6. apify_haystack-0.1.8b2/pyproject.toml.orig +173 -0
  7. apify_haystack-0.1.8b2/src/apify_haystack/__init__.py +21 -0
  8. apify_haystack-0.1.8b2/src/apify_haystack/_actor_tool.py +208 -0
  9. apify_haystack-0.1.8b2/src/apify_haystack/_client.py +84 -0
  10. apify_haystack-0.1.8b2/src/apify_haystack/_constants.py +7 -0
  11. apify_haystack-0.1.8b2/src/apify_haystack/_dataset.py +398 -0
  12. apify_haystack-0.1.8b2/src/apify_haystack/_web_search.py +127 -0
  13. apify_haystack-0.1.8b2/src/apify_haystack/py.typed +0 -0
  14. apify_haystack-0.1.7/PKG-INFO +0 -118
  15. apify_haystack-0.1.7/README.md +0 -87
  16. apify_haystack-0.1.7/pyproject.toml +0 -168
  17. apify_haystack-0.1.7/src/apify_haystack/__init__.py +0 -7
  18. apify_haystack-0.1.7/src/apify_haystack/apify_dataset.py +0 -259
  19. apify_haystack-0.1.7/src/apify_haystack/constants.py +0 -2
  20. apify_haystack-0.1.7/src/apify_haystack/examples/apify_actor_call.py +0 -49
  21. apify_haystack-0.1.7/src/apify_haystack/examples/apify_dataset_load.py +0 -31
  22. apify_haystack-0.1.7/src/apify_haystack/examples/crawl_and_process_data.py +0 -84
  23. apify_haystack-0.1.7/src/apify_haystack/examples/instagram_comments_analysis.py +0 -85
  24. apify_haystack-0.1.7/src/apify_haystack/examples/rag_with_crawled_website.py +0 -113
  25. {apify_haystack-0.1.7 → apify_haystack-0.1.8b2}/LICENSE +0 -0
@@ -0,0 +1,88 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ <!-- git-cliff-unreleased-start -->
6
+ ## 0.1.8 - **not yet released**
7
+
8
+ ### 🚀 Features
9
+
10
+ - Add support for Python 3.14 ([#36](https://github.com/apify/apify-haystack/pull/36)) ([fe4abac](https://github.com/apify/apify-haystack/commit/fe4abacc1511b1cbd40d98cd9b5d57ef3b9dcb5a)) by [@vdusek](https://github.com/vdusek)
11
+ - [**breaking**] Migrate to apify-client 3.x ([#47](https://github.com/apify/apify-haystack/pull/47)) ([8358f91](https://github.com/apify/apify-haystack/commit/8358f915c9b320206e7c11b08a4e64d28bac5aad)) by [@vdusek](https://github.com/vdusek), closes [#28](https://github.com/apify/apify-haystack/issues/28)
12
+ - [**breaking**] Migrate to Haystack 3.x ([#39](https://github.com/apify/apify-haystack/pull/39)) ([783706e](https://github.com/apify/apify-haystack/commit/783706eb07e0365efc7f9831de46115028add91f)) by [@vdusek](https://github.com/vdusek)
13
+ - [**breaking**] Create the Apify client in `warm_up` and release it in `close` ([#41](https://github.com/apify/apify-haystack/pull/41)) ([405455c](https://github.com/apify/apify-haystack/commit/405455cba9fcfea6c780c315d5634ee783780029)) by [@vdusek](https://github.com/vdusek)
14
+ - [**breaking**] Take the API token as a Haystack `Secret` and support component serialization ([#42](https://github.com/apify/apify-haystack/pull/42)) ([f52c359](https://github.com/apify/apify-haystack/commit/f52c35978a86dd69cd4d478d396b052ee76b0853)) by [@vdusek](https://github.com/vdusek)
15
+ - Add async support to the components ([#57](https://github.com/apify/apify-haystack/pull/57)) ([3d15741](https://github.com/apify/apify-haystack/commit/3d15741496cdca24441f93806a3bb2d3d61f0e6c)) by [@vdusek](https://github.com/vdusek)
16
+ - Add ApifyWebSearch component ([#58](https://github.com/apify/apify-haystack/pull/58)) ([974f861](https://github.com/apify/apify-haystack/commit/974f8616c1632ccf8bf444e2567534bb1371a936)) by [@vdusek](https://github.com/vdusek)
17
+ - Add ApifyActorTool for Haystack Agents ([#59](https://github.com/apify/apify-haystack/pull/59)) ([96cfedc](https://github.com/apify/apify-haystack/commit/96cfedcb798f59b17f1b97e116e697065020745c)) by [@vdusek](https://github.com/vdusek)
18
+ - [**breaking**] Rename the token parameter to apify_token and read APIFY_TOKEN ([#62](https://github.com/apify/apify-haystack/pull/62)) ([8db8ce3](https://github.com/apify/apify-haystack/commit/8db8ce3bb25dd24add347deec7d5d67b7b6369a8)) by [@vdusek](https://github.com/vdusek)
19
+ - Add a default dataset mapping function ([#64](https://github.com/apify/apify-haystack/pull/64)) ([c25c9a3](https://github.com/apify/apify-haystack/commit/c25c9a3160ca7425737abd52986d756d009df9d8)) by [@vdusek](https://github.com/vdusek)
20
+ - Mark ApifyActorTool output as untrusted external content ([#65](https://github.com/apify/apify-haystack/pull/65)) ([ee93080](https://github.com/apify/apify-haystack/commit/ee930801ccf7ac88ed77be9c27b9dea57a02c038)) by [@vdusek](https://github.com/vdusek)
21
+ - Add a max_total_charge_usd limit to the Actor runs ([#70](https://github.com/apify/apify-haystack/pull/70)) ([83a8184](https://github.com/apify/apify-haystack/commit/83a81847cc4050cabd44183979440ab944350d95)) by [@vdusek](https://github.com/vdusek)
22
+
23
+ ### 🐛 Bug Fixes
24
+
25
+ - Respect input passed to `run` in Actor and task calls ([#33](https://github.com/apify/apify-haystack/pull/33)) ([78a3882](https://github.com/apify/apify-haystack/commit/78a388256a8230d397b135bca4c3d0cbce9c16da)) by [@vdusek](https://github.com/vdusek)
26
+ - [**breaking**] Raise when an Actor or task run does not succeed ([#63](https://github.com/apify/apify-haystack/pull/63)) ([46ef2f2](https://github.com/apify/apify-haystack/commit/46ef2f29aeecda69ab6155eaa76b423fb1b4d28c)) by [@vdusek](https://github.com/vdusek)
27
+
28
+ ### 🚜 Refactor
29
+
30
+ - [**breaking**] Make the constants module private ([#68](https://github.com/apify/apify-haystack/pull/68)) ([8f5dbbd](https://github.com/apify/apify-haystack/commit/8f5dbbd7a4fa0e8c3c7c8036799d40744ee47624)) by [@vdusek](https://github.com/vdusek)
31
+ - [**breaking**] Make all modules private and export the public API from the package root ([#77](https://github.com/apify/apify-haystack/pull/77)) ([4e6ccca](https://github.com/apify/apify-haystack/commit/4e6cccae287999f9ceb72fe9b67c2305b1206113)) by [@vdusek](https://github.com/vdusek)
32
+
33
+ ### ⚙️ Miscellaneous Tasks
34
+
35
+ - [**breaking**] Drop support for Python 3.9 ([#34](https://github.com/apify/apify-haystack/pull/34)) ([d86960d](https://github.com/apify/apify-haystack/commit/d86960dbe3ad794541833680cfd05c3331170c26)) by [@vdusek](https://github.com/vdusek)
36
+ - [**breaking**] Drop support for Python 3.10 ([#35](https://github.com/apify/apify-haystack/pull/35)) ([5b33fe5](https://github.com/apify/apify-haystack/commit/5b33fe53dd722d584461909edc2d7aacfdb686d9)) by [@vdusek](https://github.com/vdusek)
37
+ - [**breaking**] Drop the unused python-dotenv dependency and move examples out of the package ([#43](https://github.com/apify/apify-haystack/pull/43)) ([9b3de5e](https://github.com/apify/apify-haystack/commit/9b3de5e81babcede7d3287fcacf1189f72d02224)) by [@vdusek](https://github.com/vdusek)
38
+
39
+
40
+ <!-- git-cliff-unreleased-end -->
41
+ # Changelog
42
+
43
+ ## [0.1.7](https://github.com/apify/apify-haystack/releases/tag/0.1.7) (2024-12-09)
44
+
45
+ 🐛 Bug Fixes
46
+ - Use CI from crawlee-python to publish to PyPI
47
+
48
+ ## [0.1.6](https://github.com/apify/apify-haystack/releases/tag/0.1.6) (2024-12-09)
49
+
50
+ 🐛 Bug Fixes
51
+ - Fix description in pyproject.toml
52
+
53
+ ## [0.1.5](https://github.com/apify/apify-haystack/releases/tag/0.1.5) (2024-09-04)
54
+
55
+ 🚀 Features
56
+ - Add link to google colab in the README
57
+
58
+ ## [0.1.4](https://github.com/apify/apify-haystack/releases/tag/0.1.4) (2024-09-04)
59
+
60
+ 🚀 Features
61
+ - Allow to add Actor inputs (`run_input`) in the ApifyDatasetFromActorCall.run() method
62
+
63
+ ## [0.1.3](https://github.com/apify/apify-haystack/releases/tag/0.1.3) (2024-08-04)
64
+
65
+ 🚀 Features
66
+ - Update code examples in the documentation
67
+
68
+ ## [0.1.2](https://github.com/apify/apify-haystack/releases/tag/0.1.2) (2024-08-02)
69
+
70
+ 🐛 Bug Fixes
71
+ - Correct examples in the documentation
72
+
73
+ ## [0.1.1](https://github.com/apify/apify-haystack/releases/tag/0.1.1) (2024-07-31)
74
+
75
+ 🐛 Bug Fixes
76
+ - Fixed publication to PyPI
77
+
78
+ ## [0.1.0](https://github.com/apify/apify-haystack/releases/tag/0.1.0) (2024-07-30)
79
+
80
+ 🚀 Features
81
+ - Added support for the Apify-Haystack integration
82
+ - Added code examples
83
+
84
+ ## [0.0.1] (2024-07-25)
85
+
86
+ 🚀 Features
87
+ - Dummy package `apify-haystack` was released on PyPI.
88
+ - Added CI
@@ -0,0 +1,70 @@
1
+ # Development
2
+
3
+ Here you'll find a contributing guide to get started with development.
4
+
5
+ ## Environment
6
+
7
+ For local development, you need a Python version that satisfies `requires-python` in `pyproject.toml`.
8
+
9
+ We use [uv](https://docs.astral.sh/uv/) for project management. Install it and set up your IDE accordingly.
10
+
11
+ We use [Poe the Poet](https://poethepoet.natn.io/) as a task runner, similar to npm scripts in `package.json`. All tasks are defined in `pyproject.toml` under `[tool.poe.tasks]`. Run `uv run poe` to list them with their descriptions, and `uv run poe <task>` to run one.
12
+
13
+ ## Dependencies
14
+
15
+ To install this package with its development dependencies and the pre-commit hooks, run:
16
+
17
+ ```sh
18
+ uv run poe install-dev
19
+ ```
20
+
21
+ ## Code checking
22
+
23
+ To run all code checks (lint, type check, and unit tests), run:
24
+
25
+ ```sh
26
+ uv run poe check-code
27
+ ```
28
+
29
+ We use [ruff](https://docs.astral.sh/ruff/) for linting and formatting, [ty](https://docs.astral.sh/ty/) for type checking, and [pytest](https://docs.pytest.org/) for tests. All of them are configured in `pyproject.toml`, and each has its own task (`lint`, `format`, `type-check`, `unit-tests`).
30
+
31
+ ## Tests
32
+
33
+ Unit tests (`tests/unit`) are isolated from the Apify API. Run them with `uv run poe unit-tests`, or a single test with `uv run pytest tests/unit/<path>.py::<test_name>`.
34
+
35
+ Integration tests (`tests/integration`) run the components against the Apify platform, so they need an Apify API token in the `APIFY_TOKEN` environment variable and are skipped without one. Run them with `uv run poe integration-tests`. They run real Actors on that account, which costs a little. CI runs them on pull requests from this repository and on pushes to `main`, with the test user's token.
36
+
37
+ ## Documentation
38
+
39
+ We adhere to the [Google docstring format](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) for documenting our codebase. Every user-facing class or method is documented. Documentation standards are enforced using [Ruff](https://docs.astral.sh/ruff/).
40
+
41
+ ## Release process
42
+
43
+ Publishing new versions to [PyPI](https://pypi.org/project/apify-haystack) is automated through GitHub Actions.
44
+
45
+ - **Beta releases**: On each commit to the main branch, a new beta release is automatically published. The version number is determined based on the latest release and conventional commits. The beta version suffix is incremented by 1 from the last beta release on PyPI.
46
+ - **Stable releases**: A stable version release may be created by triggering the `Stable release` GitHub Actions workflow. The version number is determined based on the latest release and conventional commits (`auto` release type), or it may be overridden using the `custom` release type.
47
+
48
+ ### Publishing to PyPI manually
49
+
50
+ 1. **Do not do this unless absolutely necessary.** In all conceivable scenarios, you should use the `Stable release` workflow instead.
51
+ 2. **Make sure you know what you're doing.**
52
+ 3. Update the version number by modifying the `version` field under `project` in `pyproject.toml`:
53
+
54
+ ```toml
55
+ [project]
56
+ name = "apify_haystack"
57
+ version = "x.z.y"
58
+ ```
59
+
60
+ 4. Build the package:
61
+
62
+ ```sh
63
+ uv run poe build
64
+ ```
65
+
66
+ 5. Upload to PyPI:
67
+
68
+ ```sh
69
+ uv publish --token YOUR_API_TOKEN
70
+ ```
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: apify_haystack
3
+ Version: 0.1.8b2
4
+ Summary: Apify-haystack integration
5
+ Keywords: apify,crawler,haystack,rag,scraper,scraping
6
+ Author: Apify Technologies s.r.o.
7
+ Author-email: Apify Technologies s.r.o. <support@apify.com>
8
+ License-Expression: Apache-2.0
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: apify-client>=3.3.0,<4.0.0
20
+ Requires-Dist: haystack-ai>=3.0.0,<4.0.0
21
+ Requires-Python: >=3.11
22
+ Project-URL: Homepage, https://apify.com
23
+ Project-URL: Changelog, https://github.com/apify/apify-haystack/blob/main/CHANGELOG.md
24
+ Project-URL: Documentation, https://docs.apify.com/platform/integrations/haystack
25
+ Project-URL: Issue Tracker, https://github.com/apify/apify-haystack/issues
26
+ Project-URL: Repository, https://github.com/apify/apify-haystack
27
+ Description-Content-Type: text/markdown
28
+
29
+ # Apify-Haystack integration
30
+
31
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/apify/apify-haystack/blob/main/LICENSE)
32
+ [![PyPi Package](https://badge.fury.io/py/apify-haystack.svg)](https://badge.fury.io/py/apify-haystack)
33
+ [![Python](https://img.shields.io/pypi/pyversions/apify-haystack)](https://pypi.org/project/apify-haystack)
34
+
35
+ The Apify-Haystack integration allows easy interaction between the [Apify](https://apify.com/) platform and [Haystack](https://haystack.deepset.ai/).
36
+
37
+ Apify is a platform for web scraping, data extraction, and web automation tasks.
38
+ It provides serverless applications called Actors for tasks like crawling websites and scraping Facebook, Instagram, and Google results.
39
+
40
+ Haystack offers an ecosystem of tools for building, managing, and deploying search engines and LLM applications.
41
+
42
+ ## Installation
43
+
44
+ Apify-haystack is available as the [`apify-haystack`](https://pypi.org/project/apify-haystack/) package on PyPI. It requires Python 3.11 or newer and Haystack 3.
45
+
46
+ ```sh
47
+ pip install apify-haystack
48
+ ```
49
+
50
+ ## Components
51
+
52
+ - `ApifyDatasetFromActorCall` runs an Actor, waits for it to finish, and loads its default dataset.
53
+ - `ApifyDatasetFromTaskCall` does the same for a saved Actor task.
54
+ - `ApifyDatasetLoader` loads an existing dataset by its ID.
55
+ - `ApifyWebSearch` searches the web with the [RAG Web Browser](https://apify.com/apify/rag-web-browser) Actor and returns the content of the top result pages.
56
+ - `ApifyActorTool` is a tool for Haystack Agents that runs any Actor and returns its dataset items. It takes its parameters from the Actor's input schema, and it marks the items it hands to the LLM as untrusted external content to guard against prompt injection.
57
+
58
+ The dataset components turn dataset items into Haystack `Document` objects with a mapping function. Without one, they use `default_dataset_mapping_function`, which takes the `markdown` or `text` of website and search Actors with the page `url`, `title`, and `description` as `meta`, and the whole item as JSON for other Actors. Every component also has `run_async`, which `Pipeline.run_async` uses to run it without blocking the event loop. When an Actor or task run finishes with any status other than `SUCCEEDED`, the component raises a `RuntimeError` instead of loading a partial dataset.
59
+
60
+ The components read your Apify API token from the `APIFY_TOKEN` environment variable, or from `APIFY_API_TOKEN` if `APIFY_TOKEN` isn't set. To pass the token differently, use a Haystack `Secret`, for example `apify_token=Secret.from_env_var('MY_APIFY_TOKEN')`.
61
+
62
+ ## Examples
63
+
64
+ ### Crawl a website using Apify's Website Content Crawler and convert it to Haystack Documents
65
+
66
+ You need an Apify account and API token to run this example.
67
+ You can start with a free account at [Apify](https://apify.com/) and get your [API token](https://docs.apify.com/platform/integrations/api).
68
+
69
+ In the example below, set the `APIFY_TOKEN` environment variable and run the script:
70
+
71
+ ```python
72
+ from haystack import Document
73
+
74
+ from apify_haystack import ApifyDatasetFromActorCall
75
+
76
+ actor_id = 'apify/website-content-crawler'
77
+ run_input = {
78
+ 'maxCrawlPages': 3, # limit the number of pages to crawl
79
+ 'startUrls': [{'url': 'https://haystack.deepset.ai/'}],
80
+ }
81
+
82
+
83
+ def dataset_mapping_function(dataset_item: dict) -> Document:
84
+ return Document(content=dataset_item.get('text'), meta={'url': dataset_item.get('url')})
85
+
86
+
87
+ actor = ApifyDatasetFromActorCall(
88
+ actor_id=actor_id, run_input=run_input, dataset_mapping_function=dataset_mapping_function
89
+ )
90
+ print(f'Calling the Apify Actor {actor_id}. Crawling will take some time.')
91
+ print('You can monitor the progress at: https://console.apify.com/actors/runs')
92
+
93
+ dataset = actor.run()['documents']
94
+
95
+ print(f'Loaded {len(dataset)} documents from the Apify Actor {actor_id}:')
96
+ for d in dataset:
97
+ print(d)
98
+ ```
99
+
100
+ ### Search the web
101
+
102
+ `ApifyWebSearch` returns the top result pages as Markdown `Document` objects, with the page `url`, `title`, and `description` in `meta`, and their URLs in `links`:
103
+
104
+ ```python
105
+ from apify_haystack import ApifyWebSearch
106
+
107
+ search = ApifyWebSearch(top_k=3)
108
+ result = search.run(query='What is Haystack?')
109
+
110
+ for document in result['documents']:
111
+ print(document.meta['url'], document.meta['title'])
112
+ ```
113
+
114
+ ### Give an Agent access to an Actor
115
+
116
+ `ApifyActorTool` lets a Haystack `Agent` run an Actor. Limit `dataset_items_limit` to keep the tool output within the model's context window. For pay-per-event Actors, `max_total_charge_usd` caps what each run the Agent starts can cost:
117
+
118
+ ```python
119
+ from haystack.components.agents import Agent
120
+ from haystack.components.generators.chat import OpenAIChatGenerator
121
+ from haystack.dataclasses import ChatMessage
122
+
123
+ from apify_haystack import ApifyActorTool
124
+
125
+ tool = ApifyActorTool('apify/rag-web-browser', dataset_items_limit=3, max_total_charge_usd=0.5)
126
+ agent = Agent(chat_generator=OpenAIChatGenerator(), tools=[tool])
127
+
128
+ result = agent.run([ChatMessage.from_user('What is new in Haystack 3?')])
129
+ print(result['last_message'].text)
130
+ ```
131
+
132
+ ### Save and load a pipeline
133
+
134
+ The components and the tool support Haystack serialization. The token is saved as the name of its environment variable, never as its value. Haystack 3 only loads classes and functions from trusted modules, so allow `apify_haystack` and the module with your mapping function:
135
+
136
+ ```python
137
+ from haystack import Pipeline
138
+
139
+ yaml = pipeline.dumps()
140
+ restored = Pipeline.loads(yaml, allowed_modules=['apify_haystack', 'my_project.mapping'])
141
+ ```
142
+
143
+ ### More examples
144
+
145
+ The [examples directory](https://github.com/apify/apify-haystack/tree/main/examples) has more examples:
146
+
147
+ - Load a dataset from Apify and convert it to a Haystack Document
148
+ - Call [Website Content Crawler](https://apify.com/apify/website-content-crawler) and convert the data into the Haystack Documents
149
+ - Crawl websites, retrieve text content, and store it in the `InMemoryDocumentStore`
150
+ - Retrieval-Augmented Generation (RAG): Extracting text from a website & question answering <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/apify_haystack_rag.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
151
+ - Analyze your Instagram comments' vibe with Apify and Haystack <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/apify_haystack_instagram_comments_analysis.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
152
+
153
+ ## Support
154
+
155
+ If you find any bug or issue, please [submit an issue on GitHub](https://github.com/apify/apify-haystack/issues).
156
+ For questions, you can ask on [Stack Overflow](https://stackoverflow.com/questions/tagged/apify), in GitHub Discussions or you can join our [Discord server](https://discord.com/invite/jyEM2PRvMU).
157
+
158
+ ## Contributing
159
+
160
+ Code contributions are welcome.
161
+ If you have ideas for improvements, submit an issue or create a pull request.
162
+ For contribution guidelines, see [CONTRIBUTING.md](https://github.com/apify/apify-haystack/blob/main/CONTRIBUTING.md).
163
+
164
+ ## License
165
+
166
+ This project is licensed under the Apache License 2.0 - see the [LICENSE](https://github.com/apify/apify-haystack/blob/main/LICENSE) file for details.
@@ -0,0 +1,138 @@
1
+ # Apify-Haystack integration
2
+
3
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/apify/apify-haystack/blob/main/LICENSE)
4
+ [![PyPi Package](https://badge.fury.io/py/apify-haystack.svg)](https://badge.fury.io/py/apify-haystack)
5
+ [![Python](https://img.shields.io/pypi/pyversions/apify-haystack)](https://pypi.org/project/apify-haystack)
6
+
7
+ The Apify-Haystack integration allows easy interaction between the [Apify](https://apify.com/) platform and [Haystack](https://haystack.deepset.ai/).
8
+
9
+ Apify is a platform for web scraping, data extraction, and web automation tasks.
10
+ It provides serverless applications called Actors for tasks like crawling websites and scraping Facebook, Instagram, and Google results.
11
+
12
+ Haystack offers an ecosystem of tools for building, managing, and deploying search engines and LLM applications.
13
+
14
+ ## Installation
15
+
16
+ Apify-haystack is available as the [`apify-haystack`](https://pypi.org/project/apify-haystack/) package on PyPI. It requires Python 3.11 or newer and Haystack 3.
17
+
18
+ ```sh
19
+ pip install apify-haystack
20
+ ```
21
+
22
+ ## Components
23
+
24
+ - `ApifyDatasetFromActorCall` runs an Actor, waits for it to finish, and loads its default dataset.
25
+ - `ApifyDatasetFromTaskCall` does the same for a saved Actor task.
26
+ - `ApifyDatasetLoader` loads an existing dataset by its ID.
27
+ - `ApifyWebSearch` searches the web with the [RAG Web Browser](https://apify.com/apify/rag-web-browser) Actor and returns the content of the top result pages.
28
+ - `ApifyActorTool` is a tool for Haystack Agents that runs any Actor and returns its dataset items. It takes its parameters from the Actor's input schema, and it marks the items it hands to the LLM as untrusted external content to guard against prompt injection.
29
+
30
+ The dataset components turn dataset items into Haystack `Document` objects with a mapping function. Without one, they use `default_dataset_mapping_function`, which takes the `markdown` or `text` of website and search Actors with the page `url`, `title`, and `description` as `meta`, and the whole item as JSON for other Actors. Every component also has `run_async`, which `Pipeline.run_async` uses to run it without blocking the event loop. When an Actor or task run finishes with any status other than `SUCCEEDED`, the component raises a `RuntimeError` instead of loading a partial dataset.
31
+
32
+ The components read your Apify API token from the `APIFY_TOKEN` environment variable, or from `APIFY_API_TOKEN` if `APIFY_TOKEN` isn't set. To pass the token differently, use a Haystack `Secret`, for example `apify_token=Secret.from_env_var('MY_APIFY_TOKEN')`.
33
+
34
+ ## Examples
35
+
36
+ ### Crawl a website using Apify's Website Content Crawler and convert it to Haystack Documents
37
+
38
+ You need an Apify account and API token to run this example.
39
+ You can start with a free account at [Apify](https://apify.com/) and get your [API token](https://docs.apify.com/platform/integrations/api).
40
+
41
+ In the example below, set the `APIFY_TOKEN` environment variable and run the script:
42
+
43
+ ```python
44
+ from haystack import Document
45
+
46
+ from apify_haystack import ApifyDatasetFromActorCall
47
+
48
+ actor_id = 'apify/website-content-crawler'
49
+ run_input = {
50
+ 'maxCrawlPages': 3, # limit the number of pages to crawl
51
+ 'startUrls': [{'url': 'https://haystack.deepset.ai/'}],
52
+ }
53
+
54
+
55
+ def dataset_mapping_function(dataset_item: dict) -> Document:
56
+ return Document(content=dataset_item.get('text'), meta={'url': dataset_item.get('url')})
57
+
58
+
59
+ actor = ApifyDatasetFromActorCall(
60
+ actor_id=actor_id, run_input=run_input, dataset_mapping_function=dataset_mapping_function
61
+ )
62
+ print(f'Calling the Apify Actor {actor_id}. Crawling will take some time.')
63
+ print('You can monitor the progress at: https://console.apify.com/actors/runs')
64
+
65
+ dataset = actor.run()['documents']
66
+
67
+ print(f'Loaded {len(dataset)} documents from the Apify Actor {actor_id}:')
68
+ for d in dataset:
69
+ print(d)
70
+ ```
71
+
72
+ ### Search the web
73
+
74
+ `ApifyWebSearch` returns the top result pages as Markdown `Document` objects, with the page `url`, `title`, and `description` in `meta`, and their URLs in `links`:
75
+
76
+ ```python
77
+ from apify_haystack import ApifyWebSearch
78
+
79
+ search = ApifyWebSearch(top_k=3)
80
+ result = search.run(query='What is Haystack?')
81
+
82
+ for document in result['documents']:
83
+ print(document.meta['url'], document.meta['title'])
84
+ ```
85
+
86
+ ### Give an Agent access to an Actor
87
+
88
+ `ApifyActorTool` lets a Haystack `Agent` run an Actor. Limit `dataset_items_limit` to keep the tool output within the model's context window. For pay-per-event Actors, `max_total_charge_usd` caps what each run the Agent starts can cost:
89
+
90
+ ```python
91
+ from haystack.components.agents import Agent
92
+ from haystack.components.generators.chat import OpenAIChatGenerator
93
+ from haystack.dataclasses import ChatMessage
94
+
95
+ from apify_haystack import ApifyActorTool
96
+
97
+ tool = ApifyActorTool('apify/rag-web-browser', dataset_items_limit=3, max_total_charge_usd=0.5)
98
+ agent = Agent(chat_generator=OpenAIChatGenerator(), tools=[tool])
99
+
100
+ result = agent.run([ChatMessage.from_user('What is new in Haystack 3?')])
101
+ print(result['last_message'].text)
102
+ ```
103
+
104
+ ### Save and load a pipeline
105
+
106
+ The components and the tool support Haystack serialization. The token is saved as the name of its environment variable, never as its value. Haystack 3 only loads classes and functions from trusted modules, so allow `apify_haystack` and the module with your mapping function:
107
+
108
+ ```python
109
+ from haystack import Pipeline
110
+
111
+ yaml = pipeline.dumps()
112
+ restored = Pipeline.loads(yaml, allowed_modules=['apify_haystack', 'my_project.mapping'])
113
+ ```
114
+
115
+ ### More examples
116
+
117
+ The [examples directory](https://github.com/apify/apify-haystack/tree/main/examples) has more examples:
118
+
119
+ - Load a dataset from Apify and convert it to a Haystack Document
120
+ - Call [Website Content Crawler](https://apify.com/apify/website-content-crawler) and convert the data into the Haystack Documents
121
+ - Crawl websites, retrieve text content, and store it in the `InMemoryDocumentStore`
122
+ - Retrieval-Augmented Generation (RAG): Extracting text from a website & question answering <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/apify_haystack_rag.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
123
+ - Analyze your Instagram comments' vibe with Apify and Haystack <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/apify_haystack_instagram_comments_analysis.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
124
+
125
+ ## Support
126
+
127
+ If you find any bug or issue, please [submit an issue on GitHub](https://github.com/apify/apify-haystack/issues).
128
+ For questions, you can ask on [Stack Overflow](https://stackoverflow.com/questions/tagged/apify), in GitHub Discussions or you can join our [Discord server](https://discord.com/invite/jyEM2PRvMU).
129
+
130
+ ## Contributing
131
+
132
+ Code contributions are welcome.
133
+ If you have ideas for improvements, submit an issue or create a pull request.
134
+ For contribution guidelines, see [CONTRIBUTING.md](https://github.com/apify/apify-haystack/blob/main/CONTRIBUTING.md).
135
+
136
+ ## License
137
+
138
+ This project is licensed under the Apache License 2.0 - see the [LICENSE](https://github.com/apify/apify-haystack/blob/main/LICENSE) file for details.