libentry 1.23.4__py3-none-any.whl → 1.24__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.
libentry/mcp/service.py CHANGED
@@ -57,11 +57,24 @@ class SubroutineAdapter:
57
57
 
58
58
  def __call__(
59
59
  self,
60
- request: Dict[str, Any]
60
+ request: Any,
61
+ args: Optional[Dict[str, str]] = None
61
62
  ) -> Union[SubroutineResponse, Iterable[SubroutineResponse]]:
62
63
  if isinstance(request, BaseModel):
63
64
  request = request.model_dump()
64
65
 
66
+ if not isinstance(request, Dict):
67
+ raise ValueError(
68
+ f"Subroutine only accepts JSON object as input. "
69
+ f"Expect \"dict\", got \"{type(request)}\"."
70
+ )
71
+
72
+ if args is not None:
73
+ conflicts = args.keys() & request.keys()
74
+ if len(conflicts) > 0:
75
+ raise ValueError(f"Duplicated fields: \"{conflicts}\".")
76
+ request = {**args, **request}
77
+
65
78
  try:
66
79
  input_model = self.api_signature.input_model
67
80
  if input_model is not None:
@@ -117,16 +130,29 @@ class JSONRPCAdapter:
117
130
 
118
131
  def __call__(
119
132
  self,
120
- request: Union[JSONRPCRequest, JSONRPCNotification, Dict[str, Any]]
133
+ request: Union[JSONRPCRequest, JSONRPCNotification, Dict[str, Any]],
134
+ args: Optional[Dict[str, str]] = None
121
135
  ) -> Union[JSONRPCResponse, Iterable[JSONRPCResponse], None]:
122
136
  if isinstance(request, Dict):
137
+ if args is not None:
138
+ conflicts = args.keys() & request.keys()
139
+ if len(conflicts) > 0:
140
+ raise ValueError(f"Duplicated fields: \"{conflicts}\".")
141
+ request = {**args, **request}
123
142
  request = self.type_adapter.validate_python(request)
124
143
 
144
+ if isinstance(request, JSONRPCRequest):
145
+ fn = self._apply_request
146
+ elif isinstance(request, JSONRPCNotification):
147
+ fn = self._apply_notification
148
+ else:
149
+ raise ValueError(
150
+ f"JSONRPC only accepts JSONRPCRequest, JSONRPCNotification as input. "
151
+ f"Expect \"JSONRPCRequest\", \"JSONRPCNotification\" or \"dict\", got \"{type(request)}\"."
152
+ )
153
+
125
154
  try:
126
- if isinstance(request, JSONRPCRequest):
127
- return self._apply_request(request)
128
- else:
129
- return self._apply_notification(request)
155
+ return fn(request)
130
156
  except SystemExit as e:
131
157
  raise e
132
158
  except KeyboardInterrupt as e:
@@ -251,26 +277,20 @@ class FlaskHandler:
251
277
  data = flask_request.data
252
278
  content_type = flask_request.content_type
253
279
 
254
- json_from_url = {**args}
280
+ args = {**args}
255
281
  if data:
256
282
  if (not content_type) or content_type == MIME.json.value:
257
- json_from_data = json.loads(data)
283
+ raw_request = json.loads(data)
258
284
  else:
259
285
  return self.app.error(f"Unsupported Content-Type: \"{content_type}\".")
260
286
  else:
261
- json_from_data = {}
262
-
263
- conflicts = json_from_url.keys() & json_from_data.keys()
264
- if len(conflicts) > 0:
265
- return self.app.error(f"Duplicated fields: \"{conflicts}\".")
266
-
267
- input_json = {**json_from_url, **json_from_data}
287
+ raw_request = {}
268
288
 
269
289
  ################################################################################
270
290
  # Call method as MCP
271
291
  ################################################################################
272
292
  try:
273
- mcp_response = self.default_adapter(input_json)
293
+ mcp_response = self.default_adapter(raw_request, args)
274
294
  except Exception as e:
275
295
  error = json.dumps(SubroutineError.from_exception(e))
276
296
  return self.app.error(error, mimetype=MIME.json.value)
@@ -370,7 +390,11 @@ class SSEService:
370
390
 
371
391
  # noinspection PyUnusedLocal
372
392
  @api.get("/sse", tag=api.TAG_ENDPOINT)
373
- def sse(self, raw_request: Dict[str, Any]) -> Iterable[SSE]:
393
+ def sse(
394
+ self,
395
+ raw_request: Any,
396
+ args: Optional[Dict[str, str]] = None
397
+ ) -> Iterable[SSE]:
374
398
  session_id = str(uuid.uuid4())
375
399
  queue = Queue(8)
376
400
  with self.lock:
@@ -396,7 +420,23 @@ class SSEService:
396
420
  return _stream()
397
421
 
398
422
  @api.route("/sse/message", tag=api.TAG_ENDPOINT)
399
- def sse_message(self, raw_request: Dict[str, Any]) -> None:
423
+ def sse_message(
424
+ self,
425
+ raw_request: Any,
426
+ args: Optional[Dict[str, str]] = None
427
+ ) -> None:
428
+ if not isinstance(raw_request, Dict):
429
+ raise ValueError(
430
+ f"/message only accepts JSON object as input. "
431
+ f"Expect \"dict\", got \"{type(raw_request)}\"."
432
+ )
433
+
434
+ if args is not None:
435
+ conflicts = args.keys() & raw_request.keys()
436
+ if len(conflicts) > 0:
437
+ raise ValueError(f"Duplicated fields: \"{conflicts}\".")
438
+ raw_request = {**args, **raw_request}
439
+
400
440
  ################################################################################
401
441
  # session validation
402
442
  ################################################################################
@@ -472,7 +512,26 @@ class JSONRPCService:
472
512
  self.type_adapter = TypeAdapter(Union[JSONRPCRequest, JSONRPCNotification])
473
513
 
474
514
  @api.route(tag=api.TAG_ENDPOINT)
475
- def message(self, raw_request: Dict[str, Any]) -> Union[JSONRPCResponse, Iterable[JSONRPCResponse], None]:
515
+ def message(
516
+ self,
517
+ raw_request: Any,
518
+ args: Optional[Dict[str, str]] = None
519
+ ) -> Union[JSONRPCResponse, Iterable[JSONRPCResponse], None]:
520
+ if isinstance(raw_request, List):
521
+ raise ValueError("Batching RCP requests is not supported yet.")
522
+
523
+ if not isinstance(raw_request, Dict):
524
+ raise ValueError(
525
+ f"/message only accepts JSON object as input. "
526
+ f"Expect \"dict\", got \"{type(raw_request)}\"."
527
+ )
528
+
529
+ if args is not None:
530
+ conflicts = args.keys() & raw_request.keys()
531
+ if len(conflicts) > 0:
532
+ raise ValueError(f"Duplicated fields: \"{conflicts}\".")
533
+ raw_request = {**args, **raw_request}
534
+
476
535
  request = self.type_adapter.validate_python(raw_request)
477
536
  path = f"/{request.method}"
478
537
  route = self.service_routes.get(path, self.builtin_routes.get(path))
@@ -502,6 +561,10 @@ class LifeCycleService:
502
561
  serverInfo=Implementation(name="python-libentry", version="1.0.0")
503
562
  )
504
563
 
564
+ @api.route()
565
+ def ping(self):
566
+ return None
567
+
505
568
 
506
569
  class NotificationsService:
507
570
 
libentry/resource.py ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env python3
2
+
3
+ __author__ = "xi"
4
+ __all__ = [
5
+ "AbstractResourceManager",
6
+ "JSONResourceManager",
7
+ "RemoteResourceManager",
8
+ "ResourceManager",
9
+ ]
10
+
11
+ import abc
12
+ from typing import Any, Dict, List
13
+ from urllib.parse import urlparse
14
+
15
+ import yaml
16
+
17
+
18
+ class AbstractResourceManager(abc.ABC):
19
+
20
+ @abc.abstractmethod
21
+ def list(self) -> List[str]:
22
+ pass
23
+
24
+ @abc.abstractmethod
25
+ def get(self, name: str) -> Any:
26
+ pass
27
+
28
+ @abc.abstractmethod
29
+ def set(self, name: str, value: Any) -> Any:
30
+ pass
31
+
32
+
33
+ class JSONResourceManager(AbstractResourceManager):
34
+
35
+ def __init__(self, path: str):
36
+ with open(path, "r") as f:
37
+ self.resource_obj = yaml.load(f, yaml.SafeLoader)
38
+
39
+ if not isinstance(self.resource_obj, Dict):
40
+ raise RuntimeError(
41
+ f"Expect a JSON object, "
42
+ f"got {type(self.resource_obj)}."
43
+ )
44
+
45
+ def list(self) -> List[str]:
46
+ return [*self.resource_obj.keys()]
47
+
48
+ def get(self, name: str) -> Any:
49
+ return self.resource_obj.get(name)
50
+
51
+ def set(self, name: str, value: Any) -> Any:
52
+ raise NotImplementedError("\"set\" is not supported by JSONResourceClient.")
53
+
54
+
55
+ class RemoteResourceManager(AbstractResourceManager):
56
+
57
+ def __init__(self, url: str):
58
+ pass
59
+
60
+
61
+ class ResourceManager:
62
+
63
+ def __new__(cls, uri: str) -> AbstractResourceManager:
64
+ parsed_uri = urlparse(uri)
65
+ if parsed_uri.scheme in {"", "json", "yaml", "yml"}:
66
+ return JSONResourceManager(parsed_uri.path)
67
+ else:
68
+ raise NotImplementedError(f"Scheme \"{parsed_uri.scheme}\" is not supported.")
69
+
70
+
71
+ def _test():
72
+ client = ResourceManager("config_test.yml")
73
+ print(client.get("qwen_2.5"))
74
+ return 0
75
+
76
+
77
+ if __name__ == "__main__":
78
+ raise SystemExit(_test())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: libentry
3
- Version: 1.23.4
3
+ Version: 1.24
4
4
  Summary: Entries for experimental utilities.
5
5
  Home-page: https://github.com/XoriieInpottn/libentry
6
6
  Author: xi
@@ -6,13 +6,14 @@ libentry/executor.py,sha256=cTV0WxJi0nU1TP-cOwmeodN8DD6L1691M2HIQsJtGrU,6582
6
6
  libentry/experiment.py,sha256=ejgAHDXWIe9x4haUzIFuz1WasLY0_aD1z_vyEVGjTu8,4922
7
7
  libentry/json.py,sha256=CubUUu29h7idLaC4d66vKhjBgVHKN1rZOv-Tw2qM17k,1916
8
8
  libentry/logging.py,sha256=IiYoCUzm8XTK1fduA-NA0FI2Qz_m81NEPV3d3tEfgdI,1349
9
+ libentry/resource.py,sha256=qAPXF7RzRYeCM4xWft6XR3SYk7lEiQ6ymOHbpNoi0mQ,1821
9
10
  libentry/schema.py,sha256=40SOhCF_eytWOF47MWKCRHKHl_lCaQVetx1Af62PkiI,10439
10
11
  libentry/test_api.py,sha256=Xw7B7sH6g1iCTV5sFzyBF3JAJzeOr9xg0AyezTNsnIk,4452
11
12
  libentry/utils.py,sha256=O7P6GadtUIjq0N2IZH7PhHZDUM3NebzcqyDqytet7CM,683
12
13
  libentry/mcp/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
13
14
  libentry/mcp/api.py,sha256=KSvz6_TNGKQQoFJPNH1XIc8CMji0I2_CqC9VCSOPRfc,2491
14
15
  libentry/mcp/client.py,sha256=tEJbMpXiMKQ0qDgLGyavE2A4jpoXliqbrVj_TMfOGXI,22488
15
- libentry/mcp/service.py,sha256=xInlf_u8AVlGtnWH6gky_l3IolmYahm-FYMqsbm6t3w,32563
16
+ libentry/mcp/service.py,sha256=VBacwSN9xiV3wk5Ta0LHxRAor1cwR04ZavlKLTdTuWw,34721
16
17
  libentry/mcp/types.py,sha256=xTQCnKAgeJNss4klJ33MrWHGCzG_LeR3urizO_Z9q9U,12239
17
18
  libentry/service/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
18
19
  libentry/service/common.py,sha256=OVaW2afgKA6YqstJmtnprBCqQEUZEWotZ6tHavmJJeU,42
@@ -21,10 +22,10 @@ libentry/service/list.py,sha256=ElHWhTgShGOhaxMUEwVbMXos0NQKjHsODboiQ-3AMwE,1397
21
22
  libentry/service/running.py,sha256=FrPJoJX6wYxcHIysoatAxhW3LajCCm0Gx6l7__6sULQ,5105
22
23
  libentry/service/start.py,sha256=mZT7b9rVULvzy9GTZwxWnciCHgv9dbGN2JbxM60OMn4,1270
23
24
  libentry/service/stop.py,sha256=wOpwZgrEJ7QirntfvibGq-XsTC6b3ELhzRW2zezh-0s,1187
24
- libentry-1.23.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
- libentry-1.23.4.dist-info/METADATA,sha256=-gzj-ialfjOVVPyc_tv-Jj1qH7LlrauZnossj2nOFX4,1135
26
- libentry-1.23.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
27
- libentry-1.23.4.dist-info/entry_points.txt,sha256=1v_nLVDsjvVJp9SWhl4ef2zZrsLTBtFWgrYFgqvQBgc,61
28
- libentry-1.23.4.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
29
- libentry-1.23.4.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
30
- libentry-1.23.4.dist-info/RECORD,,
25
+ libentry-1.24.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
26
+ libentry-1.24.dist-info/METADATA,sha256=zvGz_iBvBEMl_1HH4odL37ySnpBaLTTo7dAsxdwNrB4,1133
27
+ libentry-1.24.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
28
+ libentry-1.24.dist-info/entry_points.txt,sha256=1v_nLVDsjvVJp9SWhl4ef2zZrsLTBtFWgrYFgqvQBgc,61
29
+ libentry-1.24.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
30
+ libentry-1.24.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
31
+ libentry-1.24.dist-info/RECORD,,