openwiki-server 0.3.2__tar.gz → 0.3.4__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.
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/PKG-INFO +1 -1
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/__init__.py +1 -1
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/adapters/openwiki.py +17 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/config.py +7 -2
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/interfaces/http_app.py +19 -4
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/persistence/sqlite_store.py +1 -1
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/pyproject.toml +1 -1
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/.gitignore +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/LICENSE +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/README.md +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/adapters/__init__.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/application/__init__.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/application/service.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/domain/__init__.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/domain/ids.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/domain/merge.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/domain/models.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/domain/wiki_config.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/errors.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/interfaces/__init__.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/interfaces/celery_app.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/interfaces/cli.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/interfaces/grpc_server.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/interfaces/mcp_server.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/logging_setup.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/persistence/__init__.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/protocol.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/openwiki_engine/runtime.py +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/proto/wiki/v1/wiki.proto +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/sdk/python/README.md +0 -0
- {openwiki_server-0.3.2 → openwiki_server-0.3.4}/sdk/python/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openwiki-server
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Lightweight SDK + Server for OpenWiki — wiki engine as standalone service with HTTP/gRPC/Celery/MCP/CLI interfaces and application integration SDK.
|
|
5
5
|
Author-email: shark8848 <admin@sharky-ai.com>
|
|
6
6
|
License: MIT
|
|
@@ -16,6 +16,7 @@ import os
|
|
|
16
16
|
import re
|
|
17
17
|
import shutil
|
|
18
18
|
import subprocess
|
|
19
|
+
from datetime import date, datetime
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
from typing import Any
|
|
21
22
|
|
|
@@ -30,6 +31,19 @@ MD_LINK_RE = re.compile(r"\[([^\]]+)\]\(([^)]+\.md)\)")
|
|
|
30
31
|
FIELD_RE = re.compile(r"^\s*([\u4e00-\u9fa5\w]+)[::]\s*(.+?)\s*$")
|
|
31
32
|
|
|
32
33
|
|
|
34
|
+
def _json_safe(value: Any) -> Any:
|
|
35
|
+
"""YAML front matter 的日期/时间归一化为 ISO 字符串,避免响应序列化失败。"""
|
|
36
|
+
if isinstance(value, datetime):
|
|
37
|
+
return value.isoformat()
|
|
38
|
+
if isinstance(value, date):
|
|
39
|
+
return value.isoformat()
|
|
40
|
+
if isinstance(value, list):
|
|
41
|
+
return [_json_safe(item) for item in value]
|
|
42
|
+
if isinstance(value, dict):
|
|
43
|
+
return {key: _json_safe(item) for key, item in value.items()}
|
|
44
|
+
return value
|
|
45
|
+
|
|
46
|
+
|
|
33
47
|
def openwiki_bin(settings: Settings | None = None) -> str:
|
|
34
48
|
settings = settings or Settings()
|
|
35
49
|
return settings.openwiki_bin_resolved()
|
|
@@ -55,6 +69,7 @@ def run_update(
|
|
|
55
69
|
settings: Settings | None = None,
|
|
56
70
|
) -> dict[str, Any]:
|
|
57
71
|
"""运行 `openwiki personal --update <message>`(非交互,stdin 关闭自动退出)。"""
|
|
72
|
+
wiki_root = os.path.abspath(wiki_root)
|
|
58
73
|
binary = openwiki_bin(settings)
|
|
59
74
|
cmd = [binary, "personal", "--update"]
|
|
60
75
|
if message:
|
|
@@ -106,6 +121,7 @@ def run_ingest(
|
|
|
106
121
|
timeout: int = 600,
|
|
107
122
|
) -> dict[str, Any]:
|
|
108
123
|
"""运行 `openwiki ingest <connector>`。"""
|
|
124
|
+
wiki_root = os.path.abspath(wiki_root)
|
|
109
125
|
binary = openwiki_bin(settings)
|
|
110
126
|
cmd = [binary, "ingest", connector]
|
|
111
127
|
env = dict(os.environ)
|
|
@@ -217,6 +233,7 @@ def parse_okf_pages(wiki_dir: str, *, kb_id: str = "") -> list[dict[str, Any]]:
|
|
|
217
233
|
for key, value in front.items()
|
|
218
234
|
if str(key) not in ("title", "type", "generated", "tags", "sources", "status", "stale_after", "stableKey")
|
|
219
235
|
}
|
|
236
|
+
fields = {key: _json_safe(value) for key, value in fields.items()}
|
|
220
237
|
status = str(front.get("status") or "active").strip().lower()
|
|
221
238
|
if status not in ("active", "deprecated"):
|
|
222
239
|
status = "active"
|
|
@@ -98,13 +98,18 @@ class Settings:
|
|
|
98
98
|
def resolved_db_path(self) -> str:
|
|
99
99
|
if self.db_path:
|
|
100
100
|
return self.db_path
|
|
101
|
-
data_dir = Path(self.
|
|
101
|
+
data_dir = Path(self.resolved_data_dir)
|
|
102
102
|
data_dir.mkdir(parents=True, exist_ok=True)
|
|
103
103
|
return str(data_dir / "engine.db")
|
|
104
104
|
|
|
105
|
+
@property
|
|
106
|
+
def resolved_data_dir(self) -> str:
|
|
107
|
+
"""数据目录绝对路径(openwiki 子进程 HOME/cwd 必须为绝对路径)。"""
|
|
108
|
+
return str(Path(self.data_dir).expanduser().resolve())
|
|
109
|
+
|
|
105
110
|
def wiki_root(self, wiki_id: str) -> str:
|
|
106
111
|
"""wiki 实例根目录:{data_dir}/wikis/{wiki_id}/(含 .openwiki/wiki 与 sources/)。"""
|
|
107
|
-
root = Path(self.
|
|
112
|
+
root = Path(self.resolved_data_dir) / "wikis" / wiki_id
|
|
108
113
|
root.mkdir(parents=True, exist_ok=True)
|
|
109
114
|
(root / ".openwiki" / "wiki").mkdir(parents=True, exist_ok=True)
|
|
110
115
|
(root / "sources").mkdir(parents=True, exist_ok=True)
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import json
|
|
6
|
+
from datetime import date, datetime
|
|
5
7
|
from typing import Any
|
|
6
8
|
|
|
7
9
|
from fastapi import FastAPI, Query, Request
|
|
@@ -14,13 +16,26 @@ from ..protocol import TRACE_ID_HEADER, error, new_trace_id, ok
|
|
|
14
16
|
from ..runtime import get_service
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
def _json_default(value: Any) -> str:
|
|
20
|
+
if isinstance(value, (datetime, date)):
|
|
21
|
+
return value.isoformat()
|
|
22
|
+
return str(value)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _JsonResponse(JSONResponse):
|
|
26
|
+
"""响应序列化兜底:datetime/date 等非标准类型转字符串,避免业务数据 500。"""
|
|
27
|
+
|
|
28
|
+
def render(self, content: Any) -> bytes:
|
|
29
|
+
return json.dumps(content, ensure_ascii=False, default=_json_default).encode("utf-8")
|
|
30
|
+
|
|
31
|
+
|
|
17
32
|
def _trace(request: Request) -> str:
|
|
18
33
|
return request.headers.get(TRACE_ID_HEADER) or new_trace_id()
|
|
19
34
|
|
|
20
35
|
|
|
21
36
|
def _handle(trace_id: str, fn) -> JSONResponse:
|
|
22
37
|
try:
|
|
23
|
-
return
|
|
38
|
+
return _JsonResponse(ok(trace_id, fn()))
|
|
24
39
|
except OpenWikiError as exc:
|
|
25
40
|
status = (
|
|
26
41
|
400
|
|
@@ -31,16 +46,16 @@ def _handle(trace_id: str, fn) -> JSONResponse:
|
|
|
31
46
|
if exc.code == "200409"
|
|
32
47
|
else 500
|
|
33
48
|
)
|
|
34
|
-
return
|
|
49
|
+
return _JsonResponse(error(trace_id, exc), status_code=status)
|
|
35
50
|
except Exception as exc: # pragma: no cover
|
|
36
|
-
return
|
|
51
|
+
return _JsonResponse(error(trace_id, exc), status_code=500)
|
|
37
52
|
|
|
38
53
|
|
|
39
54
|
def create_app(service: Any | None = None) -> FastAPI:
|
|
40
55
|
settings = Settings()
|
|
41
56
|
configure_logging(level=settings.log_level, log_center=settings.log_center)
|
|
42
57
|
svc = service or get_service()
|
|
43
|
-
app = FastAPI(title="OpenWiki Server", version="0.3.
|
|
58
|
+
app = FastAPI(title="OpenWiki Server", version="0.3.4")
|
|
44
59
|
|
|
45
60
|
@app.get("/health")
|
|
46
61
|
def health() -> dict[str, Any]:
|
|
@@ -88,7 +88,7 @@ class SqliteWikiStore:
|
|
|
88
88
|
# ---------- wiki 文件根目录 ----------
|
|
89
89
|
|
|
90
90
|
def wiki_root(self, wiki_id: str) -> str:
|
|
91
|
-
root = Path(self.data_dir) / "wikis" / wiki_id
|
|
91
|
+
root = Path(self.data_dir).expanduser().resolve() / "wikis" / wiki_id
|
|
92
92
|
root.mkdir(parents=True, exist_ok=True)
|
|
93
93
|
(root / ".openwiki" / "wiki").mkdir(parents=True, exist_ok=True)
|
|
94
94
|
(root / "sources").mkdir(parents=True, exist_ok=True)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openwiki-server"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.4"
|
|
8
8
|
description = "Lightweight SDK + Server for OpenWiki — wiki engine as standalone service with HTTP/gRPC/Celery/MCP/CLI interfaces and application integration SDK."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|