Skip to content

Commit 23d1e52

Browse files
RinZ27Tomas2D
andauthored
feat: validate class names in dynamic adapters (#1408)
Signed-off-by: RinZ27 <222222878+RinZ27@users.noreply.github.com> Co-authored-by: Tomáš Dvořák <toomas2d@gmail.com>
1 parent 8e18bb0 commit 23d1e52

12 files changed

Lines changed: 85 additions & 0 deletions

File tree

python/beeai_framework/adapters/agentstack/backend/vector_store.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from beeai_framework.backend.embedding import EmbeddingModel
99
from beeai_framework.backend.types import Document, DocumentWithScore
1010
from beeai_framework.backend.vector_store import QueryLike, VectorStore
11+
from beeai_framework.utils.strings import validate_class_name
1112

1213
try:
1314
from agentstack_sdk.platform import VectorStore as AgentStackSDKVectorStore
@@ -22,6 +23,8 @@ class AgentStackVectorStore(VectorStore, ABC):
2223
@classmethod
2324
def _class_from_name(cls, class_name: str, embedding_model: EmbeddingModel, **kwargs: Any) -> VectorStore:
2425
"""Create an instance from class name (required by VectorStore base class)."""
26+
validate_class_name(class_name)
27+
2528
# Get the current module to look for classes
2629
import sys
2730

python/beeai_framework/adapters/beeai/backend/document_processor.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from beeai_framework.backend.chat import ChatModel
1515
from beeai_framework.backend.document_processor import DocumentProcessor
1616
from beeai_framework.backend.types import DocumentWithScore
17+
from beeai_framework.utils.strings import validate_class_name
1718

1819
try:
1920
from llama_index.core.postprocessor.llm_rerank import LLMRerank
@@ -27,6 +28,8 @@ class BeeAIDocumentProcessor(DocumentProcessor, ABC):
2728
@classmethod
2829
def _class_from_name(cls, class_name: str, **kwargs: Any) -> BeeAIDocumentProcessor:
2930
"""Create an instance from class name (required by DocumentProcessor base class)."""
31+
validate_class_name(class_name)
32+
3033
# Get the current module to look for classes
3134
import sys
3235

python/beeai_framework/adapters/beeai/backend/vector_store.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from beeai_framework.backend.embedding import EmbeddingModel
1010
from beeai_framework.backend.types import Document, DocumentWithScore
1111
from beeai_framework.backend.vector_store import QueryLike, VectorStore
12+
from beeai_framework.utils.strings import validate_class_name
1213

1314
try:
1415
from langchain_core.documents import Document as LCDocument
@@ -26,6 +27,8 @@ class BeeAIVectorStore(VectorStore, ABC):
2627
@classmethod
2728
def _class_from_name(cls, class_name: str, embedding_model: EmbeddingModel, **kwargs: Any) -> BeeAIVectorStore:
2829
"""Create an instance from class name (required by VectorStore base class)."""
30+
validate_class_name(class_name)
31+
2932
# Get the current module to look for classes
3033
import sys
3134

python/beeai_framework/adapters/langchain/backend/document_loader.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from beeai_framework.adapters.langchain.mappers.documents import lc_document_to_document
1717
from beeai_framework.backend.document_loader import DocumentLoader
1818
from beeai_framework.backend.types import Document
19+
from beeai_framework.utils.strings import validate_class_name
1920
from beeai_framework.logger import Logger
2021

2122
logger = Logger(__name__)
@@ -31,6 +32,8 @@ def _class_from_name(cls, class_name: str, **kwargs: Any) -> LangChainDocumentLo
3132
"""
3233
Dynamically imports and instantiates `class_name` from LangChain document loaders
3334
"""
35+
validate_class_name(class_name)
36+
3437
lc_document_loader = None
3538

3639
# Try importing from langchain_community first (most common document loaders)

python/beeai_framework/adapters/langchain/backend/text_splitter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from beeai_framework.adapters.langchain.mappers.documents import document_to_lc_document, lc_document_to_document
1717
from beeai_framework.backend.text_splitter import TextSplitter
1818
from beeai_framework.backend.types import Document
19+
from beeai_framework.utils.strings import validate_class_name
1920
from beeai_framework.logger import Logger
2021

2122
logger = Logger(__name__)
@@ -31,6 +32,8 @@ def _class_from_name(cls, class_name: str, **kwargs: Any) -> LangChainTextSplitt
3132
"""
3233
Dynamically imports and instantiates `class_name` from LangChain text splitters
3334
"""
35+
validate_class_name(class_name)
36+
3437
lc_text_splitter = None
3538

3639
# Try importing from langchain_text_splitters first (most common text splitters)

python/beeai_framework/adapters/langchain/backend/vector_store.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from beeai_framework.adapters.langchain.mappers.documents import document_to_lc_document, lc_document_to_document
2121
from beeai_framework.backend.embedding import EmbeddingModel
2222
from beeai_framework.backend.vector_store import QueryLike, VectorStore
23+
from beeai_framework.utils.strings import validate_class_name
2324
from beeai_framework.logger import Logger
2425

2526
logger = Logger(__name__)
@@ -50,6 +51,8 @@ def _class_from_name(cls, class_name: str, embedding_model: EmbeddingModel, **kw
5051
"""
5152
Dynamically imports and instantiates `class_name` from all vector store paths on LangChain
5253
"""
54+
validate_class_name(class_name)
55+
5356
lc_vector_store = None
5457
# Convert BeeAI embedding to LangChain embedding
5558
lc_embedding = LangChainBeeAIEmbeddingModel(embedding_model)

python/beeai_framework/backend/document_loader.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from beeai_framework.backend.types import Document
1010
from beeai_framework.backend.utils import load_module, parse_module
11+
from beeai_framework.utils.strings import validate_class_name
1112

1213
__all__ = ["DocumentLoader"]
1314

@@ -85,6 +86,7 @@ def from_name(cls, name: str, **kwargs: Any) -> DocumentLoader:
8586
If the specified class cannot be found in any known integration package.
8687
"""
8788
parsed_module = parse_module(name)
89+
validate_class_name(parsed_module.entity_id)
8890
TargetDocumentLoader = load_module(parsed_module.provider_id, "document_loader") # type: ignore # noqa: N806
8991
return TargetDocumentLoader._class_from_name( # type: ignore[no-any-return]
9092
class_name=parsed_module.entity_id, **kwargs

python/beeai_framework/backend/document_processor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from beeai_framework.backend.types import DocumentWithScore
1010
from beeai_framework.backend.utils import load_module, parse_module
11+
from beeai_framework.utils.strings import validate_class_name
1112

1213
__all__ = ["DocumentProcessor"]
1314

@@ -44,6 +45,7 @@ def from_name(cls, name: str, **kwargs: Any) -> DocumentProcessor:
4445
If the specified class cannot be found in any known integration package.
4546
"""
4647
parsed_module = parse_module(name)
48+
validate_class_name(parsed_module.entity_id)
4749
TargetDocumentProcessor = load_module(parsed_module.provider_id, "document_processor") # type: ignore # noqa: N806
4850
return TargetDocumentProcessor._class_from_name( # type: ignore[no-any-return]
4951
class_name=parsed_module.entity_id, **kwargs

python/beeai_framework/backend/text_splitter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from beeai_framework.backend.types import Document
1010
from beeai_framework.backend.utils import load_module, parse_module
11+
from beeai_framework.utils.strings import validate_class_name
1112

1213
__all__ = ["TextSplitter"]
1314

@@ -82,6 +83,8 @@ def from_name(cls, name: str, **kwargs: Any) -> TextSplitter:
8283
f"Only provider {parsed_module.provider_id} was specified. Text Splitter name was not specified."
8384
)
8485

86+
validate_class_name(parsed_module.entity_id)
87+
8588
target: type[TextSplitter] = load_module(parsed_module.provider_id, "text_splitter")
8689
return target._class_from_name(class_name=parsed_module.entity_id, **kwargs)
8790

python/beeai_framework/backend/vector_store.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from beeai_framework.backend.embedding import EmbeddingModel
1010
from beeai_framework.backend.types import Document, DocumentWithScore
1111
from beeai_framework.backend.utils import load_module, parse_module
12+
from beeai_framework.utils.strings import validate_class_name
1213

1314

1415
class QueryLike(Protocol):
@@ -104,6 +105,8 @@ def from_name(cls, name: str, *, embedding_model: EmbeddingModel, **kwargs: Any)
104105
f"Only provider {parsed_module.provider_id} was specified. Vector Store name was not specified."
105106
)
106107

108+
validate_class_name(parsed_module.entity_id)
109+
107110
target: type[VectorStore] = load_module(parsed_module.provider_id, "vector_store")
108111
return target._class_from_name(
109112
class_name=parsed_module.entity_id,

0 commit comments

Comments
 (0)