upp-python 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.
- upp/__init__.py +183 -0
- upp/backends/.gitkeep +0 -0
- upp/backends/__init__.py +23 -0
- upp/backends/ingest.py +122 -0
- upp/backends/ontology.py +41 -0
- upp/backends/retriever.py +79 -0
- upp/client.py +148 -0
- upp/models/.gitkeep +0 -0
- upp/models/__init__.py +38 -0
- upp/models/client.py +113 -0
- upp/models/enums.py +124 -0
- upp/models/events.py +124 -0
- upp/models/labels.py +71 -0
- upp/ontologies/__init__.py +0 -0
- upp/ontologies/user_v1.py +112 -0
- upp/py.typed +0 -0
- upp/rpc/.gitkeep +0 -0
- upp/rpc/__init__.py +137 -0
- upp/rpc/codec.py +112 -0
- upp/rpc/errors.py +127 -0
- upp/rpc/messages.py +354 -0
- upp/rpc/methods.py +73 -0
- upp_python-0.1.0.dist-info/METADATA +137 -0
- upp_python-0.1.0.dist-info/RECORD +25 -0
- upp_python-0.1.0.dist-info/WHEEL +4 -0
upp/rpc/codec.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""UPP JSON-RPC 2.0 Codec.
|
|
2
|
+
|
|
3
|
+
Provides functions for encoding and decoding JSON-RPC 2.0 messages as
|
|
4
|
+
JSON strings. The codec handles serialization/deserialization between
|
|
5
|
+
:class:`JsonRpcRequest`/:class:`JsonRpcResponse` Pydantic models and
|
|
6
|
+
their JSON wire format.
|
|
7
|
+
|
|
8
|
+
Usage::
|
|
9
|
+
|
|
10
|
+
from upp.rpc.codec import encode_request, decode_response
|
|
11
|
+
|
|
12
|
+
wire = encode_request("upp/ingest", {"entity_key": "u1", "text": "..."}, request_id=1)
|
|
13
|
+
response = decode_response(wire_response)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from upp.rpc.messages import JsonRpcError, JsonRpcRequest, JsonRpcResponse
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"decode_request",
|
|
25
|
+
"decode_response",
|
|
26
|
+
"encode_request",
|
|
27
|
+
"encode_response",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def encode_request(
|
|
32
|
+
method: str,
|
|
33
|
+
params: dict[str, Any],
|
|
34
|
+
request_id: int | str,
|
|
35
|
+
) -> str:
|
|
36
|
+
"""Encode a JSON-RPC 2.0 request as a JSON string.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
method: The method name (e.g., ``"upp/ingest"``).
|
|
40
|
+
params: The method parameters as a dictionary.
|
|
41
|
+
request_id: Unique request identifier.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
A JSON string representing the full JSON-RPC 2.0 request.
|
|
45
|
+
"""
|
|
46
|
+
request = JsonRpcRequest(
|
|
47
|
+
id=request_id,
|
|
48
|
+
method=method,
|
|
49
|
+
params=params,
|
|
50
|
+
)
|
|
51
|
+
return request.model_dump_json()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def decode_request(data: str) -> JsonRpcRequest:
|
|
55
|
+
"""Decode a JSON string into a :class:`JsonRpcRequest`.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
data: A JSON string representing a JSON-RPC 2.0 request.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
A validated :class:`JsonRpcRequest` instance.
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
pydantic.ValidationError: If the JSON does not conform to the
|
|
65
|
+
JSON-RPC 2.0 request schema.
|
|
66
|
+
json.JSONDecodeError: If the string is not valid JSON.
|
|
67
|
+
"""
|
|
68
|
+
parsed = json.loads(data)
|
|
69
|
+
return JsonRpcRequest.model_validate(parsed)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def encode_response(
|
|
73
|
+
request_id: int | str | None,
|
|
74
|
+
result: dict[str, Any] | None = None,
|
|
75
|
+
error: JsonRpcError | None = None,
|
|
76
|
+
) -> str:
|
|
77
|
+
"""Encode a JSON-RPC 2.0 response as a JSON string.
|
|
78
|
+
|
|
79
|
+
Either ``result`` or ``error`` should be provided, but not both.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
request_id: The matching request identifier.
|
|
83
|
+
result: The result value on success.
|
|
84
|
+
error: The error object on failure.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
A JSON string representing the full JSON-RPC 2.0 response.
|
|
88
|
+
"""
|
|
89
|
+
response = JsonRpcResponse(
|
|
90
|
+
id=request_id,
|
|
91
|
+
result=result,
|
|
92
|
+
error=error,
|
|
93
|
+
)
|
|
94
|
+
return response.model_dump_json()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def decode_response(data: str) -> JsonRpcResponse:
|
|
98
|
+
"""Decode a JSON string into a :class:`JsonRpcResponse`.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
data: A JSON string representing a JSON-RPC 2.0 response.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
A validated :class:`JsonRpcResponse` instance.
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
pydantic.ValidationError: If the JSON does not conform to the
|
|
108
|
+
JSON-RPC 2.0 response schema.
|
|
109
|
+
json.JSONDecodeError: If the string is not valid JSON.
|
|
110
|
+
"""
|
|
111
|
+
parsed = json.loads(data)
|
|
112
|
+
return JsonRpcResponse.model_validate(parsed)
|
upp/rpc/errors.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""UPP Error Codes and Exception Class.
|
|
2
|
+
|
|
3
|
+
Defines all standard JSON-RPC 2.0 error codes, UPP-specific error codes,
|
|
4
|
+
and the :class:`UppError` exception class used throughout the protocol.
|
|
5
|
+
|
|
6
|
+
Standard JSON-RPC Error Codes:
|
|
7
|
+
-32700 Parse error
|
|
8
|
+
-32600 Invalid Request
|
|
9
|
+
-32601 Method not found
|
|
10
|
+
-32602 Invalid params
|
|
11
|
+
-32603 Internal error
|
|
12
|
+
|
|
13
|
+
UPP-Specific Error Codes (-32001 to -32099):
|
|
14
|
+
-32001 User not found
|
|
15
|
+
-32002 Ontology not found
|
|
16
|
+
-32003 Ingest failed
|
|
17
|
+
-32004 Extraction failed
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from upp.rpc.messages import JsonRpcError
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
# Standard JSON-RPC error codes
|
|
26
|
+
"INTERNAL_ERROR",
|
|
27
|
+
"INVALID_PARAMS",
|
|
28
|
+
"INVALID_REQUEST",
|
|
29
|
+
"METHOD_NOT_FOUND",
|
|
30
|
+
"PARSE_ERROR",
|
|
31
|
+
# UPP-specific error codes
|
|
32
|
+
"EXTRACTION_FAILED",
|
|
33
|
+
"ONTOLOGY_NOT_FOUND",
|
|
34
|
+
"INGEST_FAILED",
|
|
35
|
+
"USER_NOT_FOUND",
|
|
36
|
+
# Exception class
|
|
37
|
+
"UppError",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
# Standard JSON-RPC 2.0 Error Codes
|
|
42
|
+
# ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
#: Invalid JSON received by the server.
|
|
45
|
+
PARSE_ERROR: int = -32700
|
|
46
|
+
|
|
47
|
+
#: The JSON is valid but not a valid JSON-RPC 2.0 request.
|
|
48
|
+
INVALID_REQUEST: int = -32600
|
|
49
|
+
|
|
50
|
+
#: The requested method does not exist or is not available.
|
|
51
|
+
METHOD_NOT_FOUND: int = -32601
|
|
52
|
+
|
|
53
|
+
#: Invalid method parameter(s).
|
|
54
|
+
INVALID_PARAMS: int = -32602
|
|
55
|
+
|
|
56
|
+
#: Internal JSON-RPC error.
|
|
57
|
+
INTERNAL_ERROR: int = -32603
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# UPP-Specific Error Codes (-32001 to -32099)
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
#: The specified ``entity_key`` does not exist.
|
|
64
|
+
USER_NOT_FOUND: int = -32001
|
|
65
|
+
|
|
66
|
+
#: The requested ontology does not exist.
|
|
67
|
+
ONTOLOGY_NOT_FOUND: int = -32002
|
|
68
|
+
|
|
69
|
+
#: Error persisting events during ingestion.
|
|
70
|
+
INGEST_FAILED: int = -32003
|
|
71
|
+
|
|
72
|
+
#: Error extracting events from text.
|
|
73
|
+
EXTRACTION_FAILED: int = -32004
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# ---------------------------------------------------------------------------
|
|
77
|
+
# Exception Class
|
|
78
|
+
# ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class UppError(Exception):
|
|
82
|
+
"""Exception representing a UPP protocol error.
|
|
83
|
+
|
|
84
|
+
Can be raised by any backend or the client when a protocol-level
|
|
85
|
+
error occurs. Provides a :meth:`to_jsonrpc_error` method for
|
|
86
|
+
converting to a :class:`JsonRpcError`.
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
code: The numeric error code.
|
|
90
|
+
message: A human-readable description of the error.
|
|
91
|
+
data: Optional additional structured error data.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
code: int,
|
|
97
|
+
message: str,
|
|
98
|
+
data: dict[str, object] | None = None,
|
|
99
|
+
) -> None:
|
|
100
|
+
"""Initialize a UPP error.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
code: The numeric error code.
|
|
104
|
+
message: A human-readable description.
|
|
105
|
+
data: Optional structured data providing additional context.
|
|
106
|
+
"""
|
|
107
|
+
super().__init__(message)
|
|
108
|
+
self.code = code
|
|
109
|
+
self.message = message
|
|
110
|
+
self.data = data
|
|
111
|
+
|
|
112
|
+
def to_jsonrpc_error(self) -> JsonRpcError:
|
|
113
|
+
"""Convert this exception to a :class:`JsonRpcError` object.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
A :class:`JsonRpcError` suitable for inclusion in a
|
|
117
|
+
:class:`JsonRpcResponse`.
|
|
118
|
+
"""
|
|
119
|
+
return JsonRpcError(
|
|
120
|
+
code=self.code,
|
|
121
|
+
message=self.message,
|
|
122
|
+
data=self.data,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def __repr__(self) -> str:
|
|
126
|
+
"""Return a developer-friendly string representation."""
|
|
127
|
+
return f"UppError(code={self.code}, message={self.message!r})"
|
upp/rpc/messages.py
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"""UPP JSON-RPC 2.0 Message Types and Operation Models.
|
|
2
|
+
|
|
3
|
+
Defines Pydantic models for the four JSON-RPC 2.0 message types and
|
|
4
|
+
typed request/response models for all ten UPP operations.
|
|
5
|
+
|
|
6
|
+
JSON-RPC Message Types:
|
|
7
|
+
JsonRpcRequest, JsonRpcResponse, JsonRpcError, JsonRpcNotification
|
|
8
|
+
|
|
9
|
+
Operation Request/Response Models:
|
|
10
|
+
IngestRequest/IngestResponse, RetrieveRequest/RetrieveResponse,
|
|
11
|
+
EventsRequest/EventsResponse, DeleteRequest/DeleteResponse,
|
|
12
|
+
InfoRequest/InfoResponse, LabelsRequest/LabelsResponse,
|
|
13
|
+
ExportRequest/ExportResponse, ImportRequest/ImportResponse
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from typing import Any, Literal
|
|
20
|
+
|
|
21
|
+
from pydantic import BaseModel, Field
|
|
22
|
+
|
|
23
|
+
from upp.models.events import Event, StoredEvent, TaskResult
|
|
24
|
+
from upp.models.labels import LabelDefinition
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
# JSON-RPC base types
|
|
28
|
+
"JsonRpcError",
|
|
29
|
+
"JsonRpcNotification",
|
|
30
|
+
"JsonRpcRequest",
|
|
31
|
+
"JsonRpcResponse",
|
|
32
|
+
# Operation request/response models
|
|
33
|
+
"ContextualizeRequest",
|
|
34
|
+
"ContextualizeResponse",
|
|
35
|
+
"DeleteRequest",
|
|
36
|
+
"DeleteResponse",
|
|
37
|
+
"EventsRequest",
|
|
38
|
+
"EventsResponse",
|
|
39
|
+
"ExportRequest",
|
|
40
|
+
"ExportResponse",
|
|
41
|
+
"GetTasksRequest",
|
|
42
|
+
"GetTasksResponse",
|
|
43
|
+
"ImportRequest",
|
|
44
|
+
"ImportResponse",
|
|
45
|
+
"InfoRequest",
|
|
46
|
+
"InfoResponse",
|
|
47
|
+
"LabelsRequest",
|
|
48
|
+
"LabelsResponse",
|
|
49
|
+
"RetrieveRequest",
|
|
50
|
+
"RetrieveResponse",
|
|
51
|
+
"IngestRequest",
|
|
52
|
+
"IngestResponse",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ---------------------------------------------------------------------------
|
|
57
|
+
# JSON-RPC 2.0 Base Types
|
|
58
|
+
# ---------------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class JsonRpcError(BaseModel):
|
|
62
|
+
"""JSON-RPC 2.0 error object.
|
|
63
|
+
|
|
64
|
+
Attributes:
|
|
65
|
+
code: A number indicating the error type.
|
|
66
|
+
message: A short, human-readable description of the error.
|
|
67
|
+
data: Additional structured data about the error (optional).
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
code: int = Field(description="A number indicating the error type.")
|
|
71
|
+
message: str = Field(description="A short, human-readable description of the error.")
|
|
72
|
+
data: dict[str, Any] | None = Field(
|
|
73
|
+
default=None,
|
|
74
|
+
description="Additional structured data about the error.",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class JsonRpcRequest(BaseModel):
|
|
79
|
+
"""JSON-RPC 2.0 request message.
|
|
80
|
+
|
|
81
|
+
Attributes:
|
|
82
|
+
jsonrpc: Protocol version, always ``"2.0"``.
|
|
83
|
+
id: Unique request identifier.
|
|
84
|
+
method: The name of the method to invoke.
|
|
85
|
+
params: Method parameters as a dictionary.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
jsonrpc: Literal["2.0"] = Field(
|
|
89
|
+
default="2.0",
|
|
90
|
+
description='JSON-RPC protocol version. Always "2.0".',
|
|
91
|
+
)
|
|
92
|
+
id: int | str = Field(description="Unique request identifier.")
|
|
93
|
+
method: str = Field(description="The name of the method to invoke.")
|
|
94
|
+
params: dict[str, Any] = Field(
|
|
95
|
+
default_factory=dict,
|
|
96
|
+
description="Method parameters as a dictionary.",
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class JsonRpcResponse(BaseModel):
|
|
101
|
+
"""JSON-RPC 2.0 response message.
|
|
102
|
+
|
|
103
|
+
Contains either ``result`` (success) or ``error`` (failure), not both.
|
|
104
|
+
|
|
105
|
+
Attributes:
|
|
106
|
+
jsonrpc: Protocol version, always ``"2.0"``.
|
|
107
|
+
id: Matching request identifier.
|
|
108
|
+
result: The result value on success.
|
|
109
|
+
error: The error object on failure.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
jsonrpc: Literal["2.0"] = Field(
|
|
113
|
+
default="2.0",
|
|
114
|
+
description='JSON-RPC protocol version. Always "2.0".',
|
|
115
|
+
)
|
|
116
|
+
id: int | str | None = Field(default=None, description="Matching request identifier.")
|
|
117
|
+
result: dict[str, Any] | None = Field(
|
|
118
|
+
default=None,
|
|
119
|
+
description="The result value on success.",
|
|
120
|
+
)
|
|
121
|
+
error: JsonRpcError | None = Field(
|
|
122
|
+
default=None,
|
|
123
|
+
description="The error object on failure.",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class JsonRpcNotification(BaseModel):
|
|
128
|
+
"""JSON-RPC 2.0 notification message (fire-and-forget, no ``id``).
|
|
129
|
+
|
|
130
|
+
Attributes:
|
|
131
|
+
jsonrpc: Protocol version, always ``"2.0"``.
|
|
132
|
+
method: The name of the method to invoke.
|
|
133
|
+
params: Method parameters as a dictionary.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
jsonrpc: Literal["2.0"] = Field(
|
|
137
|
+
default="2.0",
|
|
138
|
+
description='JSON-RPC protocol version. Always "2.0".',
|
|
139
|
+
)
|
|
140
|
+
method: str = Field(description="The name of the method to invoke.")
|
|
141
|
+
params: dict[str, Any] | None = Field(
|
|
142
|
+
default=None,
|
|
143
|
+
description="Method parameters as a dictionary.",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# ---------------------------------------------------------------------------
|
|
148
|
+
# UPP Operation Request/Response Models
|
|
149
|
+
# ---------------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class IngestRequest(BaseModel):
|
|
153
|
+
"""Request model for ``upp/ingest``.
|
|
154
|
+
|
|
155
|
+
Attributes:
|
|
156
|
+
entity_key: Identifier of the user.
|
|
157
|
+
text: Text from which to extract events.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
entity_key: str = Field(description="Identifier of the user.")
|
|
161
|
+
text: str = Field(description="Text from which to extract events.")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class IngestResponse(BaseModel):
|
|
165
|
+
"""Response model for ``upp/ingest``.
|
|
166
|
+
|
|
167
|
+
Attributes:
|
|
168
|
+
events: The stored events with server-assigned metadata.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
events: list[StoredEvent] = Field(description="The stored events.")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class RetrieveRequest(BaseModel):
|
|
175
|
+
"""Request model for ``upp/retrieve``.
|
|
176
|
+
|
|
177
|
+
Attributes:
|
|
178
|
+
entity_key: Identifier of the user.
|
|
179
|
+
query: Free-text query for relevance matching.
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
entity_key: str = Field(description="Identifier of the user.")
|
|
183
|
+
query: str = Field(description="Free-text query for relevance matching.")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class RetrieveResponse(BaseModel):
|
|
187
|
+
"""Response model for ``upp/retrieve``.
|
|
188
|
+
|
|
189
|
+
Attributes:
|
|
190
|
+
events: Relevant events ranked by the server.
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
events: list[Event] = Field(description="Relevant events ranked by the server.")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class EventsRequest(BaseModel):
|
|
197
|
+
"""Request model for ``upp/events``.
|
|
198
|
+
|
|
199
|
+
Attributes:
|
|
200
|
+
entity_key: Identifier of the user.
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
entity_key: str = Field(description="Identifier of the user.")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class EventsResponse(BaseModel):
|
|
207
|
+
"""Response model for ``upp/events``.
|
|
208
|
+
|
|
209
|
+
Attributes:
|
|
210
|
+
events: All stored events for the user.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
events: list[StoredEvent] = Field(description="All stored events for the user.")
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class DeleteRequest(BaseModel):
|
|
217
|
+
"""Request model for ``upp/delete``.
|
|
218
|
+
|
|
219
|
+
Attributes:
|
|
220
|
+
entity_key: Identifier of the user.
|
|
221
|
+
event_ids: Specific event IDs to delete. If not provided, all events are deleted.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
entity_key: str = Field(description="Identifier of the user.")
|
|
225
|
+
event_ids: list[str] | None = Field(
|
|
226
|
+
default=None,
|
|
227
|
+
description="Specific event IDs to delete. If omitted, all events are deleted.",
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class DeleteResponse(BaseModel):
|
|
232
|
+
"""Response model for ``upp/delete``.
|
|
233
|
+
|
|
234
|
+
Attributes:
|
|
235
|
+
deleted_count: Number of events deleted.
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
deleted_count: int = Field(description="Number of events deleted.")
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class InfoRequest(BaseModel):
|
|
242
|
+
"""Request model for ``upp/info``. No parameters required."""
|
|
243
|
+
|
|
244
|
+
pass
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class InfoResponse(BaseModel):
|
|
248
|
+
"""Response model for ``upp/info``.
|
|
249
|
+
|
|
250
|
+
Attributes:
|
|
251
|
+
protocol_version: Semantic version of the UPP protocol.
|
|
252
|
+
ontology: The ontology identifier for this server instance.
|
|
253
|
+
operations: List of supported operations.
|
|
254
|
+
conformance_level: Server conformance level (1=Minimal, 2=Full, 3=Portable).
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
protocol_version: str = Field(description="Semantic version of the UPP protocol.")
|
|
258
|
+
ontology: str = Field(description="The ontology identifier for this server instance.")
|
|
259
|
+
operations: list[str] = Field(description="Supported operations.")
|
|
260
|
+
conformance_level: int = Field(
|
|
261
|
+
ge=1,
|
|
262
|
+
le=3,
|
|
263
|
+
description=("Server conformance level. 1: Minimal (ingest, retrieve, info). 2: Full (+ events, delete, labels). 3: Portable (+ export, import)."),
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class LabelsRequest(BaseModel):
|
|
268
|
+
"""Request model for ``upp/labels``. No parameters required."""
|
|
269
|
+
|
|
270
|
+
pass
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class LabelsResponse(BaseModel):
|
|
274
|
+
"""Response model for ``upp/labels``.
|
|
275
|
+
|
|
276
|
+
Attributes:
|
|
277
|
+
labels: Label definitions from the ontology.
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
labels: list[LabelDefinition] = Field(description="Label definitions from the ontology.")
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class ExportRequest(BaseModel):
|
|
284
|
+
"""Request model for ``upp/export``.
|
|
285
|
+
|
|
286
|
+
Attributes:
|
|
287
|
+
entity_key: Identifier of the user.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
entity_key: str = Field(description="Identifier of the user.")
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class ExportResponse(BaseModel):
|
|
294
|
+
"""Response model for ``upp/export``.
|
|
295
|
+
|
|
296
|
+
Attributes:
|
|
297
|
+
file: Path to the exported JSON file.
|
|
298
|
+
event_count: Number of events exported.
|
|
299
|
+
exported_at: Timestamp of the export.
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
file: str = Field(description="Path to the exported JSON file.")
|
|
303
|
+
event_count: int = Field(description="Number of events exported.")
|
|
304
|
+
exported_at: datetime = Field(description="Timestamp of the export.")
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class ImportRequest(BaseModel):
|
|
308
|
+
"""Request model for ``upp/import``.
|
|
309
|
+
|
|
310
|
+
Attributes:
|
|
311
|
+
entity_key: Identifier of the destination user.
|
|
312
|
+
file: Path to the JSON file containing events to import.
|
|
313
|
+
"""
|
|
314
|
+
|
|
315
|
+
entity_key: str = Field(description="Identifier of the destination user.")
|
|
316
|
+
file: str = Field(description="Path to the JSON file containing events to import.")
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
class ImportResponse(BaseModel):
|
|
320
|
+
"""Response model for ``upp/import``.
|
|
321
|
+
|
|
322
|
+
Attributes:
|
|
323
|
+
imported_count: Number of events successfully imported.
|
|
324
|
+
skipped_count: Number of events skipped during import.
|
|
325
|
+
"""
|
|
326
|
+
|
|
327
|
+
imported_count: int = Field(description="Number of events successfully imported.")
|
|
328
|
+
skipped_count: int = Field(description="Number of events skipped during import.")
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
class ContextualizeRequest(BaseModel):
|
|
332
|
+
"""Request model for ``upp/contextualize``."""
|
|
333
|
+
|
|
334
|
+
entity_key: str = Field(description="Identifier of the user.")
|
|
335
|
+
text: str = Field(description="Text to retrieve context for and extract events from.")
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class ContextualizeResponse(BaseModel):
|
|
339
|
+
"""Response model for ``upp/contextualize``."""
|
|
340
|
+
|
|
341
|
+
events: list[StoredEvent] = Field(description="Relevant existing events.")
|
|
342
|
+
task_id: str = Field(description="Reference to the background ingest task.")
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class GetTasksRequest(BaseModel):
|
|
346
|
+
"""Request model for ``upp/get_tasks``."""
|
|
347
|
+
|
|
348
|
+
task_ids: list[str] = Field(description="One or more task IDs to check.")
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
class GetTasksResponse(BaseModel):
|
|
352
|
+
"""Response model for ``upp/get_tasks``."""
|
|
353
|
+
|
|
354
|
+
tasks: list[TaskResult] = Field(description="Status of each requested task.")
|
upp/rpc/methods.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""UPP JSON-RPC Method Constants.
|
|
2
|
+
|
|
3
|
+
Defines the method name constants for all ten UPP operations.
|
|
4
|
+
All method names use the ``upp/`` prefix as specified by the protocol.
|
|
5
|
+
|
|
6
|
+
Operations:
|
|
7
|
+
5 Core: ingest, retrieve, events, delete, contextualize
|
|
8
|
+
3 Discovery: info, labels, get_tasks
|
|
9
|
+
2 Portability: export, import
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"ALL_METHODS",
|
|
16
|
+
"UPP_CONTEXTUALIZE",
|
|
17
|
+
"UPP_DELETE",
|
|
18
|
+
"UPP_EVENTS",
|
|
19
|
+
"UPP_EXPORT",
|
|
20
|
+
"UPP_GET_TASKS",
|
|
21
|
+
"UPP_IMPORT",
|
|
22
|
+
"UPP_INFO",
|
|
23
|
+
"UPP_LABELS",
|
|
24
|
+
"UPP_RETRIEVE",
|
|
25
|
+
"UPP_INGEST",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
# Core operations
|
|
29
|
+
UPP_INGEST: str = "upp/ingest"
|
|
30
|
+
"""Extract and ingest events from text."""
|
|
31
|
+
|
|
32
|
+
UPP_RETRIEVE: str = "upp/retrieve"
|
|
33
|
+
"""Retrieve relevant events given a query."""
|
|
34
|
+
|
|
35
|
+
UPP_EVENTS: str = "upp/events"
|
|
36
|
+
"""List all stored events for a user."""
|
|
37
|
+
|
|
38
|
+
UPP_DELETE: str = "upp/delete"
|
|
39
|
+
"""Delete events for compliance (GDPR, CCPA)."""
|
|
40
|
+
|
|
41
|
+
# Discovery operations
|
|
42
|
+
UPP_INFO: str = "upp/info"
|
|
43
|
+
"""Return server metadata."""
|
|
44
|
+
|
|
45
|
+
UPP_LABELS: str = "upp/labels"
|
|
46
|
+
"""List label definitions from an ontology."""
|
|
47
|
+
|
|
48
|
+
# Portability operations
|
|
49
|
+
UPP_EXPORT: str = "upp/export"
|
|
50
|
+
"""Export events for migration."""
|
|
51
|
+
|
|
52
|
+
UPP_IMPORT: str = "upp/import"
|
|
53
|
+
"""Import events from another server."""
|
|
54
|
+
|
|
55
|
+
UPP_CONTEXTUALIZE: str = "upp/contextualize"
|
|
56
|
+
"""Retrieve context and ingest events in the background."""
|
|
57
|
+
|
|
58
|
+
UPP_GET_TASKS: str = "upp/get_tasks"
|
|
59
|
+
"""Check status of background tasks."""
|
|
60
|
+
|
|
61
|
+
#: All UPP method names.
|
|
62
|
+
ALL_METHODS: list[str] = [
|
|
63
|
+
UPP_INGEST,
|
|
64
|
+
UPP_RETRIEVE,
|
|
65
|
+
UPP_EVENTS,
|
|
66
|
+
UPP_DELETE,
|
|
67
|
+
UPP_INFO,
|
|
68
|
+
UPP_LABELS,
|
|
69
|
+
UPP_EXPORT,
|
|
70
|
+
UPP_IMPORT,
|
|
71
|
+
UPP_CONTEXTUALIZE,
|
|
72
|
+
UPP_GET_TASKS,
|
|
73
|
+
]
|