rag-core-api 3.2.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.
- rag_core_api-3.2.0/PKG-INFO +31 -0
- rag_core_api-3.2.0/pyproject.toml +126 -0
- rag_core_api-3.2.0/src/rag_core_api/api_endpoints/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/api_endpoints/chat.py +28 -0
- rag_core_api-3.2.0/src/rag_core_api/api_endpoints/information_piece_remover.py +27 -0
- rag_core_api-3.2.0/src/rag_core_api/api_endpoints/information_piece_uploader.py +27 -0
- rag_core_api-3.2.0/src/rag_core_api/apis/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/apis/rag_api.py +195 -0
- rag_core_api-3.2.0/src/rag_core_api/apis/rag_api_base.py +102 -0
- rag_core_api-3.2.0/src/rag_core_api/dependency_container.py +274 -0
- rag_core_api-3.2.0/src/rag_core_api/embeddings/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/embeddings/embedder.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/evaluator/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/evaluator/evaluator.py +11 -0
- rag_core_api-3.2.0/src/rag_core_api/graph/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/graph/graph_base.py +70 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/answer_generation_chains/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/answer_generation_chains/answer_generation_chain.py +67 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/answer_generation_chains/language_detection_chain.py +137 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/answer_generation_chains/rephrasing_chain.py +64 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/api_endpoints/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/api_endpoints/default_chat.py +52 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/api_endpoints/default_information_pieces_remover.py +69 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/api_endpoints/default_information_pieces_uploader.py +53 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/embeddings/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/embeddings/embedder_type.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/embeddings/langchain_community_embedder.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/embeddings/stackit_embedder.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/evaluator/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/evaluator/langfuse_ragas_evaluator.py +259 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/graph/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/graph/chat_graph.py +305 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/graph/graph_state/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/graph/graph_state/graph_state.py +116 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/rag_api.py +141 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/reranking/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/reranking/flashrank_reranker.py +66 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/retriever/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/retriever/composite_retriever.py +106 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/retriever/no_or_empty_collection_error.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/retriever/retriever_quark.py +104 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/chat_history_settings.py +25 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/embedder_class_type_settings.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/error_messages.py +46 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/ollama_embedder_settings.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/ragas_settings.py +41 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/reranker_settings.py +23 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/retriever_settings.py +44 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/sparse_embedder_settings.py +23 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/stackit_embedder_settings.py +5 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/settings/vector_db_settings.py +32 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/vector_databases/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/impl/vector_databases/qdrant_database.py +228 -0
- rag_core_api-3.2.0/src/rag_core_api/main.py +62 -0
- rag_core_api-3.2.0/src/rag_core_api/mapper/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/mapper/information_piece_mapper.py +166 -0
- rag_core_api-3.2.0/src/rag_core_api/models/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/models/chat_history.py +99 -0
- rag_core_api-3.2.0/src/rag_core_api/models/chat_history_message.py +85 -0
- rag_core_api-3.2.0/src/rag_core_api/models/chat_request.py +93 -0
- rag_core_api-3.2.0/src/rag_core_api/models/chat_response.py +103 -0
- rag_core_api-3.2.0/src/rag_core_api/models/chat_role.py +40 -0
- rag_core_api-3.2.0/src/rag_core_api/models/content_type.py +42 -0
- rag_core_api-3.2.0/src/rag_core_api/models/delete_request.py +99 -0
- rag_core_api-3.2.0/src/rag_core_api/models/extra_models.py +9 -0
- rag_core_api-3.2.0/src/rag_core_api/models/information_piece.py +108 -0
- rag_core_api-3.2.0/src/rag_core_api/models/key_value_pair.py +85 -0
- rag_core_api-3.2.0/src/rag_core_api/prompt_templates/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/prompt_templates/answer_generation_prompt.py +28 -0
- rag_core_api-3.2.0/src/rag_core_api/prompt_templates/language_detection_prompt.py +23 -0
- rag_core_api-3.2.0/src/rag_core_api/prompt_templates/question_rephrasing_prompt.py +23 -0
- rag_core_api-3.2.0/src/rag_core_api/reranking/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/reranking/reranker.py +58 -0
- rag_core_api-3.2.0/src/rag_core_api/retriever/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/retriever/retriever.py +59 -0
- rag_core_api-3.2.0/src/rag_core_api/utils/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/utils/utils.py +48 -0
- rag_core_api-3.2.0/src/rag_core_api/vector_databases/__init__.py +0 -0
- rag_core_api-3.2.0/src/rag_core_api/vector_databases/vector_database.py +130 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: rag-core-api
|
|
3
|
+
Version: 3.2.0
|
|
4
|
+
Summary: The core of the rag-template.
|
|
5
|
+
Author: STACKIT Data and AI Consulting
|
|
6
|
+
Author-email: data-ai-consulting@stackit.cloud
|
|
7
|
+
Requires-Python: >=3.13,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Requires-Dist: datasets (>=3.5.1,<4.0.0)
|
|
11
|
+
Requires-Dist: dependency-injector (>=4.46.0,<5.0.0)
|
|
12
|
+
Requires-Dist: deprecated (>=1.2.18,<2.0.0)
|
|
13
|
+
Requires-Dist: fastapi (>=0.118.0,<0.119.0)
|
|
14
|
+
Requires-Dist: fastembed (>=0.7.0,<0.8.0)
|
|
15
|
+
Requires-Dist: flashrank (>=0.2.10,<0.3.0)
|
|
16
|
+
Requires-Dist: langchain-community (==0.3.30)
|
|
17
|
+
Requires-Dist: langchain-ollama (>=0.3.2,<0.4.0)
|
|
18
|
+
Requires-Dist: langchain-qdrant (>=0.2.0,<0.3.0)
|
|
19
|
+
Requires-Dist: langchain-text-splitters (>=0.3.9)
|
|
20
|
+
Requires-Dist: langdetect (>=1.0.9,<2.0.0)
|
|
21
|
+
Requires-Dist: langfuse (==3.6.1)
|
|
22
|
+
Requires-Dist: langgraph (>=0.6.0,<0.7.0)
|
|
23
|
+
Requires-Dist: openai (>=1.77.0,<2.0.0)
|
|
24
|
+
Requires-Dist: pillow (>=11.2.1,<12.0.0)
|
|
25
|
+
Requires-Dist: pytest-asyncio (>=0.26.0,<0.27.0)
|
|
26
|
+
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
|
27
|
+
Requires-Dist: qdrant-client (>=1.14.2,<2.0.0)
|
|
28
|
+
Requires-Dist: rag-core-lib (>=3.2.0,<4.0.0)
|
|
29
|
+
Requires-Dist: ragas (>=0.3.0,<0.4.0)
|
|
30
|
+
Requires-Dist: requests-oauthlib (>=2.0.0,<3.0.0)
|
|
31
|
+
Requires-Dist: uvicorn (>=0.37.0,<0.38.0)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["poetry-core"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
5
|
+
[tool.poetry]
|
|
6
|
+
name = "rag-core-api"
|
|
7
|
+
version = "v3.2.0"
|
|
8
|
+
description = "The core of the rag-template."
|
|
9
|
+
authors = ["STACKIT Data and AI Consulting <data-ai-consulting@stackit.cloud>"]
|
|
10
|
+
packages = [{ include = "rag_core_api", from = "src" }]
|
|
11
|
+
|
|
12
|
+
[tool.poetry.dependencies]
|
|
13
|
+
python = "^3.13"
|
|
14
|
+
rag-core-lib = "^3.2.0"
|
|
15
|
+
uvicorn = "^0.37.0"
|
|
16
|
+
langchain-qdrant = "^0.2.0"
|
|
17
|
+
dependency-injector = "^4.46.0"
|
|
18
|
+
fastapi = "^0.118.0"
|
|
19
|
+
requests-oauthlib = "^2.0.0"
|
|
20
|
+
qdrant-client = "^1.14.2"
|
|
21
|
+
deprecated = "^1.2.18"
|
|
22
|
+
datasets = "^3.5.1"
|
|
23
|
+
ragas = "^0.3.0"
|
|
24
|
+
flashrank = "^0.2.10"
|
|
25
|
+
pyyaml = "^6.0.2"
|
|
26
|
+
openai = "^1.77.0"
|
|
27
|
+
langgraph = "^0.6.0"
|
|
28
|
+
pillow = "^11.2.1"
|
|
29
|
+
langchain-ollama = "^0.3.2"
|
|
30
|
+
pytest-asyncio = "^0.26.0"
|
|
31
|
+
langchain-community = "0.3.30"
|
|
32
|
+
fastembed = "^0.7.0"
|
|
33
|
+
langdetect = "^1.0.9"
|
|
34
|
+
langfuse = "3.6.1"
|
|
35
|
+
langchain-text-splitters = ">=0.3.9"
|
|
36
|
+
|
|
37
|
+
[tool.poetry.group.dev.dependencies]
|
|
38
|
+
debugpy = "^1.8.14"
|
|
39
|
+
pytest = "^8.3.5"
|
|
40
|
+
coverage = "^7.8.0"
|
|
41
|
+
flake8 = "^7.2.0"
|
|
42
|
+
flake8-black = "^0.4.0"
|
|
43
|
+
flake8-pyproject = "^1.2.3"
|
|
44
|
+
flake8-quotes = "^3.4.0"
|
|
45
|
+
flake8-return = "^1.2.0"
|
|
46
|
+
flake8-annotations-complexity = "^0.1.0"
|
|
47
|
+
flake8-bandit = "^4.1.1"
|
|
48
|
+
flake8-bugbear = "^24.12.12"
|
|
49
|
+
flake8-builtins = "^2.5.0"
|
|
50
|
+
flake8-comprehensions = "^3.15.0"
|
|
51
|
+
flake8-eradicate = "^1.5.0"
|
|
52
|
+
flake8-expression-complexity = "^0.0.11"
|
|
53
|
+
flake8-pytest-style = "^2.1.0"
|
|
54
|
+
pep8-naming = "^0.15.1"
|
|
55
|
+
flake8-eol = "^0.0.8"
|
|
56
|
+
flake8-exceptions = "^0.0.1a0"
|
|
57
|
+
flake8-simplify = "^0.22.0"
|
|
58
|
+
flake8-wot = "^0.2.0"
|
|
59
|
+
flake8-function-order = "^0.0.5"
|
|
60
|
+
flake8-tidy-imports = "^4.10.0"
|
|
61
|
+
black = "^25.1.0"
|
|
62
|
+
# flake8-logging-format = "^2024.24.12"
|
|
63
|
+
# flake8-docstrings = "^1.7.0"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
[tool.flake8]
|
|
67
|
+
exclude= [".eggs", "src/rag_core_api/models", ".git", ".hg", ".mypy_cache", ".tox", ".venv", ".devcontainer", "venv", "_build", "buck-out", "build", "dist", "**/__init__.py"]
|
|
68
|
+
statistics = true
|
|
69
|
+
show-source = false
|
|
70
|
+
max-complexity = 8
|
|
71
|
+
max-annotations-complexity = 3
|
|
72
|
+
docstring-convention = 'numpy'
|
|
73
|
+
max-line-length = 120
|
|
74
|
+
ignore = ["E203", "W503", "E704"]
|
|
75
|
+
inline-quotes = '"'
|
|
76
|
+
docstring-quotes = '"""'
|
|
77
|
+
multiline-quotes = '"""'
|
|
78
|
+
dictionaries = ["en_US", "python", "technical", "pandas"]
|
|
79
|
+
ban-relative-imports = true
|
|
80
|
+
per-file-ignores = """
|
|
81
|
+
./src/rag_core_api/prompt_templates/*: E501,D100,
|
|
82
|
+
./src/rag_core_api/apis/rag_api.py: B008,WOT001,
|
|
83
|
+
./src/rag_core_api/impl/rag_api.py: B008,
|
|
84
|
+
./src/rag_core_api/prompt_templates/*: E501,
|
|
85
|
+
./src/rag_core_api/dependency_container.py: CCE002,CCE001,
|
|
86
|
+
./src/rag_core_api/apis/rag_api_base.py: WOT001,
|
|
87
|
+
./tests/rag_api_test.py: E402,S101,S105,I252,D409,
|
|
88
|
+
./tests/*: S101,S105,I252,D409,
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
[tool.black]
|
|
92
|
+
line-length = 120
|
|
93
|
+
exclude = """
|
|
94
|
+
/(
|
|
95
|
+
.eggs
|
|
96
|
+
| .git
|
|
97
|
+
| .hg
|
|
98
|
+
| .mypy_cache
|
|
99
|
+
| .nox
|
|
100
|
+
| .pants.d
|
|
101
|
+
| .tox
|
|
102
|
+
| .venv
|
|
103
|
+
| _build
|
|
104
|
+
| buck-out
|
|
105
|
+
| build
|
|
106
|
+
| dist
|
|
107
|
+
| node_modules
|
|
108
|
+
| venv
|
|
109
|
+
)/
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
[tool.isort]
|
|
113
|
+
profile = "black"
|
|
114
|
+
skip = ['.eggs', '.git', '.hg', '.mypy_cache', '.nox', '.pants.d', '.tox', '.venv', '_build', 'buck-out', 'build', 'dist', 'node_modules', 'venv']
|
|
115
|
+
skip_gitignore = true
|
|
116
|
+
known_local_folder = ["rag_core_api", "rag_core_lib"]
|
|
117
|
+
|
|
118
|
+
[tool.pylint]
|
|
119
|
+
max-line-length = 120
|
|
120
|
+
|
|
121
|
+
[tool.pytest.ini_options]
|
|
122
|
+
log_cli = true
|
|
123
|
+
log_cli_level = "DEBUG"
|
|
124
|
+
pythonpath = ["src", "tests"]
|
|
125
|
+
testpaths = ["tests"]
|
|
126
|
+
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Module for base class of chat endpoint."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from rag_core_api.models.chat_request import ChatRequest
|
|
6
|
+
from rag_core_api.models.chat_response import ChatResponse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Chat(ABC):
|
|
10
|
+
"""Base class for chat endpoint."""
|
|
11
|
+
|
|
12
|
+
@abstractmethod
|
|
13
|
+
async def achat(self, session_id: str, chat_request: ChatRequest) -> ChatResponse:
|
|
14
|
+
"""
|
|
15
|
+
Abstract method to handle asynchronous chat requests.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
session_id : str
|
|
20
|
+
The unique identifier for the chat session.
|
|
21
|
+
chat_request : ChatRequest
|
|
22
|
+
The request object containing the chat details.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
ChatResponse
|
|
27
|
+
The response object containing the chat results.
|
|
28
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Module for the InformationPieceRemover abstract base class."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from rag_core_api.models.delete_request import DeleteRequest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InformationPieceRemover(ABC):
|
|
9
|
+
"""Abstract base class for removing information pieces.
|
|
10
|
+
|
|
11
|
+
This class defines the interface for removing information pieces based on a given delete request.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def remove_information_piece(self, delete_request: DeleteRequest) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Remove information pieces based on the given delete request.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
delete_request : DeleteRequest
|
|
22
|
+
The request object containing the details of the information pieces to be deleted.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
None
|
|
27
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Module for the InformationPiecesUploader abstract base class."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from rag_core_api.models.information_piece import InformationPiece
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InformationPiecesUploader(ABC):
|
|
9
|
+
"""Abstract base class for uploading information pieces.
|
|
10
|
+
|
|
11
|
+
This class defines the interface for uploading a list of information pieces.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def upload_information_piece(self, information_piece: list[InformationPiece]) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Abstract method to upload a list of information pieces.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
information_piece : list[InformationPiece]
|
|
22
|
+
A list of InformationPiece objects to be uploaded.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
None
|
|
27
|
+
"""
|
|
File without changes
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""Module containing the RAG API endpoints."""
|
|
2
|
+
|
|
3
|
+
# coding: utf-8
|
|
4
|
+
# flake8: noqa: D105
|
|
5
|
+
|
|
6
|
+
import importlib
|
|
7
|
+
import logging
|
|
8
|
+
import pkgutil
|
|
9
|
+
from asyncio import FIRST_COMPLETED, CancelledError, create_task, sleep, wait
|
|
10
|
+
from contextlib import suppress
|
|
11
|
+
from typing import Any, Awaitable, List # noqa: F401
|
|
12
|
+
|
|
13
|
+
from fastapi import ( # noqa: F401
|
|
14
|
+
APIRouter,
|
|
15
|
+
BackgroundTasks,
|
|
16
|
+
Body,
|
|
17
|
+
Cookie,
|
|
18
|
+
Depends,
|
|
19
|
+
Form,
|
|
20
|
+
Header,
|
|
21
|
+
HTTPException,
|
|
22
|
+
Path,
|
|
23
|
+
Query,
|
|
24
|
+
Request,
|
|
25
|
+
Response,
|
|
26
|
+
Security,
|
|
27
|
+
status,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
import rag_core_api.impl
|
|
31
|
+
from rag_core_api.apis.rag_api_base import BaseRagApi
|
|
32
|
+
from rag_core_api.models.chat_request import ChatRequest
|
|
33
|
+
from rag_core_api.models.chat_response import ChatResponse
|
|
34
|
+
from rag_core_api.models.delete_request import DeleteRequest
|
|
35
|
+
from rag_core_api.models.information_piece import InformationPiece
|
|
36
|
+
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
router = APIRouter()
|
|
40
|
+
|
|
41
|
+
ns_pkg = rag_core_api.impl
|
|
42
|
+
for _, name, _ in pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + "."):
|
|
43
|
+
importlib.import_module(name)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def _disconnected(request: Request) -> None:
|
|
47
|
+
while True:
|
|
48
|
+
try:
|
|
49
|
+
if await request.is_disconnected():
|
|
50
|
+
break
|
|
51
|
+
await sleep(1.0)
|
|
52
|
+
except CancelledError:
|
|
53
|
+
break
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@router.post(
|
|
57
|
+
"/chat/{session_id}",
|
|
58
|
+
responses={
|
|
59
|
+
200: {"model": ChatResponse, "description": "OK."},
|
|
60
|
+
500: {"description": "Internal Server Error!"},
|
|
61
|
+
},
|
|
62
|
+
tags=["rag"],
|
|
63
|
+
response_model_by_alias=True,
|
|
64
|
+
)
|
|
65
|
+
async def chat(
|
|
66
|
+
request: Request,
|
|
67
|
+
session_id: str = Path(..., description=""),
|
|
68
|
+
chat_request: ChatRequest = Body(None, description="Chat with RAG."),
|
|
69
|
+
) -> ChatResponse | None:
|
|
70
|
+
"""
|
|
71
|
+
Asynchronously handles the chat endpoint for the RAG API.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
request : Request
|
|
76
|
+
The request object.
|
|
77
|
+
session_id : str
|
|
78
|
+
The session ID for the chat.
|
|
79
|
+
chat_request : ChatRequest, optional
|
|
80
|
+
The chat request payload
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
ChatResponse or None
|
|
85
|
+
The chat response if the chat task completes successfully, otherwise None.
|
|
86
|
+
|
|
87
|
+
Raises
|
|
88
|
+
------
|
|
89
|
+
CancelledError
|
|
90
|
+
If the task is cancelled.
|
|
91
|
+
|
|
92
|
+
Notes
|
|
93
|
+
-----
|
|
94
|
+
This function creates two asynchronous tasks: one for handling disconnection and one for processing the chat
|
|
95
|
+
request. It waits for either task to complete first and cancels the remaining tasks.
|
|
96
|
+
"""
|
|
97
|
+
disconnect_task = create_task(_disconnected(request))
|
|
98
|
+
chat_task = create_task(BaseRagApi.subclasses[0]().chat(session_id, chat_request))
|
|
99
|
+
done, pending = await wait(
|
|
100
|
+
[disconnect_task, chat_task],
|
|
101
|
+
return_when=FIRST_COMPLETED,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# cancel all remaining tasks
|
|
105
|
+
for task in pending:
|
|
106
|
+
task.cancel()
|
|
107
|
+
with suppress(CancelledError):
|
|
108
|
+
await task
|
|
109
|
+
if chat_task in done:
|
|
110
|
+
return chat_task.result()
|
|
111
|
+
logger.info("Request got cancelled!")
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@router.post(
|
|
116
|
+
"/evaluate",
|
|
117
|
+
responses={
|
|
118
|
+
201: {"description": "Accepted."},
|
|
119
|
+
500: {"description": "Internal Server Error."},
|
|
120
|
+
},
|
|
121
|
+
tags=["rag"],
|
|
122
|
+
response_model_by_alias=True,
|
|
123
|
+
)
|
|
124
|
+
async def evaluate() -> None:
|
|
125
|
+
"""
|
|
126
|
+
Asynchronously evaluate the RAG.
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
None
|
|
131
|
+
"""
|
|
132
|
+
return await BaseRagApi.subclasses[0]().evaluate()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@router.post(
|
|
136
|
+
"/information_pieces/remove",
|
|
137
|
+
responses={
|
|
138
|
+
202: {"description": "Accepted."},
|
|
139
|
+
404: {"description": "Ressource not Found"},
|
|
140
|
+
422: {"description": "ID or metadata missing."},
|
|
141
|
+
500: {"description": "Internal Server Error."},
|
|
142
|
+
},
|
|
143
|
+
tags=["rag"],
|
|
144
|
+
summary="remove information piece",
|
|
145
|
+
response_model_by_alias=True,
|
|
146
|
+
)
|
|
147
|
+
async def remove_information_piece(
|
|
148
|
+
delete_request: DeleteRequest = Body(None, description=""),
|
|
149
|
+
) -> None:
|
|
150
|
+
"""
|
|
151
|
+
Asynchronously removes information pieces.
|
|
152
|
+
|
|
153
|
+
This endpoint removes information pieces based on the provided delete request.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
delete_request : DeleteRequest
|
|
158
|
+
The request body containing the details for the information piece to be removed.
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
None
|
|
163
|
+
"""
|
|
164
|
+
return await BaseRagApi.subclasses[0]().remove_information_piece(delete_request)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@router.post(
|
|
168
|
+
"/information_pieces/upload",
|
|
169
|
+
responses={
|
|
170
|
+
201: {"description": "The file was successful uploaded."},
|
|
171
|
+
422: {"model": str, "description": "Wrong json format."},
|
|
172
|
+
500: {"model": str, "description": "Internal Server Error."},
|
|
173
|
+
},
|
|
174
|
+
tags=["rag"],
|
|
175
|
+
summary="Upload information pieces for vectordatabase",
|
|
176
|
+
response_model_by_alias=True,
|
|
177
|
+
)
|
|
178
|
+
async def upload_information_piece(
|
|
179
|
+
information_piece: List[InformationPiece] = Body(None, description=""),
|
|
180
|
+
) -> None:
|
|
181
|
+
"""
|
|
182
|
+
Asynchronously uploads information pieces for vectordatabase.
|
|
183
|
+
|
|
184
|
+
This endpoint allows for the upload of information pieces to the vector database.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
information_piece : List[InformationPiece]
|
|
189
|
+
A list of information pieces to be uploaded (default None).
|
|
190
|
+
|
|
191
|
+
Returns
|
|
192
|
+
-------
|
|
193
|
+
None
|
|
194
|
+
"""
|
|
195
|
+
return await BaseRagApi.subclasses[0]().upload_information_piece(information_piece)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Module containing the base RAG API class."""
|
|
2
|
+
|
|
3
|
+
# coding: utf-8
|
|
4
|
+
# flake8: noqa: D105
|
|
5
|
+
|
|
6
|
+
from typing import ClassVar, Dict, List, Tuple # noqa: F401
|
|
7
|
+
|
|
8
|
+
from rag_core_api.models.chat_request import ChatRequest
|
|
9
|
+
from rag_core_api.models.chat_response import ChatResponse
|
|
10
|
+
from rag_core_api.models.delete_request import DeleteRequest
|
|
11
|
+
from rag_core_api.models.information_piece import InformationPiece
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseRagApi:
|
|
15
|
+
"""Base class for RAG API.
|
|
16
|
+
|
|
17
|
+
This class serves as the base for the RAG API implementations. It provides
|
|
18
|
+
asynchronous methods for handling chat, evaluating the RAG, removing information
|
|
19
|
+
pieces, and uploading information pieces to a vector database.
|
|
20
|
+
|
|
21
|
+
Attributes
|
|
22
|
+
subclasses : ClassVar[Tuple]
|
|
23
|
+
A tuple that holds all subclasses of BaseRagApi.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
subclasses: ClassVar[Tuple] = ()
|
|
27
|
+
|
|
28
|
+
def __init_subclass__(cls, **kwargs):
|
|
29
|
+
super().__init_subclass__(**kwargs)
|
|
30
|
+
BaseRagApi.subclasses = BaseRagApi.subclasses + (cls,)
|
|
31
|
+
|
|
32
|
+
async def chat(
|
|
33
|
+
self,
|
|
34
|
+
session_id: str,
|
|
35
|
+
chat_request: ChatRequest,
|
|
36
|
+
) -> ChatResponse:
|
|
37
|
+
"""
|
|
38
|
+
Asynchronously handles the chat endpoint for the RAG API.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
request : Request
|
|
43
|
+
The request object.
|
|
44
|
+
session_id : str
|
|
45
|
+
The session ID for the chat.
|
|
46
|
+
chat_request : ChatRequest, optional
|
|
47
|
+
The chat request payload
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
ChatResponse or None
|
|
52
|
+
The chat response if the chat task completes successfully, otherwise None.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
async def evaluate(
|
|
56
|
+
self,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Asynchronously evaluate the RAG.
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
None
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
async def remove_information_piece(
|
|
67
|
+
self,
|
|
68
|
+
delete_request: DeleteRequest,
|
|
69
|
+
) -> None:
|
|
70
|
+
"""
|
|
71
|
+
Asynchronously removes information pieces.
|
|
72
|
+
|
|
73
|
+
This endpoint removes information pieces based on the provided delete request.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
delete_request : DeleteRequest
|
|
78
|
+
The request body containing the details for the information piece to be removed.
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
None
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
async def upload_information_piece(
|
|
86
|
+
self,
|
|
87
|
+
information_piece: List[InformationPiece],
|
|
88
|
+
) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Asynchronously uploads information pieces for vectordatabase.
|
|
91
|
+
|
|
92
|
+
This endpoint allows for the upload of information pieces to the vector database.
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
information_piece : List[InformationPiece]
|
|
97
|
+
A list of information pieces to be uploaded (default None).
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
None
|
|
102
|
+
"""
|