libentry 1.24.9__py3-none-any.whl → 1.25.1__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/client.py +2 -2
- libentry/mcp/service.py +122 -30
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/METADATA +1 -1
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/RECORD +9 -9
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/LICENSE +0 -0
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/WHEEL +0 -0
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/entry_points.txt +0 -0
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/top_level.txt +0 -0
- {libentry-1.24.9.dist-info → libentry-1.25.1.dist-info}/zip-safe +0 -0
libentry/mcp/client.py
CHANGED
@@ -9,7 +9,7 @@ from threading import Semaphore, Thread
|
|
9
9
|
from time import sleep
|
10
10
|
from types import GeneratorType
|
11
11
|
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type, Union
|
12
|
-
from urllib.parse import urlencode
|
12
|
+
from urllib.parse import urlencode
|
13
13
|
|
14
14
|
import httpx
|
15
15
|
from pydantic import BaseModel, TypeAdapter
|
@@ -371,7 +371,7 @@ class APIClient(SubroutineMixIn, MCPMixIn):
|
|
371
371
|
raise err
|
372
372
|
|
373
373
|
def _http_request(self, request: HTTPRequest, timeout: float) -> HTTPResponse:
|
374
|
-
full_url =
|
374
|
+
full_url = self.base_url.rstrip("/") + "/" + request.path.lstrip("/")
|
375
375
|
headers = (
|
376
376
|
{**self.headers}
|
377
377
|
if request.options.headers is None else
|
libentry/mcp/service.py
CHANGED
@@ -10,10 +10,10 @@ 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, Optional, Type, Union
|
13
|
+
from typing import Any, Callable, Dict, Generator, Iterable, List, Literal, Optional, Tuple, Type, Union
|
14
14
|
|
15
15
|
from flask import Flask, request as flask_request
|
16
|
-
from pydantic import BaseModel, TypeAdapter
|
16
|
+
from pydantic import BaseModel, Field, TypeAdapter
|
17
17
|
|
18
18
|
from libentry import json, logger
|
19
19
|
from libentry.mcp import api
|
@@ -21,8 +21,8 @@ from libentry.mcp.api import APIInfo, list_api_info
|
|
21
21
|
from libentry.mcp.types import BlobResourceContents, CallToolRequestParams, CallToolResult, Implementation, \
|
22
22
|
InitializeRequestParams, InitializeResult, JSONRPCError, JSONRPCNotification, JSONRPCRequest, JSONRPCResponse, \
|
23
23
|
ListResourcesResult, ListToolsResult, MIME, ReadResourceRequestParams, ReadResourceResult, Resource, SSE, \
|
24
|
-
ServerCapabilities, SubroutineError, SubroutineResponse, TextContent, TextResourceContents, Tool,
|
25
|
-
|
24
|
+
ServerCapabilities, SubroutineError, SubroutineResponse, TextContent, TextResourceContents, Tool, ToolSchema, \
|
25
|
+
ToolsCapability
|
26
26
|
from libentry.schema import APISignature, get_api_signature, query_api
|
27
27
|
|
28
28
|
try:
|
@@ -805,9 +805,11 @@ class FlaskServer(Flask):
|
|
805
805
|
logger.info("Initializing Flask application.")
|
806
806
|
existing_routes = {}
|
807
807
|
|
808
|
-
|
809
|
-
|
810
|
-
|
808
|
+
input_services = self.service if isinstance(self.service, (List, Tuple)) else [self.service]
|
809
|
+
for input_service in input_services:
|
810
|
+
routes = self._create_routes(input_service)
|
811
|
+
self.service_routes.update(routes)
|
812
|
+
existing_routes.update(self.service_routes)
|
811
813
|
|
812
814
|
for builtin_service in self.builtin_services:
|
813
815
|
routes = self._create_routes(builtin_service, existing_routes)
|
@@ -904,26 +906,116 @@ class GunicornApplication(BaseApplication):
|
|
904
906
|
return FlaskServer(service)
|
905
907
|
|
906
908
|
|
909
|
+
class RunServiceConfig(BaseModel):
|
910
|
+
"""Run service config."""
|
911
|
+
|
912
|
+
host: str = Field(
|
913
|
+
title="Hostname",
|
914
|
+
description=(
|
915
|
+
"The hostname of the server that runs the service. "
|
916
|
+
"IP address or domain name."
|
917
|
+
),
|
918
|
+
default="0.0.0.0"
|
919
|
+
)
|
920
|
+
port: int = Field(
|
921
|
+
title="Port number",
|
922
|
+
description="The port that the service listened to.",
|
923
|
+
)
|
924
|
+
num_workers: int = Field(
|
925
|
+
title="Number of workers",
|
926
|
+
description="The number of workers (processes) to run the service.",
|
927
|
+
default=1
|
928
|
+
)
|
929
|
+
num_threads: int = Field(
|
930
|
+
title="Number of threads",
|
931
|
+
description="The number of threads for each worker.",
|
932
|
+
default=20
|
933
|
+
)
|
934
|
+
num_connections: Optional[int] = Field(
|
935
|
+
title="Max number of connections",
|
936
|
+
description="The maximum number of simultaneous clients (or socket connections).",
|
937
|
+
default=1024
|
938
|
+
)
|
939
|
+
backlog: Optional[int] = Field(
|
940
|
+
title="The maximum number of pending connections",
|
941
|
+
description="The maximum number of pending connections.",
|
942
|
+
default=2048
|
943
|
+
)
|
944
|
+
worker_class: Literal["sync", "gthread", "eventlet", "gevent", "tornado"] = Field(
|
945
|
+
title="The type of workers to use",
|
946
|
+
description="The type of workers to use.",
|
947
|
+
default="gthread"
|
948
|
+
)
|
949
|
+
timeout: int = Field(
|
950
|
+
title="Worker timeout",
|
951
|
+
description="Workers silent for more than this many seconds are killed and restarted.",
|
952
|
+
default=60
|
953
|
+
)
|
954
|
+
keyfile: Optional[str] = Field(
|
955
|
+
title="SSL key file",
|
956
|
+
description="SSL key file.",
|
957
|
+
default=None
|
958
|
+
)
|
959
|
+
keyfile_password: Optional[str] = Field(
|
960
|
+
title="SSL key file password",
|
961
|
+
description="SSL key file password.",
|
962
|
+
default=None
|
963
|
+
)
|
964
|
+
certfile: Optional[str] = Field(
|
965
|
+
title="SSL certificate file",
|
966
|
+
description="SSL certificate file.",
|
967
|
+
default=None
|
968
|
+
)
|
969
|
+
|
970
|
+
|
907
971
|
def run_service(
|
908
972
|
service_type: Union[Type, Callable],
|
909
973
|
service_config=None,
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
974
|
+
run_config: Optional[RunServiceConfig] = None,
|
975
|
+
*,
|
976
|
+
host: Optional[str] = None,
|
977
|
+
port: Optional[int] = None,
|
978
|
+
num_workers: Optional[int] = None,
|
979
|
+
num_threads: Optional[int] = None,
|
980
|
+
num_connections: Optional[int] = None,
|
981
|
+
backlog: Optional[int] = None,
|
982
|
+
worker_class: Optional[str] = None,
|
983
|
+
timeout: Optional[int] = None,
|
918
984
|
keyfile: Optional[str] = None,
|
919
985
|
keyfile_password: Optional[str] = None,
|
920
986
|
certfile: Optional[str] = None
|
921
|
-
):
|
987
|
+
) -> None:
|
988
|
+
kwargs = {}
|
989
|
+
if host is not None:
|
990
|
+
kwargs["host"] = host
|
991
|
+
if port is not None:
|
992
|
+
kwargs["port"] = port
|
993
|
+
if num_workers is not None:
|
994
|
+
kwargs["num_workers"] = num_workers
|
995
|
+
if num_threads is not None:
|
996
|
+
kwargs["num_threads"] = num_threads
|
997
|
+
if num_connections is not None:
|
998
|
+
kwargs["num_connections"] = num_connections
|
999
|
+
if backlog is not None:
|
1000
|
+
kwargs["backlog"] = backlog
|
1001
|
+
if worker_class is not None:
|
1002
|
+
kwargs["worker_class"] = worker_class
|
1003
|
+
if timeout is not None:
|
1004
|
+
kwargs["timeout"] = timeout
|
1005
|
+
if keyfile is not None:
|
1006
|
+
kwargs["keyfile"] = keyfile
|
1007
|
+
if keyfile_password is not None:
|
1008
|
+
kwargs["keyfile_password"] = keyfile_password
|
1009
|
+
if certfile is not None:
|
1010
|
+
kwargs["certfile"] = certfile
|
1011
|
+
|
1012
|
+
if run_config is None:
|
1013
|
+
run_config = RunServiceConfig(**kwargs)
|
1014
|
+
else:
|
1015
|
+
for name, value in kwargs.items():
|
1016
|
+
setattr(run_config, name, value)
|
1017
|
+
|
922
1018
|
logger.info("Starting gunicorn server.")
|
923
|
-
if num_connections is None or num_connections < num_threads * 2:
|
924
|
-
num_connections = num_threads * 2
|
925
|
-
if backlog is None or backlog < num_threads * 2:
|
926
|
-
backlog = num_threads * 2
|
927
1019
|
|
928
1020
|
def ssl_context(config, _default_ssl_context_factory):
|
929
1021
|
import ssl
|
@@ -931,21 +1023,21 @@ def run_service(
|
|
931
1023
|
context.load_cert_chain(
|
932
1024
|
certfile=config.certfile,
|
933
1025
|
keyfile=config.keyfile,
|
934
|
-
password=keyfile_password
|
1026
|
+
password=run_config.keyfile_password
|
935
1027
|
)
|
936
1028
|
context.minimum_version = ssl.TLSVersion.TLSv1_3
|
937
1029
|
return context
|
938
1030
|
|
939
1031
|
options = {
|
940
|
-
"bind": f"{host}:{port}",
|
941
|
-
"workers": num_workers,
|
942
|
-
"threads": num_threads,
|
943
|
-
"timeout": timeout,
|
944
|
-
"worker_connections": num_connections,
|
945
|
-
"backlog": backlog,
|
946
|
-
"keyfile": keyfile,
|
947
|
-
"certfile": certfile,
|
948
|
-
"worker_class": worker_class,
|
1032
|
+
"bind": f"{run_config.host}:{run_config.port}",
|
1033
|
+
"workers": run_config.num_workers,
|
1034
|
+
"threads": run_config.num_threads,
|
1035
|
+
"timeout": run_config.timeout,
|
1036
|
+
"worker_connections": run_config.num_connections,
|
1037
|
+
"backlog": run_config.backlog,
|
1038
|
+
"keyfile": run_config.keyfile,
|
1039
|
+
"certfile": run_config.certfile,
|
1040
|
+
"worker_class": run_config.worker_class,
|
949
1041
|
"ssl_context": ssl_context
|
950
1042
|
}
|
951
1043
|
for name, value in options.items():
|
@@ -12,8 +12,8 @@ libentry/test_api.py,sha256=Xw7B7sH6g1iCTV5sFzyBF3JAJzeOr9xg0AyezTNsnIk,4452
|
|
12
12
|
libentry/utils.py,sha256=O7P6GadtUIjq0N2IZH7PhHZDUM3NebzcqyDqytet7CM,683
|
13
13
|
libentry/mcp/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
|
14
14
|
libentry/mcp/api.py,sha256=GDErVCz_hh_ZeMxLS8bTPyBUhCTHw3Mm-nGFMV2W2yo,3669
|
15
|
-
libentry/mcp/client.py,sha256=
|
16
|
-
libentry/mcp/service.py,sha256=
|
15
|
+
libentry/mcp/client.py,sha256=qFbigNIOJvEf8ZICN2K8nnmVcITIzDhJgaw3c0P-WXM,23078
|
16
|
+
libentry/mcp/service.py,sha256=PpdQBxqKPiZ2tpnsqDYiC29_yjMjK9J3VWynn4uvpVg,38109
|
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.25.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
26
|
+
libentry-1.25.1.dist-info/METADATA,sha256=7HVCqasAkkqvvXhodRtTmaoZTG4FC70Q6CxsgZWnC8U,1135
|
27
|
+
libentry-1.25.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
28
|
+
libentry-1.25.1.dist-info/entry_points.txt,sha256=1v_nLVDsjvVJp9SWhl4ef2zZrsLTBtFWgrYFgqvQBgc,61
|
29
|
+
libentry-1.25.1.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
|
30
|
+
libentry-1.25.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
31
|
+
libentry-1.25.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|