doc-store-client-dev 0.1.185__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.
- doc_store_client/__init__.py +194 -0
- doc_store_client/cli.py +192 -0
- doc_store_client/client.py +1509 -0
- doc_store_client/models.py +1635 -0
- doc_store_client/owned_document_cleanup.py +143 -0
- doc_store_client/py.typed +0 -0
- doc_store_client/text_verification.py +21 -0
- doc_store_client_cli.py +16 -0
- doc_store_client_dev-0.1.185.dist-info/METADATA +133 -0
- doc_store_client_dev-0.1.185.dist-info/RECORD +13 -0
- doc_store_client_dev-0.1.185.dist-info/WHEEL +5 -0
- doc_store_client_dev-0.1.185.dist-info/entry_points.txt +2 -0
- doc_store_client_dev-0.1.185.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Public API for the transport-neutral doc-store client package."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError as _PackageNotFoundError
|
|
4
|
+
from importlib.metadata import version as _distribution_version
|
|
5
|
+
from pathlib import Path as _Path
|
|
6
|
+
import tomllib as _tomllib
|
|
7
|
+
|
|
8
|
+
from .client import (
|
|
9
|
+
DOC_STORE_COMMANDS,
|
|
10
|
+
DocStoreClient,
|
|
11
|
+
DocStoreClientError,
|
|
12
|
+
DocStoreNotFoundError,
|
|
13
|
+
FileAlreadyLockedError,
|
|
14
|
+
LockServiceUnavailableError,
|
|
15
|
+
SessionNotFoundError,
|
|
16
|
+
)
|
|
17
|
+
from .owned_document_cleanup import OwnedDocumentCleanup, OwnedDocumentCleanupError
|
|
18
|
+
from .text_verification import text_verification_phrase
|
|
19
|
+
from .models import (
|
|
20
|
+
BackupEmergencyResult,
|
|
21
|
+
BackupInspectFile,
|
|
22
|
+
BackupInspectResult,
|
|
23
|
+
BackupPoint,
|
|
24
|
+
BackupPointsResult,
|
|
25
|
+
BackupRecoverCatalogResult,
|
|
26
|
+
BackupRestoreResult,
|
|
27
|
+
BackupRunResult,
|
|
28
|
+
BackupStatusResult,
|
|
29
|
+
ChapterGetRequest,
|
|
30
|
+
ChapterGetResult,
|
|
31
|
+
ChapterTextGetRequest,
|
|
32
|
+
ChunkHistoryRequest,
|
|
33
|
+
ChunkHistoryResult,
|
|
34
|
+
ChunkVersionAddRequest,
|
|
35
|
+
ChunkVersionAddResult,
|
|
36
|
+
ChunkVersionDeleteRequest,
|
|
37
|
+
ChunkVersionDeleteResult,
|
|
38
|
+
ChunkVersionDiffRequest,
|
|
39
|
+
ChunkVersionDiffResult,
|
|
40
|
+
ChunkVersionGetRequest,
|
|
41
|
+
ChunkVersionGetResult,
|
|
42
|
+
ChunkVersionItem,
|
|
43
|
+
ChunkVersionListRequest,
|
|
44
|
+
ChunkVersionListResult,
|
|
45
|
+
ChunkVersionRestoreRequest,
|
|
46
|
+
ChunkVersionRestoreResult,
|
|
47
|
+
ChunkVersionRetireRequest,
|
|
48
|
+
ChunkVersionRetireResult,
|
|
49
|
+
ChunkVersionSetCurrentRequest,
|
|
50
|
+
ChunkVersionSetCurrentResult,
|
|
51
|
+
ChunkVersionTextMutationRequest,
|
|
52
|
+
ChunkVersionUpdateRequest,
|
|
53
|
+
ChunkVersionUpdateResult,
|
|
54
|
+
DocumentChunkRequest,
|
|
55
|
+
DocumentChunkResult,
|
|
56
|
+
DocumentCreateRequest,
|
|
57
|
+
DocumentCreateResult,
|
|
58
|
+
DocumentDeleteRequest,
|
|
59
|
+
DocumentDeleteResult,
|
|
60
|
+
DocumentGetRequest,
|
|
61
|
+
DocumentGetResult,
|
|
62
|
+
DocumentRebindRequest,
|
|
63
|
+
DocumentRebindResult,
|
|
64
|
+
DocumentUpdateRequest,
|
|
65
|
+
DocumentUpdateResult,
|
|
66
|
+
DocumentWriteRequest,
|
|
67
|
+
DocumentWriteResult,
|
|
68
|
+
EntityGetRequest,
|
|
69
|
+
EntityGetResult,
|
|
70
|
+
EntityTextGetRequest,
|
|
71
|
+
EntityTextGetResult,
|
|
72
|
+
EntityIdsRequest,
|
|
73
|
+
EntityLifecycleResult,
|
|
74
|
+
EntityListRequest,
|
|
75
|
+
EntityListResult,
|
|
76
|
+
EntityOwnerTreeRequest,
|
|
77
|
+
EntityOwnerTreeResult,
|
|
78
|
+
EntityReferencesRequest,
|
|
79
|
+
EntityReferencesResult,
|
|
80
|
+
OperationState,
|
|
81
|
+
ParagraphGetByNumberRequest,
|
|
82
|
+
ParagraphGetByNumberResult,
|
|
83
|
+
ParagraphGetRequest,
|
|
84
|
+
ParagraphGetResult,
|
|
85
|
+
ProcessingStatusRequest,
|
|
86
|
+
ProcessingStatusResult,
|
|
87
|
+
RankedSearchHit,
|
|
88
|
+
RetrievalRequest,
|
|
89
|
+
RetrievalResult,
|
|
90
|
+
SearchResult,
|
|
91
|
+
ServerError,
|
|
92
|
+
SemanticChunkMetadataUpdateRequest,
|
|
93
|
+
SemanticChunkMetadataUpdateResult,
|
|
94
|
+
SourceFileReconstructRequest,
|
|
95
|
+
TextReconstructionRequest,
|
|
96
|
+
TextReconstructionResult,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
__version__ = _distribution_version("doc-store-client")
|
|
101
|
+
except _PackageNotFoundError:
|
|
102
|
+
_pyproject = _Path(__file__).resolve().parents[2] / "pyproject.toml"
|
|
103
|
+
__version__ = _tomllib.loads(_pyproject.read_text(encoding="utf-8"))["project"]["version"]
|
|
104
|
+
|
|
105
|
+
# The package includes ``py.typed`` in its distribution metadata.
|
|
106
|
+
__all__ = [
|
|
107
|
+
"BackupEmergencyResult",
|
|
108
|
+
"BackupInspectFile",
|
|
109
|
+
"BackupInspectResult",
|
|
110
|
+
"BackupPoint",
|
|
111
|
+
"BackupPointsResult",
|
|
112
|
+
"BackupRecoverCatalogResult",
|
|
113
|
+
"BackupRestoreResult",
|
|
114
|
+
"BackupRunResult",
|
|
115
|
+
"BackupStatusResult",
|
|
116
|
+
"ChapterGetRequest",
|
|
117
|
+
"ChapterGetResult",
|
|
118
|
+
"ChapterTextGetRequest",
|
|
119
|
+
"ChunkHistoryRequest",
|
|
120
|
+
"ChunkHistoryResult",
|
|
121
|
+
"ChunkVersionAddRequest",
|
|
122
|
+
"ChunkVersionAddResult",
|
|
123
|
+
"ChunkVersionDeleteRequest",
|
|
124
|
+
"ChunkVersionDeleteResult",
|
|
125
|
+
"ChunkVersionDiffRequest",
|
|
126
|
+
"ChunkVersionDiffResult",
|
|
127
|
+
"ChunkVersionGetRequest",
|
|
128
|
+
"ChunkVersionGetResult",
|
|
129
|
+
"ChunkVersionItem",
|
|
130
|
+
"ChunkVersionListRequest",
|
|
131
|
+
"ChunkVersionListResult",
|
|
132
|
+
"ChunkVersionRestoreRequest",
|
|
133
|
+
"ChunkVersionRestoreResult",
|
|
134
|
+
"ChunkVersionRetireRequest",
|
|
135
|
+
"ChunkVersionRetireResult",
|
|
136
|
+
"ChunkVersionSetCurrentRequest",
|
|
137
|
+
"ChunkVersionSetCurrentResult",
|
|
138
|
+
"ChunkVersionTextMutationRequest",
|
|
139
|
+
"ChunkVersionUpdateRequest",
|
|
140
|
+
"ChunkVersionUpdateResult",
|
|
141
|
+
"DOC_STORE_COMMANDS",
|
|
142
|
+
"DocStoreClient",
|
|
143
|
+
"DocStoreClientError",
|
|
144
|
+
"DocStoreNotFoundError",
|
|
145
|
+
"FileAlreadyLockedError",
|
|
146
|
+
"LockServiceUnavailableError",
|
|
147
|
+
"SessionNotFoundError",
|
|
148
|
+
"OwnedDocumentCleanup",
|
|
149
|
+
"OwnedDocumentCleanupError",
|
|
150
|
+
"DocumentCreateRequest",
|
|
151
|
+
"DocumentCreateResult",
|
|
152
|
+
"DocumentChunkRequest",
|
|
153
|
+
"DocumentChunkResult",
|
|
154
|
+
"DocumentDeleteRequest",
|
|
155
|
+
"DocumentDeleteResult",
|
|
156
|
+
"DocumentGetRequest",
|
|
157
|
+
"DocumentGetResult",
|
|
158
|
+
"DocumentRebindRequest",
|
|
159
|
+
"DocumentRebindResult",
|
|
160
|
+
"DocumentUpdateRequest",
|
|
161
|
+
"DocumentUpdateResult",
|
|
162
|
+
"DocumentWriteRequest",
|
|
163
|
+
"DocumentWriteResult",
|
|
164
|
+
"EntityGetRequest",
|
|
165
|
+
"EntityGetResult",
|
|
166
|
+
"EntityTextGetRequest",
|
|
167
|
+
"EntityTextGetResult",
|
|
168
|
+
"EntityIdsRequest",
|
|
169
|
+
"EntityLifecycleResult",
|
|
170
|
+
"EntityListRequest",
|
|
171
|
+
"EntityListResult",
|
|
172
|
+
"EntityOwnerTreeRequest",
|
|
173
|
+
"EntityOwnerTreeResult",
|
|
174
|
+
"EntityReferencesRequest",
|
|
175
|
+
"EntityReferencesResult",
|
|
176
|
+
"OperationState",
|
|
177
|
+
"ParagraphGetByNumberRequest",
|
|
178
|
+
"ParagraphGetByNumberResult",
|
|
179
|
+
"ParagraphGetRequest",
|
|
180
|
+
"ParagraphGetResult",
|
|
181
|
+
"ProcessingStatusRequest",
|
|
182
|
+
"ProcessingStatusResult",
|
|
183
|
+
"RankedSearchHit",
|
|
184
|
+
"RetrievalRequest",
|
|
185
|
+
"RetrievalResult",
|
|
186
|
+
"SearchResult",
|
|
187
|
+
"ServerError",
|
|
188
|
+
"SemanticChunkMetadataUpdateRequest",
|
|
189
|
+
"SemanticChunkMetadataUpdateResult",
|
|
190
|
+
"SourceFileReconstructRequest",
|
|
191
|
+
"TextReconstructionRequest",
|
|
192
|
+
"TextReconstructionResult",
|
|
193
|
+
"text_verification_phrase",
|
|
194
|
+
]
|
doc_store_client/cli.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Command line entrypoint for the installed doc-store client."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import asyncio
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
from urllib.parse import urlsplit
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class _AdapterBridge:
|
|
15
|
+
def __init__(self, client: Any) -> None:
|
|
16
|
+
self._client = client
|
|
17
|
+
|
|
18
|
+
async def execute_command_unified(
|
|
19
|
+
self, command: str, params: dict[str, Any], **kwargs: Any
|
|
20
|
+
) -> Any:
|
|
21
|
+
dispatch = getattr(self._client, "execute_command_unified", None)
|
|
22
|
+
if dispatch is None:
|
|
23
|
+
dispatch = getattr(self._client, "execute_command", None)
|
|
24
|
+
if dispatch is None:
|
|
25
|
+
raise TypeError("configured adapter exposes no supported command dispatch method")
|
|
26
|
+
result = await dispatch(command, params, **kwargs)
|
|
27
|
+
if isinstance(result, dict) and "error" in result:
|
|
28
|
+
return {
|
|
29
|
+
"success": False,
|
|
30
|
+
"code": "SERVER_ERROR",
|
|
31
|
+
"message": str(result["error"]),
|
|
32
|
+
"details": {},
|
|
33
|
+
}
|
|
34
|
+
return result
|
|
35
|
+
|
|
36
|
+
async def wait_for_job(self, job_id: str, **kwargs: Any) -> Any:
|
|
37
|
+
return await self._client.wait_for_job(job_id, **kwargs)
|
|
38
|
+
|
|
39
|
+
async def fetch_command_session_result(self, job_id: str) -> Any:
|
|
40
|
+
return await self._client.fetch_command_session_result(job_id)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _config_path(explicit: str | None) -> Path | None:
|
|
44
|
+
if explicit:
|
|
45
|
+
return Path(explicit).expanduser()
|
|
46
|
+
configured = os.environ.get("DOC_STORE_CLIENT_CONFIG")
|
|
47
|
+
if configured:
|
|
48
|
+
return Path(configured).expanduser()
|
|
49
|
+
current = Path.cwd().resolve()
|
|
50
|
+
for directory in (current, *current.parents):
|
|
51
|
+
candidate = directory / "doc-store-client.json"
|
|
52
|
+
if candidate.is_file():
|
|
53
|
+
return candidate
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _load_config(args: argparse.Namespace) -> dict[str, Any]:
|
|
58
|
+
path = _config_path(args.config)
|
|
59
|
+
config: dict[str, Any] = {}
|
|
60
|
+
if path is not None:
|
|
61
|
+
try:
|
|
62
|
+
value = json.loads(path.read_text(encoding="utf-8"))
|
|
63
|
+
except (OSError, json.JSONDecodeError) as exc:
|
|
64
|
+
raise ValueError(f"Unable to load configuration: {exc}") from exc
|
|
65
|
+
if not isinstance(value, dict):
|
|
66
|
+
raise ValueError("Configuration must be a JSON object")
|
|
67
|
+
config = value
|
|
68
|
+
if args.server_url:
|
|
69
|
+
config["server_url"] = args.server_url
|
|
70
|
+
elif os.environ.get("DOC_STORE_SERVER_URL"):
|
|
71
|
+
config.setdefault("server_url", os.environ["DOC_STORE_SERVER_URL"])
|
|
72
|
+
if not config.get("server_url"):
|
|
73
|
+
raise ValueError(
|
|
74
|
+
"No server URL configured; use --config, --server-url, "
|
|
75
|
+
"DOC_STORE_CLIENT_CONFIG, or DOC_STORE_SERVER_URL"
|
|
76
|
+
)
|
|
77
|
+
return config
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _params(text: str | None) -> dict[str, Any]:
|
|
81
|
+
if text is None:
|
|
82
|
+
return {}
|
|
83
|
+
try:
|
|
84
|
+
value = json.loads(text)
|
|
85
|
+
except json.JSONDecodeError as exc:
|
|
86
|
+
raise ValueError(f"--params must be a JSON object: {exc.msg}") from exc
|
|
87
|
+
if not isinstance(value, dict):
|
|
88
|
+
raise ValueError("--params must be a JSON object")
|
|
89
|
+
return value
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
async def _execute(args: argparse.Namespace) -> Any:
|
|
93
|
+
from mcp_proxy_adapter.client.jsonrpc_client import JsonRpcClient
|
|
94
|
+
|
|
95
|
+
from doc_store_client.client import DocStoreClient
|
|
96
|
+
|
|
97
|
+
config = _load_config(args)
|
|
98
|
+
parsed = urlsplit(str(config["server_url"]))
|
|
99
|
+
if not parsed.hostname:
|
|
100
|
+
raise ValueError("server_url must include a host")
|
|
101
|
+
protocol = str(config.get("protocol") or parsed.scheme or "http")
|
|
102
|
+
port = int(
|
|
103
|
+
config.get("port")
|
|
104
|
+
or parsed.port
|
|
105
|
+
or (443 if protocol in {"https", "mtls"} else 80)
|
|
106
|
+
)
|
|
107
|
+
transport = JsonRpcClient(
|
|
108
|
+
protocol=protocol,
|
|
109
|
+
host=str(config.get("host") or parsed.hostname),
|
|
110
|
+
port=port,
|
|
111
|
+
token_header=config.get("token_header"),
|
|
112
|
+
token=config.get("token"),
|
|
113
|
+
cert=config.get("cert"),
|
|
114
|
+
key=config.get("key"),
|
|
115
|
+
ca=config.get("ca"),
|
|
116
|
+
check_hostname=config.get("check_hostname"),
|
|
117
|
+
timeout=float(config["timeout"]) if config.get("timeout") is not None else None,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
async def emit_event(event: dict[str, Any]) -> None:
|
|
121
|
+
print(
|
|
122
|
+
json.dumps(event, ensure_ascii=False, separators=(",", ":")),
|
|
123
|
+
file=os.sys.stderr,
|
|
124
|
+
flush=True,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
client = DocStoreClient(_AdapterBridge(transport), event_callback=emit_event)
|
|
128
|
+
try:
|
|
129
|
+
if args.action == "call":
|
|
130
|
+
return await client.call(args.command, _params(args.params))
|
|
131
|
+
params = _params(args.params)
|
|
132
|
+
if args.file:
|
|
133
|
+
path = Path(args.file)
|
|
134
|
+
try:
|
|
135
|
+
payload = path.read_text(encoding="utf-8")
|
|
136
|
+
except OSError as exc:
|
|
137
|
+
raise ValueError(f"Unable to read --file: {exc}") from exc
|
|
138
|
+
params["raw_text"] = payload
|
|
139
|
+
return await client.call(args.action, params)
|
|
140
|
+
finally:
|
|
141
|
+
await transport.close()
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _parser() -> argparse.ArgumentParser:
|
|
145
|
+
parser = argparse.ArgumentParser(
|
|
146
|
+
prog="doc-store-client",
|
|
147
|
+
description="Execute doc-store server commands through the installed client.",
|
|
148
|
+
)
|
|
149
|
+
parser.add_argument("--config", help="JSON config path; defaults to nearest doc-store-client.json")
|
|
150
|
+
parser.add_argument("--server-url", help="Override the configured server URL")
|
|
151
|
+
sub = parser.add_subparsers(dest="action", required=True)
|
|
152
|
+
call = sub.add_parser("call", help="Call any server command with a JSON object")
|
|
153
|
+
call.add_argument("command", help="Server command name")
|
|
154
|
+
call.add_argument("--params", help="JSON object passed to the command")
|
|
155
|
+
for name in ("document-create", "document-update", "import"):
|
|
156
|
+
command = sub.add_parser(name, help=f"Run {name} through the client")
|
|
157
|
+
command.set_defaults(action={"document-create": "document_create", "document-update": "document_update", "import": "document_import"}[name])
|
|
158
|
+
command.add_argument("--params", help="JSON object passed to the command")
|
|
159
|
+
command.add_argument("--file", help="UTF-8 text file to use as the document source")
|
|
160
|
+
return parser
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def main() -> int:
|
|
164
|
+
args = _parser().parse_args()
|
|
165
|
+
try:
|
|
166
|
+
result = asyncio.run(_execute(args))
|
|
167
|
+
except Exception as exc:
|
|
168
|
+
message = str(exc)
|
|
169
|
+
lowered = message.lower()
|
|
170
|
+
code = "CLI_ERROR"
|
|
171
|
+
details: Any = {}
|
|
172
|
+
server_error = getattr(exc, "error", None)
|
|
173
|
+
if server_error is not None:
|
|
174
|
+
code = str(getattr(server_error, "code", "SERVER_ERROR"))
|
|
175
|
+
message = str(getattr(server_error, "message", message))
|
|
176
|
+
details = getattr(server_error, "details", {}) or {}
|
|
177
|
+
if "no module named" in lowered:
|
|
178
|
+
code = "CLIENT_RUNTIME_INCOMPATIBLE"
|
|
179
|
+
print(
|
|
180
|
+
json.dumps(
|
|
181
|
+
{"code": code, "message": message, "details": details},
|
|
182
|
+
ensure_ascii=False,
|
|
183
|
+
),
|
|
184
|
+
file=os.sys.stderr,
|
|
185
|
+
)
|
|
186
|
+
return 2
|
|
187
|
+
print(json.dumps(result, ensure_ascii=False, indent=2, default=str))
|
|
188
|
+
return 0
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
if __name__ == "__main__":
|
|
192
|
+
raise SystemExit(main())
|