snowloader 0.1.0__py3-none-any.whl
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.
- snowloader/__init__.py +36 -0
- snowloader/adapters/__init__.py +16 -0
- snowloader/adapters/langchain.py +110 -0
- snowloader/adapters/llamaindex.py +127 -0
- snowloader/connection.py +670 -0
- snowloader/loaders/__init__.py +25 -0
- snowloader/loaders/_field_utils.py +88 -0
- snowloader/loaders/catalog.py +94 -0
- snowloader/loaders/changes.py +132 -0
- snowloader/loaders/cmdb.py +268 -0
- snowloader/loaders/incidents.py +158 -0
- snowloader/loaders/knowledge_base.py +103 -0
- snowloader/loaders/problems.py +137 -0
- snowloader/models.py +260 -0
- snowloader/py.typed +0 -0
- snowloader/utils/__init__.py +14 -0
- snowloader/utils/html_cleaner.py +73 -0
- snowloader-0.1.0.dist-info/METADATA +248 -0
- snowloader-0.1.0.dist-info/RECORD +21 -0
- snowloader-0.1.0.dist-info/WHEEL +4 -0
- snowloader-0.1.0.dist-info/licenses/LICENSE +21 -0
snowloader/__init__.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""snowloader -- Comprehensive ServiceNow data loader for AI/LLM pipelines.
|
|
2
|
+
|
|
3
|
+
Provides a clean, Pythonic interface for pulling data out of ServiceNow tables
|
|
4
|
+
and converting it into document formats that LangChain, LlamaIndex, and other
|
|
5
|
+
LLM frameworks can work with directly. Built for production use with proper
|
|
6
|
+
pagination, delta sync, and memory-efficient streaming.
|
|
7
|
+
|
|
8
|
+
Author: Roni Das
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from snowloader.connection import SnowConnection, SnowConnectionError
|
|
14
|
+
from snowloader.loaders.catalog import CatalogLoader
|
|
15
|
+
from snowloader.loaders.changes import ChangeLoader
|
|
16
|
+
from snowloader.loaders.cmdb import CMDBLoader
|
|
17
|
+
from snowloader.loaders.incidents import IncidentLoader
|
|
18
|
+
from snowloader.loaders.knowledge_base import KnowledgeBaseLoader
|
|
19
|
+
from snowloader.loaders.problems import ProblemLoader
|
|
20
|
+
from snowloader.models import BaseSnowLoader, SnowDocument
|
|
21
|
+
|
|
22
|
+
__version__ = "0.1.0"
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"BaseSnowLoader",
|
|
26
|
+
"CatalogLoader",
|
|
27
|
+
"ChangeLoader",
|
|
28
|
+
"CMDBLoader",
|
|
29
|
+
"IncidentLoader",
|
|
30
|
+
"KnowledgeBaseLoader",
|
|
31
|
+
"ProblemLoader",
|
|
32
|
+
"SnowConnection",
|
|
33
|
+
"SnowConnectionError",
|
|
34
|
+
"SnowDocument",
|
|
35
|
+
"__version__",
|
|
36
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Framework adapters for snowloader.
|
|
2
|
+
|
|
3
|
+
Thin wrappers that convert SnowDocument output from the core loaders into
|
|
4
|
+
document types expected by LangChain, LlamaIndex, or other LLM frameworks.
|
|
5
|
+
No business logic lives here. If you are looking for query building,
|
|
6
|
+
pagination, or field mapping, check the loaders package instead.
|
|
7
|
+
|
|
8
|
+
Import paths (adapters are not auto-imported to avoid pulling in optional
|
|
9
|
+
dependencies)::
|
|
10
|
+
|
|
11
|
+
# LangChain
|
|
12
|
+
from snowloader.adapters.langchain import ServiceNowIncidentLoader
|
|
13
|
+
|
|
14
|
+
# LlamaIndex
|
|
15
|
+
from snowloader.adapters.llamaindex import ServiceNowIncidentReader
|
|
16
|
+
"""
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""LangChain adapter for snowloader.
|
|
2
|
+
|
|
3
|
+
Thin wrappers that expose snowloader's core loaders through the standard
|
|
4
|
+
langchain_core BaseLoader interface. Each adapter delegates all the real
|
|
5
|
+
work to the underlying loader and just handles the conversion from
|
|
6
|
+
SnowDocument to langchain_core Document.
|
|
7
|
+
|
|
8
|
+
No business logic here. If you need to change how documents are built,
|
|
9
|
+
modify the core loaders instead.
|
|
10
|
+
|
|
11
|
+
Author: Roni Das
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
from collections.abc import Iterator
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
from langchain_core.document_loaders import BaseLoader
|
|
23
|
+
from langchain_core.documents import Document
|
|
24
|
+
except ImportError as exc:
|
|
25
|
+
raise ImportError(
|
|
26
|
+
"langchain-core is required for the LangChain adapter. "
|
|
27
|
+
"Install it with: pip install snowloader[langchain]"
|
|
28
|
+
) from exc
|
|
29
|
+
|
|
30
|
+
from snowloader.connection import SnowConnection
|
|
31
|
+
from snowloader.loaders.catalog import CatalogLoader
|
|
32
|
+
from snowloader.loaders.changes import ChangeLoader
|
|
33
|
+
from snowloader.loaders.cmdb import CMDBLoader
|
|
34
|
+
from snowloader.loaders.incidents import IncidentLoader
|
|
35
|
+
from snowloader.loaders.knowledge_base import KnowledgeBaseLoader
|
|
36
|
+
from snowloader.loaders.problems import ProblemLoader
|
|
37
|
+
from snowloader.models import BaseSnowLoader
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger(__name__)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class _LangChainAdapter(BaseLoader):
|
|
43
|
+
"""Base adapter that wraps any snowloader loader for LangChain.
|
|
44
|
+
|
|
45
|
+
Converts SnowDocument instances to LangChain Document objects.
|
|
46
|
+
Subclasses just set the _loader_class attribute.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
_loader_class: type[BaseSnowLoader]
|
|
50
|
+
|
|
51
|
+
def __init__(self, connection: SnowConnection, **kwargs: Any) -> None:
|
|
52
|
+
self._loader = self._loader_class(connection=connection, **kwargs)
|
|
53
|
+
|
|
54
|
+
def lazy_load(self) -> Iterator[Document]:
|
|
55
|
+
"""Yield LangChain Documents one at a time from the core loader."""
|
|
56
|
+
for snow_doc in self._loader.lazy_load():
|
|
57
|
+
yield Document(
|
|
58
|
+
page_content=snow_doc.page_content,
|
|
59
|
+
metadata=snow_doc.metadata,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def load_since(self, since: datetime) -> list[Document]:
|
|
63
|
+
"""Fetch only records updated after the given datetime.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
since: Cutoff datetime for delta sync.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
List of LangChain Document instances.
|
|
70
|
+
"""
|
|
71
|
+
return [
|
|
72
|
+
Document(page_content=d.page_content, metadata=d.metadata)
|
|
73
|
+
for d in self._loader.load_since(since)
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ServiceNowIncidentLoader(_LangChainAdapter):
|
|
78
|
+
"""LangChain loader for ServiceNow incidents."""
|
|
79
|
+
|
|
80
|
+
_loader_class = IncidentLoader
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ServiceNowKBLoader(_LangChainAdapter):
|
|
84
|
+
"""LangChain loader for ServiceNow Knowledge Base articles."""
|
|
85
|
+
|
|
86
|
+
_loader_class = KnowledgeBaseLoader
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ServiceNowCMDBLoader(_LangChainAdapter):
|
|
90
|
+
"""LangChain loader for ServiceNow CMDB configuration items."""
|
|
91
|
+
|
|
92
|
+
_loader_class = CMDBLoader
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ServiceNowChangeLoader(_LangChainAdapter):
|
|
96
|
+
"""LangChain loader for ServiceNow change requests."""
|
|
97
|
+
|
|
98
|
+
_loader_class = ChangeLoader
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class ServiceNowProblemLoader(_LangChainAdapter):
|
|
102
|
+
"""LangChain loader for ServiceNow problem records."""
|
|
103
|
+
|
|
104
|
+
_loader_class = ProblemLoader
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class ServiceNowCatalogLoader(_LangChainAdapter):
|
|
108
|
+
"""LangChain loader for ServiceNow service catalog items."""
|
|
109
|
+
|
|
110
|
+
_loader_class = CatalogLoader
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""LlamaIndex adapter for snowloader.
|
|
2
|
+
|
|
3
|
+
Thin wrappers that expose snowloader's core loaders through the standard
|
|
4
|
+
llama_index BaseReader interface. Each adapter delegates all the real
|
|
5
|
+
work to the underlying loader and just handles the conversion from
|
|
6
|
+
SnowDocument to llama_index Document.
|
|
7
|
+
|
|
8
|
+
No business logic here. If you need to change how documents are built,
|
|
9
|
+
modify the core loaders instead.
|
|
10
|
+
|
|
11
|
+
Author: Roni Das
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
from llama_index.core.readers.base import BaseReader
|
|
22
|
+
from llama_index.core.schema import Document
|
|
23
|
+
except ImportError as exc:
|
|
24
|
+
raise ImportError(
|
|
25
|
+
"llama-index-core is required for the LlamaIndex adapter. "
|
|
26
|
+
"Install it with: pip install snowloader[llamaindex]"
|
|
27
|
+
) from exc
|
|
28
|
+
|
|
29
|
+
from snowloader.connection import SnowConnection
|
|
30
|
+
from snowloader.loaders.catalog import CatalogLoader
|
|
31
|
+
from snowloader.loaders.changes import ChangeLoader
|
|
32
|
+
from snowloader.loaders.cmdb import CMDBLoader
|
|
33
|
+
from snowloader.loaders.incidents import IncidentLoader
|
|
34
|
+
from snowloader.loaders.knowledge_base import KnowledgeBaseLoader
|
|
35
|
+
from snowloader.loaders.problems import ProblemLoader
|
|
36
|
+
from snowloader.models import BaseSnowLoader, SnowDocument
|
|
37
|
+
|
|
38
|
+
logger = logging.getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class _LlamaIndexAdapter(BaseReader):
|
|
42
|
+
"""Base adapter that wraps any snowloader loader for LlamaIndex.
|
|
43
|
+
|
|
44
|
+
Converts SnowDocument instances to LlamaIndex Document objects.
|
|
45
|
+
Subclasses just set the _loader_class attribute.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
_loader_class: type[BaseSnowLoader]
|
|
49
|
+
|
|
50
|
+
_default_excluded_llm_keys: list[str] = ["sys_id"]
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
connection: SnowConnection,
|
|
55
|
+
excluded_llm_metadata_keys: list[str] | None = None,
|
|
56
|
+
**kwargs: Any,
|
|
57
|
+
) -> None:
|
|
58
|
+
super().__init__()
|
|
59
|
+
self._excluded_keys = (
|
|
60
|
+
excluded_llm_metadata_keys
|
|
61
|
+
if excluded_llm_metadata_keys is not None
|
|
62
|
+
else self._default_excluded_llm_keys
|
|
63
|
+
)
|
|
64
|
+
self._loader = self._loader_class(connection=connection, **kwargs)
|
|
65
|
+
|
|
66
|
+
def load_data(self) -> list[Document]:
|
|
67
|
+
"""Return a list of LlamaIndex Documents from the core loader.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
List of LlamaIndex Document instances.
|
|
71
|
+
"""
|
|
72
|
+
return [self._to_document(d) for d in self._loader.lazy_load()]
|
|
73
|
+
|
|
74
|
+
def load_data_since(self, since: datetime) -> list[Document]:
|
|
75
|
+
"""Fetch only records updated after the given datetime.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
since: Cutoff datetime for delta sync.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
List of LlamaIndex Document instances.
|
|
82
|
+
"""
|
|
83
|
+
return [self._to_document(d) for d in self._loader.load_since(since)]
|
|
84
|
+
|
|
85
|
+
def _to_document(self, snow_doc: SnowDocument) -> Document:
|
|
86
|
+
"""Convert a SnowDocument to a LlamaIndex Document."""
|
|
87
|
+
return Document(
|
|
88
|
+
text=snow_doc.page_content,
|
|
89
|
+
metadata=snow_doc.metadata,
|
|
90
|
+
excluded_llm_metadata_keys=self._excluded_keys,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class ServiceNowIncidentReader(_LlamaIndexAdapter):
|
|
95
|
+
"""LlamaIndex reader for ServiceNow incidents."""
|
|
96
|
+
|
|
97
|
+
_loader_class = IncidentLoader
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class ServiceNowKBReader(_LlamaIndexAdapter):
|
|
101
|
+
"""LlamaIndex reader for ServiceNow Knowledge Base articles."""
|
|
102
|
+
|
|
103
|
+
_loader_class = KnowledgeBaseLoader
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ServiceNowCMDBReader(_LlamaIndexAdapter):
|
|
107
|
+
"""LlamaIndex reader for ServiceNow CMDB configuration items."""
|
|
108
|
+
|
|
109
|
+
_loader_class = CMDBLoader
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ServiceNowChangeReader(_LlamaIndexAdapter):
|
|
113
|
+
"""LlamaIndex reader for ServiceNow change requests."""
|
|
114
|
+
|
|
115
|
+
_loader_class = ChangeLoader
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ServiceNowProblemReader(_LlamaIndexAdapter):
|
|
119
|
+
"""LlamaIndex reader for ServiceNow problem records."""
|
|
120
|
+
|
|
121
|
+
_loader_class = ProblemLoader
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class ServiceNowCatalogReader(_LlamaIndexAdapter):
|
|
125
|
+
"""LlamaIndex reader for ServiceNow service catalog items."""
|
|
126
|
+
|
|
127
|
+
_loader_class = CatalogLoader
|