ragpy-core 1.0.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 William Klusman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the “Software”), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: ragpy-core
3
+ Version: 1.0.0
4
+ Summary: A modular Retrieval-Augmented Generation (RAG) pipeline for Python.
5
+ Author: William Klusman
6
+ Author-email: William Klusman <klusmannwilliam@gmail.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2026 William Klusman
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the “Software”), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
+ DEALINGS IN THE SOFTWARE.
28
+ Keywords: RAG,retrieval-augmented-generation,LLM,vector-database,azure-openai,machine-learning,nlp
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Intended Audience :: Science/Research
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.9
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
38
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
39
+ Requires-Python: >=3.9
40
+ Description-Content-Type: text/markdown
41
+ License-File: LICENSE
42
+ Requires-Dist: chromadb>=0.4.0
43
+ Requires-Dist: numpy>=1.20
44
+ Requires-Dist: tiktoken>=0.5.0
45
+ Requires-Dist: requests>=2.0
46
+ Requires-Dist: openai>=1.0.0
47
+ Requires-Dist: pypdf>=4.0.0
48
+ Dynamic: author
49
+ Dynamic: license-file
50
+ Dynamic: requires-python
51
+
52
+ RAGpy
53
+ RAGpy is a lightweight, modular Retrieval-Augmented Generation (RAG) pipeline for Python. It provides a clear and testable architecture for document ingestion, chunking, embedding, retrieval, reranking, context compression, and grounded answer generation using Azure OpenAI and ChromaDB.
54
+
55
+ RAGpy is designed for developers who want a transparent, hackable RAG system without the complexity of large frameworks.
56
+
57
+ Features
58
+ Modular ingestion pipeline for text and PDF documents
59
+
60
+ Chunking and batching utilities for efficient embedding
61
+
62
+ Azure OpenAI embeddings and chat completions
63
+
64
+ ChromaDB vector database integration
65
+
66
+ LLM-based reranking for improved retrieval quality
67
+
68
+ Context compression to reduce token usage
69
+
70
+ Fully monkeypatch-friendly design for offline testing
71
+
72
+ Clean architecture suitable for extension and customization
73
+
74
+ Installation
75
+ Once published to PyPI:
76
+
77
+ Code
78
+ pip install ragpy
79
+ For development:
80
+
81
+ Code
82
+ git clone https://github.com/yourusername/ragpy
83
+ cd ragpy
84
+ pip install -e .
85
+ Quickstart Example
86
+ python
87
+ from ragpy.RAGOrchestrator import IngestFile, GenerateAnswer
88
+ from ragpy.VectorDatabase import OpenDatabase
89
+
90
+ OpenDatabase("AeroDB", "./vectorDB")
91
+ IngestFile("engine_vibration.pdf", "AeroDB")
92
+
93
+ answer = GenerateAnswer("What causes engine vibration?", "AeroDB")
94
+ print(answer)
95
+ How RAGpy Works
96
+ 1. Ingestion
97
+ Load text or PDF using FileLoader
98
+
99
+ Chunk text using TextChunker
100
+
101
+ Batch chunks using ChunkBatcher
102
+
103
+ Generate embeddings with Azure OpenAI
104
+
105
+ Store vectors and metadata in ChromaDB
106
+
107
+ 2. Retrieval
108
+ Embed the user query
109
+
110
+ Retrieve top-K candidates from the vector database
111
+
112
+ 3. Reranking
113
+ Use an LLM-based reranker to reorder retrieved chunks by relevance
114
+
115
+ 4. Compression
116
+ Summarize top chunks into a compact context block
117
+
118
+ 5. Answer Generation
119
+ Build a prompt using compressed context
120
+
121
+ Generate a grounded answer using Azure OpenAI
122
+
123
+ Project Structure
124
+ Code
125
+ ragpy/
126
+ AzureOpenAIRelay.py
127
+ RAGOrchestrator.py
128
+ VectorDatabase.py
129
+ Reranker.py
130
+ ChunkCompressor.py
131
+ loaders/
132
+ FileLoader.py
133
+ TextChunker.py
134
+ batching/
135
+ ChunkBatcher.py
136
+ tests/
137
+ docs/
138
+ Requirements
139
+ Python 3.9+
140
+
141
+ ChromaDB
142
+
143
+ numpy
144
+
145
+ tiktoken
146
+
147
+ pypdf
148
+
149
+ openai (Azure OpenAI SDK)
150
+
151
+ Testing
152
+ RAGpy includes a full pytest suite. All Azure calls are monkeypatch-friendly, allowing offline testing with mock LLMs.
153
+
154
+ Run tests:
155
+
156
+ Code
157
+ pytest -q
158
+ Contributing
159
+ Contributions are welcome.
160
+ Please open an issue or submit a pull request on GitHub.
161
+
162
+ Planned enhancements include:
163
+
164
+ Local embedding support (sentence-transformers)
165
+
166
+ Hybrid retrieval (vector + keyword)
167
+
168
+ Multimodal RAG (image + text)
169
+
170
+ Evaluation tools for relevance and faithfulness
171
+
172
+ Agentic RAG extensions
173
+
174
+ License
175
+ RAGpy is released under the MIT License.
@@ -0,0 +1,124 @@
1
+ RAGpy
2
+ RAGpy is a lightweight, modular Retrieval-Augmented Generation (RAG) pipeline for Python. It provides a clear and testable architecture for document ingestion, chunking, embedding, retrieval, reranking, context compression, and grounded answer generation using Azure OpenAI and ChromaDB.
3
+
4
+ RAGpy is designed for developers who want a transparent, hackable RAG system without the complexity of large frameworks.
5
+
6
+ Features
7
+ Modular ingestion pipeline for text and PDF documents
8
+
9
+ Chunking and batching utilities for efficient embedding
10
+
11
+ Azure OpenAI embeddings and chat completions
12
+
13
+ ChromaDB vector database integration
14
+
15
+ LLM-based reranking for improved retrieval quality
16
+
17
+ Context compression to reduce token usage
18
+
19
+ Fully monkeypatch-friendly design for offline testing
20
+
21
+ Clean architecture suitable for extension and customization
22
+
23
+ Installation
24
+ Once published to PyPI:
25
+
26
+ Code
27
+ pip install ragpy
28
+ For development:
29
+
30
+ Code
31
+ git clone https://github.com/yourusername/ragpy
32
+ cd ragpy
33
+ pip install -e .
34
+ Quickstart Example
35
+ python
36
+ from ragpy.RAGOrchestrator import IngestFile, GenerateAnswer
37
+ from ragpy.VectorDatabase import OpenDatabase
38
+
39
+ OpenDatabase("AeroDB", "./vectorDB")
40
+ IngestFile("engine_vibration.pdf", "AeroDB")
41
+
42
+ answer = GenerateAnswer("What causes engine vibration?", "AeroDB")
43
+ print(answer)
44
+ How RAGpy Works
45
+ 1. Ingestion
46
+ Load text or PDF using FileLoader
47
+
48
+ Chunk text using TextChunker
49
+
50
+ Batch chunks using ChunkBatcher
51
+
52
+ Generate embeddings with Azure OpenAI
53
+
54
+ Store vectors and metadata in ChromaDB
55
+
56
+ 2. Retrieval
57
+ Embed the user query
58
+
59
+ Retrieve top-K candidates from the vector database
60
+
61
+ 3. Reranking
62
+ Use an LLM-based reranker to reorder retrieved chunks by relevance
63
+
64
+ 4. Compression
65
+ Summarize top chunks into a compact context block
66
+
67
+ 5. Answer Generation
68
+ Build a prompt using compressed context
69
+
70
+ Generate a grounded answer using Azure OpenAI
71
+
72
+ Project Structure
73
+ Code
74
+ ragpy/
75
+ AzureOpenAIRelay.py
76
+ RAGOrchestrator.py
77
+ VectorDatabase.py
78
+ Reranker.py
79
+ ChunkCompressor.py
80
+ loaders/
81
+ FileLoader.py
82
+ TextChunker.py
83
+ batching/
84
+ ChunkBatcher.py
85
+ tests/
86
+ docs/
87
+ Requirements
88
+ Python 3.9+
89
+
90
+ ChromaDB
91
+
92
+ numpy
93
+
94
+ tiktoken
95
+
96
+ pypdf
97
+
98
+ openai (Azure OpenAI SDK)
99
+
100
+ Testing
101
+ RAGpy includes a full pytest suite. All Azure calls are monkeypatch-friendly, allowing offline testing with mock LLMs.
102
+
103
+ Run tests:
104
+
105
+ Code
106
+ pytest -q
107
+ Contributing
108
+ Contributions are welcome.
109
+ Please open an issue or submit a pull request on GitHub.
110
+
111
+ Planned enhancements include:
112
+
113
+ Local embedding support (sentence-transformers)
114
+
115
+ Hybrid retrieval (vector + keyword)
116
+
117
+ Multimodal RAG (image + text)
118
+
119
+ Evaluation tools for relevance and faithfulness
120
+
121
+ Agentic RAG extensions
122
+
123
+ License
124
+ RAGpy is released under the MIT License.
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ragpy-core"
7
+ version = "1.0.0"
8
+ description = "A modular Retrieval-Augmented Generation (RAG) pipeline for Python."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { file = "LICENSE" }
12
+
13
+ authors = [
14
+ { name = "William Klusman", email = "klusmannwilliam@gmail.com" }
15
+ ]
16
+
17
+ keywords = [
18
+ "RAG",
19
+ "retrieval-augmented-generation",
20
+ "LLM",
21
+ "vector-database",
22
+ "azure-openai",
23
+ "machine-learning",
24
+ "nlp"
25
+ ]
26
+
27
+ classifiers = [
28
+ "Development Status :: 3 - Alpha",
29
+ "Intended Audience :: Developers",
30
+ "Intended Audience :: Science/Research",
31
+ "License :: OSI Approved :: MIT License",
32
+ "Programming Language :: Python :: 3",
33
+ "Programming Language :: Python :: 3.9",
34
+ "Programming Language :: Python :: 3.10",
35
+ "Programming Language :: Python :: 3.11",
36
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
37
+ "Topic :: Software Development :: Libraries :: Python Modules"
38
+ ]
39
+
40
+ dependencies = [
41
+ "chromadb>=0.4.0",
42
+ "numpy>=1.20",
43
+ "tiktoken>=0.5.0",
44
+ "requests>=2.0",
45
+ "openai>=1.0.0",
46
+ "pypdf>=4.0.0"
47
+ ]
48
+
49
+ [project.urls]
50
+
51
+ [tool.setuptools]
52
+ packages = ["ragpy-core"]
53
+
54
+ [tool.setuptools.package-data]
55
+ ragpy = ["*.txt", "*.md"]
@@ -0,0 +1,206 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Azure OpenAI relay utilities for the RAGpy pipeline.
4
+
5
+ This module provides a thin, deterministic wrapper around the Azure OpenAI
6
+ Python SDK. It exposes simple embedding and chat‑completion functions used
7
+ throughout the RAG workflow, while keeping configuration isolated and
8
+ monkeypatch‑friendly for unit testing.
9
+
10
+ Two independent clients are supported:
11
+ • Embedding client — for generating text embeddings.
12
+ • Chat completion client — for LLM‑based scoring, compression, and
13
+ answer generation.
14
+
15
+ The relay is intentionally minimal to ensure predictable behavior and easy
16
+ replacement during offline tests.
17
+
18
+ """
19
+ from openai import AzureOpenAI
20
+
21
+ #new Azure OpenAI SDK
22
+ embedding_Client = None
23
+ chat_Client = None
24
+ embedding_Deployment = None
25
+ completion_Deployment = None
26
+
27
+ def SetCompletionEndpointInfo(completion_Endpoint, completion_Deployment_Name, completion_Api_Version, api_Key):
28
+ """
29
+ Configure the Azure OpenAI chat completion client.
30
+
31
+ This sets up the client used for all LLM‑based operations in the RAG
32
+ pipeline, including reranking, compression, and final answer generation.
33
+
34
+ Args:
35
+ completion_Endpoint (str):
36
+ The Azure endpoint URL for chat completions.
37
+ completion_Deployment_Name (str):
38
+ The name of the deployed chat model.
39
+ completion_Api_Version (str):
40
+ The API version to use.
41
+ api_Key (str):
42
+ The Azure OpenAI API key.
43
+
44
+ Returns:
45
+ None
46
+ """
47
+ global chat_Client, completion_Deployment
48
+ completion_Deployment = completion_Deployment_Name
49
+
50
+ chat_Client = AzureOpenAI(
51
+ azure_endpoint=completion_Endpoint,
52
+ api_version=completion_Api_Version,
53
+ api_key=api_Key
54
+
55
+ )
56
+
57
+ return
58
+
59
+ def SetEmbeddingEndpointInfo(embedding_Endpoint, embedding_Deployment_Name, embedding_Api_Version, azure_Api_Key):
60
+ """
61
+ Configure the Azure OpenAI embedding client.
62
+
63
+ This sets up the client used for generating embeddings during ingestion
64
+ and query processing.
65
+
66
+ Args:
67
+ embedding_Endpoint (str):
68
+ The Azure endpoint URL for embeddings.
69
+ embedding_Deployment_Name (str):
70
+ The name of the deployed embedding model.
71
+ embedding_Api_Version (str):
72
+ The API version to use.
73
+ azure_Api_Key (str):
74
+ The Azure OpenAI API key.
75
+
76
+ Returns:
77
+ None
78
+ """
79
+ global embedding_Client, embedding_Deployment
80
+ embedding_Deployment = embedding_Deployment_Name
81
+
82
+ embedding_Client = AzureOpenAI(
83
+ azure_endpoint=embedding_Endpoint,
84
+ api_version=embedding_Api_Version,
85
+ api_key = azure_Api_Key
86
+ )
87
+
88
+ return
89
+
90
+ def EmbedText(text):
91
+ """
92
+ Generate an embedding vector for a single text string.
93
+
94
+ Args:
95
+ text (str):
96
+ The input text to embed.
97
+
98
+ Returns:
99
+ list[float]:
100
+ A 3072‑dimensional embedding vector produced by the configured
101
+ Azure OpenAI embedding model.
102
+
103
+ Raises:
104
+ ValueError:
105
+ If the returned embedding dimension is unexpected.
106
+
107
+ Notes:
108
+ - This function is intentionally simple to support monkeypatching
109
+ during unit tests.
110
+ - The embedding client must be configured before calling this
111
+ function.
112
+ """
113
+ vector = embedding_Client.embeddings.create(
114
+ model=embedding_Deployment,
115
+ input=text
116
+ ).data[0].embedding
117
+
118
+ if len(vector) != 3072:
119
+ raise ValueError(f"Unexpected embedding dimension: {len(vector)}")
120
+
121
+ return vector
122
+
123
+ def EmbedChunksInBatches(batched_chunks, batch_size=16):
124
+ """
125
+ Embed multiple batches of text chunks.
126
+
127
+ Each batch is sent to the embedding model as a single request, and all
128
+ resulting vectors are returned in a flat list (one embedding per chunk).
129
+
130
+ Args:
131
+ batched_chunks (list[list[str]]):
132
+ A list of batches, each containing text chunks.
133
+ batch_size (int):
134
+ Optional batch size hint (unused but kept for compatibility).
135
+
136
+ Returns:
137
+ list[list[float]]:
138
+ A flat list of embedding vectors, one per chunk.
139
+
140
+ Notes:
141
+ - Ordering is preserved: embeddings appear in the same order as
142
+ the input chunks.
143
+ - This function is intentionally simple to support monkeypatching.
144
+ """
145
+ all_vectors = []
146
+
147
+ for batch in batched_chunks:
148
+ response = embedding_Client.embeddings.create(
149
+ model=embedding_Deployment,
150
+ input=batch
151
+ )
152
+
153
+ for item in response.data:
154
+ all_vectors.append(item.embedding)
155
+
156
+ return all_vectors
157
+
158
+ def ChatCompletion(prompt):
159
+ """
160
+ Generate a chat completion response using the configured Azure OpenAI client.
161
+
162
+ Args:
163
+ prompt (str):
164
+ The user prompt to send to the model.
165
+
166
+ Returns:
167
+ str:
168
+ The model's response text. Returns an empty string if no chat
169
+ client is configured.
170
+
171
+ Notes:
172
+ - This function is intentionally simple to support monkeypatching
173
+ during unit tests.
174
+ - No additional formatting or metadata is returned.
175
+ """
176
+ client = GetChatClient()
177
+ if client is None:
178
+ # In tests, FakeChat will override this entirely.
179
+ return ""
180
+
181
+ response = client.chat.completions.create(
182
+ model=GetChatModel(),
183
+ messages=[{"role": "user", "content": prompt}]
184
+ )
185
+
186
+ return response.choices[0].message.content
187
+
188
+ def GetChatClient():
189
+ """
190
+ Retrieve the configured Azure OpenAI chat client.
191
+
192
+ Returns:
193
+ AzureOpenAI | None:
194
+ The chat client instance, or None if not configured.
195
+ """
196
+ return chat_Client
197
+
198
+ def GetChatModel():
199
+ """
200
+ Retrieve the configured chat model deployment name.
201
+
202
+ Returns:
203
+ str | None:
204
+ The model deployment name, or None if not configured.
205
+ """
206
+ return completion_Deployment
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ LLM-based context compressor for the RAGpy pipeline.
4
+
5
+ This module provides a lightweight, deterministic interface for reducing
6
+ multiple retrieved chunks into a single compact summary. The compressor
7
+ uses AzureOpenAIRelay to generate a concise, query‑aware context block
8
+ that preserves meaning while reducing token usage. The design is
9
+ intentionally simple to support both production usage and easy
10
+ monkeypatching during unit tests.
11
+
12
+ """
13
+ from ragpy import AzureOpenAIRelay as AI
14
+
15
+ def CompressChunks(query, chunks):
16
+ """
17
+ Compress a list of retrieved chunks into a shorter, unified context block.
18
+
19
+ This function sends the provided chunks and user query to an LLM,
20
+ requesting a concise summary that preserves the information most
21
+ relevant to the query. It is primarily used to reduce token usage
22
+ during prompt construction while maintaining grounding in the
23
+ retrieved content.
24
+
25
+ Args:
26
+ query (str):
27
+ The user query that determines what information is relevant.
28
+ chunks (list[dict]):
29
+ A list of chunk objects, each containing at least a "chunk"
30
+ field (or "text") holding the raw text to be compressed.
31
+
32
+ Returns:
33
+ str:
34
+ A compressed context string. Returns an empty string if the
35
+ compression model is not configured or returns no output.
36
+
37
+ Notes:
38
+ - The function is intentionally simple to allow monkeypatching
39
+ during unit tests.
40
+ - The compression prompt is defined inline for clarity and
41
+ isolation.
42
+ - If AzureOpenAIRelay is not configured, the function safely
43
+ returns an empty string.
44
+ """
45
+ # If monkeypatched, FakeCompress will run instead of this function.
46
+ if AI.GetChatClient() is None:
47
+ return ""
48
+
49
+ text = "\n\n".join(c.get("chunk") or c.get("text", "") for c in chunks)
50
+
51
+ prompt = f"""
52
+ You are a compression model. Your job is to compress the following text
53
+ into a concise summary that preserves meaning and focuses on information
54
+ relevant to the user query:
55
+
56
+ Query:
57
+ {query}
58
+
59
+ {text}
60
+
61
+ Return ONLY the compressed summary.
62
+ """
63
+
64
+ return AI.ChatCompletion(prompt)