libentry 1.25.1__py3-none-any.whl → 1.27__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 +32 -10
- libentry/test_api.py +4 -4
- libentry/utils.py +44 -1
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/METADATA +1 -1
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/RECORD +10 -10
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/LICENSE +0 -0
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/WHEEL +0 -0
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/entry_points.txt +0 -0
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/top_level.txt +0 -0
- {libentry-1.25.1.dist-info → libentry-1.27.dist-info}/zip-safe +0 -0
libentry/mcp/service.py
CHANGED
@@ -10,7 +10,7 @@ from dataclasses import dataclass
|
|
10
10
|
from queue import Empty, Queue
|
11
11
|
from threading import Lock
|
12
12
|
from types import GeneratorType
|
13
|
-
from typing import Any, Callable, Dict, Generator, Iterable, List, Literal, Optional, Tuple,
|
13
|
+
from typing import Any, Callable, Dict, Generator, Iterable, List, Literal, Optional, Tuple, Union
|
14
14
|
|
15
15
|
from flask import Flask, request as flask_request
|
16
16
|
from pydantic import BaseModel, Field, TypeAdapter
|
@@ -891,19 +891,41 @@ class GunicornApplication(BaseApplication):
|
|
891
891
|
|
892
892
|
def load(self):
|
893
893
|
logger.info("Initializing the service.")
|
894
|
-
if isinstance(self.service_type,
|
895
|
-
|
896
|
-
|
894
|
+
if isinstance(self.service_type, (List, Tuple)):
|
895
|
+
if isinstance(self.service_config, (List, Tuple)) and len(self.service_config) == len(self.service_type):
|
896
|
+
service = [
|
897
|
+
self._create_service(t, c)
|
898
|
+
for t, c in zip(self.service_type, self.service_config)
|
899
|
+
]
|
900
|
+
elif self.service_config is None:
|
901
|
+
service = [
|
902
|
+
self._create_service(t, self.service_config)
|
903
|
+
for t in self.service_type
|
904
|
+
]
|
905
|
+
else:
|
906
|
+
raise RuntimeError(
|
907
|
+
f"You are going to run {len(self.service_type)} services. "
|
908
|
+
"In the multiple service mode, every `service_type` requires a `service_config` object."
|
909
|
+
)
|
910
|
+
else:
|
911
|
+
service = self._create_service(self.service_type, self.service_config)
|
912
|
+
logger.info("Service initialized.")
|
913
|
+
|
914
|
+
return FlaskServer(service)
|
915
|
+
|
916
|
+
@staticmethod
|
917
|
+
def _create_service(service_type, service_config):
|
918
|
+
if isinstance(service_type, type) or callable(service_type):
|
919
|
+
service = service_type(service_config) if service_config else service_type()
|
920
|
+
elif service_config is None:
|
897
921
|
logger.warning(
|
898
922
|
"Be careful! It is not recommended to start the server from a service instance. "
|
899
923
|
"Use service_type and service_config instead."
|
900
924
|
)
|
901
|
-
service =
|
925
|
+
service = service_type
|
902
926
|
else:
|
903
|
-
raise TypeError(f"Invalid service type \"{type(
|
904
|
-
|
905
|
-
|
906
|
-
return FlaskServer(service)
|
927
|
+
raise TypeError(f"Invalid service type \"{type(service_type)}\".")
|
928
|
+
return service
|
907
929
|
|
908
930
|
|
909
931
|
class RunServiceConfig(BaseModel):
|
@@ -969,7 +991,7 @@ class RunServiceConfig(BaseModel):
|
|
969
991
|
|
970
992
|
|
971
993
|
def run_service(
|
972
|
-
service_type: Union[
|
994
|
+
service_type: Union[Union[type, Callable], List, Tuple],
|
973
995
|
service_config=None,
|
974
996
|
run_config: Optional[RunServiceConfig] = None,
|
975
997
|
*,
|
libentry/test_api.py
CHANGED
@@ -11,7 +11,8 @@ from typing import Literal, Optional
|
|
11
11
|
|
12
12
|
from pydantic import BaseModel
|
13
13
|
|
14
|
-
from libentry.
|
14
|
+
from libentry.mcp.client import APIClient
|
15
|
+
from libentry.mcp.types import HTTPOptions
|
15
16
|
|
16
17
|
|
17
18
|
class TestRequest(BaseModel):
|
@@ -49,14 +50,13 @@ def test(request: TestRequest):
|
|
49
50
|
if request.method == "GET":
|
50
51
|
response = APIClient().get(
|
51
52
|
request.url,
|
52
|
-
**kwargs
|
53
|
+
HTTPOptions(**kwargs)
|
53
54
|
)
|
54
55
|
else:
|
55
56
|
response = APIClient().post(
|
56
57
|
request.url,
|
57
58
|
request.data,
|
58
|
-
stream=request.stream,
|
59
|
-
**kwargs
|
59
|
+
HTTPOptions(stream=request.stream, **kwargs)
|
60
60
|
)
|
61
61
|
if not request.stream:
|
62
62
|
t = time() - t
|
libentry/utils.py
CHANGED
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
__author__ = "xi"
|
4
4
|
__all__ = [
|
5
|
-
"Timer"
|
5
|
+
"Timer",
|
6
|
+
"TimedLRUCache",
|
6
7
|
]
|
7
8
|
|
9
|
+
import threading
|
8
10
|
import time
|
11
|
+
from collections import OrderedDict
|
12
|
+
from functools import wraps
|
9
13
|
|
10
14
|
|
11
15
|
class Timer:
|
@@ -32,3 +36,42 @@ class Timer:
|
|
32
36
|
raise RuntimeError("The timer has not started yet.")
|
33
37
|
self.end_time = time.perf_counter()
|
34
38
|
self.cost = self.end_time - self.start_time
|
39
|
+
|
40
|
+
|
41
|
+
class TimedLRUCache:
|
42
|
+
|
43
|
+
def __init__(self, max_size: int = 256, timeout: float = 12):
|
44
|
+
self.maxsize = max_size
|
45
|
+
self.timeout = timeout # seconds
|
46
|
+
|
47
|
+
self.lock = threading.Lock()
|
48
|
+
self.cache = OrderedDict()
|
49
|
+
|
50
|
+
def __call__(self, func):
|
51
|
+
@wraps(func)
|
52
|
+
def wrapped(*args, **kwargs):
|
53
|
+
key = (args, frozenset(kwargs.items()))
|
54
|
+
now = time.time()
|
55
|
+
|
56
|
+
with self.lock:
|
57
|
+
# clean expired items
|
58
|
+
if key in self.cache:
|
59
|
+
result, timestamp = self.cache[key]
|
60
|
+
if now - timestamp < self.timeout:
|
61
|
+
self.cache.move_to_end(key)
|
62
|
+
return result
|
63
|
+
else:
|
64
|
+
del self.cache[key] # expired
|
65
|
+
|
66
|
+
# compute new result
|
67
|
+
result = func(*args, **kwargs)
|
68
|
+
self.cache[key] = (result, now)
|
69
|
+
self.cache.move_to_end(key)
|
70
|
+
|
71
|
+
# exceed the max size
|
72
|
+
if len(self.cache) > self.maxsize:
|
73
|
+
self.cache.popitem(last=False) # remove the oldest item
|
74
|
+
|
75
|
+
return result
|
76
|
+
|
77
|
+
return wrapped
|
@@ -8,12 +8,12 @@ libentry/json.py,sha256=gTjogVG6eGUMkVrjilKkpFC8ZkElGAyZIutO7mbmSzg,1956
|
|
8
8
|
libentry/logging.py,sha256=IiYoCUzm8XTK1fduA-NA0FI2Qz_m81NEPV3d3tEfgdI,1349
|
9
9
|
libentry/resource.py,sha256=qAPXF7RzRYeCM4xWft6XR3SYk7lEiQ6ymOHbpNoi0mQ,1821
|
10
10
|
libentry/schema.py,sha256=40SOhCF_eytWOF47MWKCRHKHl_lCaQVetx1Af62PkiI,10439
|
11
|
-
libentry/test_api.py,sha256=
|
12
|
-
libentry/utils.py,sha256=
|
11
|
+
libentry/test_api.py,sha256=bs7P8gveLtuUvHxrpujSrfuYqLVJ3fOXVg_MZnZxoJ4,4504
|
12
|
+
libentry/utils.py,sha256=vCm6UyAlibnPOlPJHZO57u3TXhw5PZmGM5_vBAPUnB4,1981
|
13
13
|
libentry/mcp/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
|
14
14
|
libentry/mcp/api.py,sha256=GDErVCz_hh_ZeMxLS8bTPyBUhCTHw3Mm-nGFMV2W2yo,3669
|
15
15
|
libentry/mcp/client.py,sha256=qFbigNIOJvEf8ZICN2K8nnmVcITIzDhJgaw3c0P-WXM,23078
|
16
|
-
libentry/mcp/service.py,sha256=
|
16
|
+
libentry/mcp/service.py,sha256=YMzP9sTR6RaeguwbwapFZFcc7MjKuDDfpeXSCD09Xzg,39081
|
17
17
|
libentry/mcp/types.py,sha256=aAoVO4jjqEvDzNneuZapmRYonLLnGsbcLoypVyRNNYg,12389
|
18
18
|
libentry/service/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
|
19
19
|
libentry/service/common.py,sha256=OVaW2afgKA6YqstJmtnprBCqQEUZEWotZ6tHavmJJeU,42
|
@@ -22,10 +22,10 @@ libentry/service/list.py,sha256=ElHWhTgShGOhaxMUEwVbMXos0NQKjHsODboiQ-3AMwE,1397
|
|
22
22
|
libentry/service/running.py,sha256=FrPJoJX6wYxcHIysoatAxhW3LajCCm0Gx6l7__6sULQ,5105
|
23
23
|
libentry/service/start.py,sha256=mZT7b9rVULvzy9GTZwxWnciCHgv9dbGN2JbxM60OMn4,1270
|
24
24
|
libentry/service/stop.py,sha256=wOpwZgrEJ7QirntfvibGq-XsTC6b3ELhzRW2zezh-0s,1187
|
25
|
-
libentry-1.
|
26
|
-
libentry-1.
|
27
|
-
libentry-1.
|
28
|
-
libentry-1.
|
29
|
-
libentry-1.
|
30
|
-
libentry-1.
|
31
|
-
libentry-1.
|
25
|
+
libentry-1.27.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
26
|
+
libentry-1.27.dist-info/METADATA,sha256=4Kmb2RNxxAYb26wbovxkx8haDAaW7tBg_JEuxPwkwuI,1133
|
27
|
+
libentry-1.27.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
28
|
+
libentry-1.27.dist-info/entry_points.txt,sha256=1v_nLVDsjvVJp9SWhl4ef2zZrsLTBtFWgrYFgqvQBgc,61
|
29
|
+
libentry-1.27.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
|
30
|
+
libentry-1.27.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
31
|
+
libentry-1.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|