PowerScale RAG Connector
The PowerScale RAG Connector is an open-source Python library designed to enhance RAG application performance during data ingestion by skipping files that have already been processed. It leverages PowerScale's unique MetadataIQ capability to identify changed files within the OneFS filesystem and publish this information in an easily consumable format via ElasticSearch.
Developers can integrate the PowerScale RAG Connector directly within a LangChain RAG application as a supported document loader, a LlamaIndex RAG application as a supported reader, or use it independently as a generic Python class.
Workflow
Figure 1: Workflow and integration of how the PowerScale RAG Connector integrates with the LangChain and NVIDIA AI Enterprise Software.
Audience
The intended audience for this document includes software developers, machine learning scientists, and AI developers who will utilize files from PowerScale in the development of a RAG application.
Overview
This guide is divided into two sections: setting up the environment and using the connector. Note that system administration privileges are required for the initial configuration on PowerScale, which may need to be performed by PowerScale administrators.
Terminology
| Term | Definition |
|---|---|
| RAG | Retrieval Augmented Generation. A technique used to take an off the shelf large language model and provide the LLM context to data it has no knowledge of. |
| LangChain | LangChain is an open-source python and javascript framework used to help developers create RAG applications. |
| LlamaIndex | LlamaIndex is an open-source Python framework for building RAG applications. |
| Nvidia NIM Services | Part of Nvidia AI Enterprise, a set of microservices that can optional be used to efficiently chunk and embed files with GPU. The output of this data can be stored in a vector database for a RAG framework to use. |
| NV-Ingest | An Nvidia NIM microservice that will ingest complex office documents files with tables, and figures, and produce chunks and embedding to be stored in a vector database. |
| Chunking | The process of splitting the source file into smaller context aware pieces that can be searched and converted into vectors. Example: a chunk could be every paragraph within a large office document |
| Embedding | Turning a chunk of data into a vector where vector operations such as similarity, can be performed. |
| MetadataIQ | A new feature in PowerScale OneFS 9.10 that will periodically save filesystem metadata to an external database such as Elasticsearch |
| lin | Logical inode number. A unique and stable identifier for a file on PowerScale OneFS, used to track file versions across renames and modifications. |
| PowerScale RAG Connector | An open-source connector that integrates with LangChain or LlamaIndex to improve data ingestion when data resides on PowerScale. |
Installation
Basic installation
pip install powerscale-rag-connector
Install with LangChain dependencies
pip install powerscale-rag-connector[langchain]
Install with LlamaIndex dependencies
pip install powerscale-rag-connector[llamaindex]
Full installation (LangChain + LlamaIndex)
pip install powerscale-rag-connector[all]
Installing NVIDIA Ingest Client
The NvIngest examples use the v2 API. For more information refer to the official NV-Ingest documentation.
pip install nv-ingest-client
Usage
The PowerScale RAG Connector can be used in three ways:
- As a LangChain document loader
- As a LlamaIndex reader
- As a standalone Python class
Using as a LangChain Document Loader
from powerscale_rag_connector import PowerScaleDocumentLoader
loader = PowerScaleDocumentLoader(
es_host_url="https://elasticsearch:9200",
es_index_name="isi-metadataiq-index.cluster.guid",
es_api_key="your-encoded-api-key",
folder_path="/ifs/data"
)
for doc in loader.lazy_load():
print(doc.metadata["source"], doc.metadata["change_types"])
# Checkpoint is saved automatically when the loop completes.
Each returned Document includes source, snapshot, lin, and change_types in its metadata.
Handling Modified Files
The lin field (logical inode number) is a stable file identifier on OneFS that persists across renames and modifications. Use it to remove stale chunks from your vectorstore before re-ingesting a modified file.
for doc in loader.lazy_load():
lin = doc.metadata["lin"]
source = doc.metadata["source"]
change_types = doc.metadata["change_types"]
if "ENTRY_MODIFIED" in change_types:
vectorstore.delete({"lin": lin})
chunks = process_document(source) # your chunking/embedding logic
vectorstore.add(chunks, metadata={"lin": lin, "source": source})
# Checkpoint is saved automatically when the loop completes.
Note on deleted files: MetadataIQ does not emit
ENTRY_DELETEDevents in the current OneFS firmware version.get_deleted_files()raisesNotImplementedErroraccordingly. To handle deletes, you must tracklinvalues in your own application layer and detect when a previously-seenlinstops appearing in results.
Using as a LangChain Unstructured Loader
PowerScaleUnstructuredLoader subclasses langchain-unstructured's UnstructuredLoader, so every partition option of the upstream loader stays available while PowerScale supplies the set of files to parse:
from powerscale_rag_connector import PowerScaleUnstructuredLoader
loader = PowerScaleUnstructuredLoader(
es_host_url="https://elasticsearch:9200",
es_index_name="isi-metadataiq-index.cluster.guid",
es_api_key="your-encoded-api-key",
folder_path="/ifs/data",
# chunking_strategy controls how unstructured partitions each file.
# None (default): each document element is a separate Document object.
# "basic": merge elements into larger contiguous chunks.
# "by_title": chunk at section-title boundaries.
chunking_strategy=None,
)
for doc in loader.lazy_load():
print(doc.metadata["source"], doc.page_content[:80])
# Checkpoint is saved automatically when the loop completes.
Any additional keyword arguments are forwarded to UnstructuredLoader, so upstream
options work unchanged:
loader = PowerScaleUnstructuredLoader(
es_host_url="https://elasticsearch:9200",
es_index_name="isi-metadataiq-index.cluster.guid",
es_api_key="your-encoded-api-key",
folder_path="/ifs/data",
chunking_strategy="by_title",
strategy="hi_res", # forwarded to unstructured
languages=["en", "de"], # forwarded to unstructured
partition_via_api=False, # forwarded to UnstructuredLoader
)
Deprecation note:
langchain-community'sUnstructuredFileLoader(the old loader that accepted amode=parameter) is deprecated and has been replaced bylangchain-unstructured'sUnstructuredLoader.PowerScaleUnstructuredLoaderuses the new loader. The oldmode="single"/mode="elements"parameter does not exist in the new API; usechunking_strategy=instead.
Using as a LlamaIndex Reader
Two LlamaIndex readers are available. PowerScaleSimpleDirectoryReader wraps LlamaIndex's SimpleDirectoryReader filtered to changed files. It supports three mutually exclusive selection scopes: input_dir, input_files, or dataset_name (a MetadataIQ dataset definition in Elasticsearch):
from powerscale_rag_connector import PowerScaleSimpleDirectoryReader
reader = PowerScaleSimpleDirectoryReader(
es_host_url="https://elasticsearch:9200",
es_index_name="isi-metadataiq-index.cluster.guid",
es_api_key="your-encoded-api-key",
input_dir="/ifs/data",
# Alternatively use input_files=[...] or dataset_name="my_dataset"
)
for doc in reader.lazy_load_data():
print(doc.metadata["source"], doc.metadata["change_types"])
# Checkpoint is saved automatically when the loop completes.
PowerScaleUnstructuredReader subclasses LlamaIndex's UnstructuredReader for element-level parsing:
from powerscale_rag_connector import PowerScaleUnstructuredReader
reader = PowerScaleUnstructuredReader(
es_host_url="https://elasticsearch:9200",
es_index_name="isi-metadataiq-index.cluster.guid",
es_api_key="your-encoded-api-key",
folder_path="/ifs/data",
mode="elements", # 'single' keeps the whole file as one Document; 'elements' yields element-level Documents
languages=["en"], # optional OCR language hints
)
documents = reader.load_data()
# Checkpoint is saved automatically after load_data() returns.
Because it subclasses UnstructuredReader, the upstream single-file contract still
works and bypasses PowerScale entirely:
# PowerScale-driven scan (no `file` argument)
documents = reader.load_data()
# Upstream UnstructuredReader behaviour: parse one explicit file, no MetadataIQ query
documents = reader.load_data(file=Path("/ifs/data/report.pdf"))
Common reader/loader parameters
All loaders/readers that parse file content share a PowerScale-specific raise_on_error switch. The default is False for all of them:
raise_on_error(defaultFalse): If a file fails to parse, the error is logged and processing continues with the next file. The checkpoint advances automatically when the scan completes, meaning failed files are not retried on the next run. Set toTrueto re-raise the exception and stop the scan; the checkpoint will not advance, so the next run will retry the same set of files.
Using as a Standalone Path Loader
from powerscale_rag_connector import PowerScalePathLoader
# Initialize the loader
loader = PowerScalePathLoader(
es_host_url="https://elasticsearch:9200",
es_index_name="isi-metadataiq-index.cluster.guid",
es_api_key="your-encoded-api-key",
folder_path="/ifs/data"
)
# Get changed files
for path_info in loader.lazy_load():
print(path_info) # (Path, snapshot, lin, change_types)
# Checkpoint is saved automatically when the loop completes.
Examples
Check out the examples directory for complete usage examples:
- Environment Configuration
- PowerScale LangChain Document Loader
- PowerScale LangChain Unstructured Loader
- PowerScale LlamaIndex Simple Directory Reader
- PowerScale LlamaIndex Unstructured Reader
- PowerScale Path Loader
- PowerScale NVIngest LangChain Document Loader
- PowerScale NVIngest LlamaIndex Simple Directory Reader
- PowerScale NVIngest Path Loader
Components
The connector consists of several modules:
- PowerScalePathLoader: Core module for identifying changed files
- PowerScaleDocumentLoader: Custom DocumentLoader for LangChain integration
- PowerScaleUnstructuredLoader: Custom Loader returning Documents processed by LangChain's UnstructuredLoader
- PowerScaleSimpleDirectoryReader: Custom Simple Directory Reader for LlamaIndex integration
- PowerScaleUnstructuredReader: Custom Loader returning Documents processed by LlamaIndex's UnstructuredReader
Requirements
- Python 3.10+
- Elasticsearch client
- PowerScale OneFS 9.10+ with MetadataIQ configured
- LangChain (optional, for LangChain integration)
- LlamaIndex (optional, for LlamaIndex integration)
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file powerscale_rag_connector-2.0.0.tar.gz.
File metadata
- Download URL: powerscale_rag_connector-2.0.0.tar.gz
- Upload date:
- Size: 141.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26a116cd1407f273d8edcfe478b7bf70d6e046e5d1301523ca7912304415c319
|
|
| MD5 |
30f2cfa9548915800eb0fed445867a58
|
|
| BLAKE2b-256 |
17c803b1297287e73371871a87d0a4767128e0acddb254d3f0930004deaa05ca
|
File details
Details for the file powerscale_rag_connector-2.0.0-py3-none-any.whl.
File metadata
- Download URL: powerscale_rag_connector-2.0.0-py3-none-any.whl
- Upload date:
- Size: 30.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e4903e117dbb745c86238342ded42b7f1c5915cdbb9a5cc5f4a12f8788a22f1
|
|
| MD5 |
61c7f44bc57b4421a5d9b84c0504239e
|
|
| BLAKE2b-256 |
79d7575895f9b7fe262a7dd1ae4313cab7249b5390a2db371a0599d59c6746be
|