gurucloud-kb 0.1.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,90 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ env/
8
+ build/
9
+ develop-eggs/
10
+ dist/
11
+ downloads/
12
+ eggs/
13
+ .eggs/
14
+ lib/
15
+ lib64/
16
+ parts/
17
+ sdist/
18
+ var/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ .playwright-mcp/
24
+ .pytest_cache/
25
+
26
+ # Virtual Environment
27
+ venv/
28
+ ENV/
29
+ .env
30
+
31
+ # IDE
32
+ .idea/
33
+ .vscode/
34
+ *.swp
35
+ *.swo
36
+
37
+ # Claude Code MCP config (contains user-specific tokens)
38
+ .mcp.json
39
+
40
+ # Docker
41
+ docker-compose.override.yml
42
+
43
+ # Database
44
+ *.sqlite3
45
+ *.db
46
+
47
+ # Project specific
48
+ application_default_credentials.json
49
+ *.log
50
+ local_cache/
51
+ local_files/
52
+
53
+ # Gmail API credentials (generated via admin UI)
54
+ credentials.json
55
+ token.json
56
+
57
+ # Logs directory
58
+ logs/
59
+
60
+ # OS specific
61
+ .DS_Store
62
+ Thumbs.db
63
+
64
+ # Secrets and credentials
65
+ *.pem
66
+ *.key
67
+ secrets/
68
+
69
+ # Initialization tracking
70
+ initialization_scripts/initialization_status.json
71
+
72
+ # Certbot/Let's Encrypt files (contain sensitive account data)
73
+ certbot/conf/accounts/
74
+ certbot/conf/live/
75
+ certbot/conf/renewal/
76
+ certbot/conf/archive/
77
+ certbot/conf/keys/
78
+
79
+ # Node.js
80
+ node_modules/
81
+ npm-debug.log*
82
+ yarn-debug.log*
83
+ yarn-error.log*
84
+ .npm/
85
+ .yarn/
86
+
87
+ gcloud_credentials.json
88
+ *.glb
89
+ *.blend
90
+ *.blend1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GuruCloud AI
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 all
13
+ 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 FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,184 @@
1
+ Metadata-Version: 2.4
2
+ Name: gurucloud-kb
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the GuruCloud Knowledge Bank API
5
+ Author-email: GuruCloud AI <support@gurucloudai.com>
6
+ License-File: LICENSE
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: httpx>=0.25.0
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
20
+ Requires-Dist: pytest>=7.0; extra == 'dev'
21
+ Requires-Dist: respx>=0.21; extra == 'dev'
22
+ Description-Content-Type: text/markdown
23
+
24
+ # GuruCloud KB SDK
25
+
26
+ Python SDK for the [GuruCloud Knowledge Bank API](https://www.gurucloudai.com/docs/kb).
27
+
28
+ **Full documentation**: [gurucloudai.com/docs/kb](https://www.gurucloudai.com/docs/kb)
29
+ **OpenAPI spec**: [gurucloudai.com/docs/kb/openapi.json](https://www.gurucloudai.com/docs/kb/openapi.json)
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ pip install gurucloud-kb
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ```python
40
+ from gurucloud_kb import GuruCloudClient
41
+
42
+ client = GuruCloudClient(api_key="kb_your_api_key")
43
+
44
+ # List your Knowledge Banks
45
+ kbs = client.list_kbs()
46
+
47
+ # Work with a specific KB
48
+ kb = client.get_kb("your-kb-uuid")
49
+
50
+ # Search
51
+ results = kb.search("how does authentication work?")
52
+ for r in results:
53
+ print(r["content"], r["combined_score"])
54
+
55
+ # Add an entry
56
+ kb.add_entry({
57
+ "dimensions": {
58
+ "content": "The auth service uses JWT tokens with RS256 signing.",
59
+ "useful_for": "Understanding authentication architecture",
60
+ }
61
+ })
62
+ ```
63
+
64
+ ## Async Support
65
+
66
+ ```python
67
+ from gurucloud_kb import AsyncGuruCloudClient
68
+
69
+ async with AsyncGuruCloudClient(api_key="kb_your_api_key") as client:
70
+ kb = await client.get_kb("your-kb-uuid")
71
+ results = await kb.search("deployment process")
72
+ ```
73
+
74
+ ## Key Features
75
+
76
+ - **Sync & async clients** — `GuruCloudClient` and `AsyncGuruCloudClient`
77
+ - **Knowledge Bank CRUD** — create, list, update, delete KBs
78
+ - **Entry management** — add, update, delete, batch ingest entries
79
+ - **Semantic search** — single-query or multi-dimensional weighted search
80
+ - **Schema management** — get, update, validate dimension schemas
81
+ - **MCP integration** — get MCP server definitions for agent injection
82
+ - **Deduplication events** — inspect how entries were deduplicated
83
+ - **Event logs** — trace entry processing lifecycle
84
+ - **API key management** — create, list, delete API keys
85
+ - **Typed responses** — all methods return TypedDict types for IDE autocomplete
86
+
87
+ ## Entry Management
88
+
89
+ ```python
90
+ # List entries
91
+ entries = kb.list_entries(limit=20, offset=0)
92
+
93
+ # Get a single entry
94
+ entry = kb.get_entry("entry-uuid")
95
+
96
+ # Update an entry
97
+ kb.update_entry("entry-uuid", {"dimensions": {"content": "Updated content"}})
98
+
99
+ # Delete
100
+ kb.delete_entry("entry-uuid")
101
+
102
+ # Batch ingest with deduplication
103
+ result = kb.ingest([
104
+ {"dimensions": {"content": "Fact 1", "useful_for": "Context 1"}},
105
+ {"dimensions": {"content": "Fact 2", "useful_for": "Context 2"}},
106
+ ], deduplicate=True)
107
+ print(f"Ingested: {result['ingested']}")
108
+ ```
109
+
110
+ ## Search
111
+
112
+ ```python
113
+ # Simple string search (searches the "content" dimension)
114
+ results = kb.search("authentication flow", k=5, threshold=0.6)
115
+
116
+ # Multi-dimensional weighted search
117
+ results = kb.search({
118
+ "dimensions": {
119
+ "content": {"query_text": "JWT tokens", "weight": 0.7},
120
+ "useful_for": {"query_text": "security audit", "weight": 0.3},
121
+ },
122
+ "k": 10,
123
+ "threshold": 0.5,
124
+ })
125
+ ```
126
+
127
+ ## MCP Integration
128
+
129
+ ```python
130
+ # Get MCP server definition for agent injection
131
+ mcp_def = kb.get_mcp_server_definition()
132
+
133
+ # Use in agent config:
134
+ mcp_config = {
135
+ "type": "http",
136
+ "url": mcp_def["url"],
137
+ "headers": {"Authorization": f"Bearer {mcp_def['token']}"}
138
+ }
139
+ ```
140
+
141
+ ## Deduplication Events
142
+
143
+ ```python
144
+ # List dedup events
145
+ events = kb.list_events(action="conflict", limit=20)
146
+
147
+ # Get full event details
148
+ event = kb.get_event("event-uuid")
149
+ print(event["reasoning"], event["action"])
150
+
151
+ # Entry processing logs
152
+ logs = kb.list_event_logs(event_type="dedup", limit=50)
153
+ ```
154
+
155
+ ## Error Handling
156
+
157
+ ```python
158
+ from gurucloud_kb import (
159
+ GuruCloudError,
160
+ AuthenticationError,
161
+ NotFoundError,
162
+ RateLimitError,
163
+ )
164
+
165
+ try:
166
+ kb = client.get_kb("bad-uuid")
167
+ except NotFoundError:
168
+ print("KB not found")
169
+ except AuthenticationError:
170
+ print("Invalid API key")
171
+ except RateLimitError:
172
+ print("Rate limited — slow down")
173
+ except GuruCloudError as e:
174
+ print(f"API error: {e.message}")
175
+ ```
176
+
177
+ ## Requirements
178
+
179
+ - Python 3.10+
180
+ - `httpx` >= 0.25.0
181
+
182
+ ## License
183
+
184
+ MIT
@@ -0,0 +1,161 @@
1
+ # GuruCloud KB SDK
2
+
3
+ Python SDK for the [GuruCloud Knowledge Bank API](https://www.gurucloudai.com/docs/kb).
4
+
5
+ **Full documentation**: [gurucloudai.com/docs/kb](https://www.gurucloudai.com/docs/kb)
6
+ **OpenAPI spec**: [gurucloudai.com/docs/kb/openapi.json](https://www.gurucloudai.com/docs/kb/openapi.json)
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ pip install gurucloud-kb
12
+ ```
13
+
14
+ ## Quick Start
15
+
16
+ ```python
17
+ from gurucloud_kb import GuruCloudClient
18
+
19
+ client = GuruCloudClient(api_key="kb_your_api_key")
20
+
21
+ # List your Knowledge Banks
22
+ kbs = client.list_kbs()
23
+
24
+ # Work with a specific KB
25
+ kb = client.get_kb("your-kb-uuid")
26
+
27
+ # Search
28
+ results = kb.search("how does authentication work?")
29
+ for r in results:
30
+ print(r["content"], r["combined_score"])
31
+
32
+ # Add an entry
33
+ kb.add_entry({
34
+ "dimensions": {
35
+ "content": "The auth service uses JWT tokens with RS256 signing.",
36
+ "useful_for": "Understanding authentication architecture",
37
+ }
38
+ })
39
+ ```
40
+
41
+ ## Async Support
42
+
43
+ ```python
44
+ from gurucloud_kb import AsyncGuruCloudClient
45
+
46
+ async with AsyncGuruCloudClient(api_key="kb_your_api_key") as client:
47
+ kb = await client.get_kb("your-kb-uuid")
48
+ results = await kb.search("deployment process")
49
+ ```
50
+
51
+ ## Key Features
52
+
53
+ - **Sync & async clients** — `GuruCloudClient` and `AsyncGuruCloudClient`
54
+ - **Knowledge Bank CRUD** — create, list, update, delete KBs
55
+ - **Entry management** — add, update, delete, batch ingest entries
56
+ - **Semantic search** — single-query or multi-dimensional weighted search
57
+ - **Schema management** — get, update, validate dimension schemas
58
+ - **MCP integration** — get MCP server definitions for agent injection
59
+ - **Deduplication events** — inspect how entries were deduplicated
60
+ - **Event logs** — trace entry processing lifecycle
61
+ - **API key management** — create, list, delete API keys
62
+ - **Typed responses** — all methods return TypedDict types for IDE autocomplete
63
+
64
+ ## Entry Management
65
+
66
+ ```python
67
+ # List entries
68
+ entries = kb.list_entries(limit=20, offset=0)
69
+
70
+ # Get a single entry
71
+ entry = kb.get_entry("entry-uuid")
72
+
73
+ # Update an entry
74
+ kb.update_entry("entry-uuid", {"dimensions": {"content": "Updated content"}})
75
+
76
+ # Delete
77
+ kb.delete_entry("entry-uuid")
78
+
79
+ # Batch ingest with deduplication
80
+ result = kb.ingest([
81
+ {"dimensions": {"content": "Fact 1", "useful_for": "Context 1"}},
82
+ {"dimensions": {"content": "Fact 2", "useful_for": "Context 2"}},
83
+ ], deduplicate=True)
84
+ print(f"Ingested: {result['ingested']}")
85
+ ```
86
+
87
+ ## Search
88
+
89
+ ```python
90
+ # Simple string search (searches the "content" dimension)
91
+ results = kb.search("authentication flow", k=5, threshold=0.6)
92
+
93
+ # Multi-dimensional weighted search
94
+ results = kb.search({
95
+ "dimensions": {
96
+ "content": {"query_text": "JWT tokens", "weight": 0.7},
97
+ "useful_for": {"query_text": "security audit", "weight": 0.3},
98
+ },
99
+ "k": 10,
100
+ "threshold": 0.5,
101
+ })
102
+ ```
103
+
104
+ ## MCP Integration
105
+
106
+ ```python
107
+ # Get MCP server definition for agent injection
108
+ mcp_def = kb.get_mcp_server_definition()
109
+
110
+ # Use in agent config:
111
+ mcp_config = {
112
+ "type": "http",
113
+ "url": mcp_def["url"],
114
+ "headers": {"Authorization": f"Bearer {mcp_def['token']}"}
115
+ }
116
+ ```
117
+
118
+ ## Deduplication Events
119
+
120
+ ```python
121
+ # List dedup events
122
+ events = kb.list_events(action="conflict", limit=20)
123
+
124
+ # Get full event details
125
+ event = kb.get_event("event-uuid")
126
+ print(event["reasoning"], event["action"])
127
+
128
+ # Entry processing logs
129
+ logs = kb.list_event_logs(event_type="dedup", limit=50)
130
+ ```
131
+
132
+ ## Error Handling
133
+
134
+ ```python
135
+ from gurucloud_kb import (
136
+ GuruCloudError,
137
+ AuthenticationError,
138
+ NotFoundError,
139
+ RateLimitError,
140
+ )
141
+
142
+ try:
143
+ kb = client.get_kb("bad-uuid")
144
+ except NotFoundError:
145
+ print("KB not found")
146
+ except AuthenticationError:
147
+ print("Invalid API key")
148
+ except RateLimitError:
149
+ print("Rate limited — slow down")
150
+ except GuruCloudError as e:
151
+ print(f"API error: {e.message}")
152
+ ```
153
+
154
+ ## Requirements
155
+
156
+ - Python 3.10+
157
+ - `httpx` >= 0.25.0
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "gurucloud-kb"
7
+ version = "0.1.0"
8
+ description = "Python SDK for the GuruCloud Knowledge Bank API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [
12
+ { name = "GuruCloud AI", email = "support@gurucloudai.com" },
13
+ ]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "httpx>=0.25.0",
27
+ ]
28
+
29
+ [project.optional-dependencies]
30
+ dev = [
31
+ "pytest>=7.0",
32
+ "pytest-asyncio>=0.21",
33
+ "respx>=0.21",
34
+ ]
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/gurucloud_kb"]
38
+
39
+ [tool.pyright]
40
+ pythonVersion = "3.10"
41
+ typeCheckingMode = "strict"
@@ -0,0 +1,90 @@
1
+ """GuruCloud Knowledge Bank SDK.
2
+
3
+ Example::
4
+
5
+ from gurucloud_kb import GuruCloudClient
6
+
7
+ client = GuruCloudClient(api_key="kb_abc123...")
8
+
9
+ # List all KBs
10
+ kbs = client.list_kbs()
11
+
12
+ # Work with a specific KB
13
+ kb = client.get_kb("my-kb-uuid")
14
+ results = kb.search("how does auth work?")
15
+
16
+ # Get MCP server definition for agent injection
17
+ mcp_def = kb.get_mcp_server_definition()
18
+ """
19
+
20
+ from gurucloud_kb.async_client import AsyncGuruCloudClient
21
+ from gurucloud_kb.async_kb import AsyncKnowledgeBank
22
+ from gurucloud_kb.client import GuruCloudClient
23
+ from gurucloud_kb.errors import (
24
+ APIError,
25
+ AuthenticationError,
26
+ ConnectionError,
27
+ GuruCloudError,
28
+ NotFoundError,
29
+ PermissionError,
30
+ RateLimitError,
31
+ )
32
+ from gurucloud_kb.kb import KnowledgeBank
33
+ from gurucloud_kb.types import (
34
+ APIKeyInfo,
35
+ BatchIngestResult,
36
+ CategoryConfig,
37
+ DeduplicationEvent,
38
+ DeduplicationEventList,
39
+ DeduplicationEventSummary,
40
+ DimensionConfig,
41
+ DimensionQuery,
42
+ DimensionSchema,
43
+ EntryEventLog,
44
+ EntryEventLogList,
45
+ EntryInput,
46
+ EntryResult,
47
+ KBInfo,
48
+ MCPServerDefinition,
49
+ SchemaWarning,
50
+ SearchRequest,
51
+ SearchResult,
52
+ )
53
+
54
+ __all__ = [
55
+ # Sync client
56
+ "GuruCloudClient",
57
+ "KnowledgeBank",
58
+ # Async client
59
+ "AsyncGuruCloudClient",
60
+ "AsyncKnowledgeBank",
61
+ # Errors
62
+ "GuruCloudError",
63
+ "APIError",
64
+ "AuthenticationError",
65
+ "PermissionError",
66
+ "NotFoundError",
67
+ "RateLimitError",
68
+ "ConnectionError",
69
+ # Types
70
+ "KBInfo",
71
+ "DimensionConfig",
72
+ "CategoryConfig",
73
+ "DimensionSchema",
74
+ "SchemaWarning",
75
+ "EntryInput",
76
+ "EntryResult",
77
+ "DimensionQuery",
78
+ "SearchRequest",
79
+ "SearchResult",
80
+ "MCPServerDefinition",
81
+ "APIKeyInfo",
82
+ "BatchIngestResult",
83
+ "DeduplicationEvent",
84
+ "DeduplicationEventSummary",
85
+ "DeduplicationEventList",
86
+ "EntryEventLog",
87
+ "EntryEventLogList",
88
+ ]
89
+
90
+ __version__ = "0.1.0"
@@ -0,0 +1,112 @@
1
+ """Async HTTP transport for the GuruCloud KB SDK.
2
+
3
+ Wraps httpx.AsyncClient to provide:
4
+ - Automatic Bearer token injection
5
+ - Response envelope unwrapping (``{"data": ...}``)
6
+ - Typed error raising
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any
12
+
13
+ import httpx
14
+
15
+ from gurucloud_kb.errors import (
16
+ APIError,
17
+ AuthenticationError,
18
+ ConnectionError,
19
+ NotFoundError,
20
+ PermissionError,
21
+ RateLimitError,
22
+ )
23
+
24
+ _DEFAULT_TIMEOUT = 30.0
25
+
26
+
27
+ class AsyncHTTPClient:
28
+ """Async wrapper around httpx for the KB API."""
29
+
30
+ def __init__(
31
+ self,
32
+ base_url: str,
33
+ api_key: str,
34
+ timeout: float = _DEFAULT_TIMEOUT,
35
+ ) -> None:
36
+ self._base_url = base_url.rstrip("/")
37
+ self._client = httpx.AsyncClient(
38
+ base_url=f"{self._base_url}/api/v1/kb",
39
+ headers={
40
+ "Authorization": f"Bearer {api_key}",
41
+ "Content-Type": "application/json",
42
+ },
43
+ timeout=timeout,
44
+ )
45
+
46
+ # ── public verbs ────────────────────────────────────────────
47
+
48
+ async def get(self, path: str, params: dict[str, Any] | None = None) -> Any:
49
+ return await self._request("GET", path, params=params)
50
+
51
+ async def post(self, path: str, json: Any = None) -> Any:
52
+ return await self._request("POST", path, json=json)
53
+
54
+ async def put(self, path: str, json: Any = None) -> Any:
55
+ return await self._request("PUT", path, json=json)
56
+
57
+ async def patch(self, path: str, json: Any = None) -> Any:
58
+ return await self._request("PATCH", path, json=json)
59
+
60
+ async def delete(self, path: str) -> Any:
61
+ return await self._request("DELETE", path)
62
+
63
+ async def close(self) -> None:
64
+ await self._client.aclose()
65
+
66
+ # ── internals ───────────────────────────────────────────────
67
+
68
+ async def _request(
69
+ self,
70
+ method: str,
71
+ path: str,
72
+ params: dict[str, Any] | None = None,
73
+ json: Any = None,
74
+ ) -> Any:
75
+ try:
76
+ resp = await self._client.request(method, path, params=params, json=json)
77
+ except httpx.ConnectError as exc:
78
+ raise ConnectionError(f"Cannot reach {self._base_url}: {exc}") from exc
79
+ except httpx.TimeoutException as exc:
80
+ raise ConnectionError(f"Request timed out: {exc}") from exc
81
+
82
+ if resp.status_code >= 400:
83
+ self._raise_for_status(resp)
84
+
85
+ # The API wraps successful responses in {"data": ...}
86
+ body = resp.json()
87
+ if isinstance(body, dict) and "data" in body:
88
+ return body["data"]
89
+ return body
90
+
91
+ @staticmethod
92
+ def _raise_for_status(resp: httpx.Response) -> None:
93
+ """Map HTTP error responses to typed SDK exceptions."""
94
+ try:
95
+ body = resp.json()
96
+ except Exception:
97
+ raise APIError(resp.status_code, "unknown", resp.text)
98
+
99
+ error = body.get("error", {})
100
+ code = error.get("code", "unknown") if isinstance(error, dict) else "unknown"
101
+ message = error.get("message", resp.text) if isinstance(error, dict) else str(error)
102
+
103
+ status = resp.status_code
104
+ if status == 401:
105
+ raise AuthenticationError(code, message)
106
+ if status == 403:
107
+ raise PermissionError(code, message)
108
+ if status == 404:
109
+ raise NotFoundError(code, message)
110
+ if status == 429:
111
+ raise RateLimitError(code, message)
112
+ raise APIError(status, code, message)