scmcp-shared 0.4.0__py3-none-any.whl → 0.5.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.
- scmcp_shared/__init__.py +1 -3
- scmcp_shared/agent.py +58 -8
- scmcp_shared/backend.py +44 -0
- scmcp_shared/cli.py +75 -46
- scmcp_shared/kb.py +38 -0
- scmcp_shared/logging_config.py +6 -8
- scmcp_shared/mcp_base.py +184 -0
- scmcp_shared/schema/io.py +101 -59
- scmcp_shared/schema/pl.py +386 -490
- scmcp_shared/schema/pp.py +514 -265
- scmcp_shared/schema/preset/__init__.py +15 -0
- scmcp_shared/schema/preset/io.py +103 -0
- scmcp_shared/schema/preset/pl.py +843 -0
- scmcp_shared/schema/preset/pp.py +616 -0
- scmcp_shared/schema/preset/tl.py +917 -0
- scmcp_shared/schema/preset/util.py +123 -0
- scmcp_shared/schema/tl.py +355 -407
- scmcp_shared/schema/util.py +57 -72
- scmcp_shared/server/__init__.py +0 -12
- scmcp_shared/server/auto.py +10 -8
- scmcp_shared/server/code.py +3 -0
- scmcp_shared/server/preset/__init__.py +14 -0
- scmcp_shared/server/{io.py → preset/io.py} +26 -22
- scmcp_shared/server/{pl.py → preset/pl.py} +162 -78
- scmcp_shared/server/{pp.py → preset/pp.py} +123 -65
- scmcp_shared/server/{tl.py → preset/tl.py} +142 -79
- scmcp_shared/server/{util.py → preset/util.py} +123 -66
- scmcp_shared/util.py +109 -38
- scmcp_shared/vector_db/decoupler.lance/_transactions/0-9499b1b5-85d4-44c2-8f05-1bcce87fe4ef.txn +3 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/1-1632e7a3-4427-4077-8d03-57437144443d.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/10-dcf66479-eafb-4193-9358-198154aea1c1.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/11-2c6ddc17-49f5-47b5-8764-753297cf9e1b.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/12-f079d0a2-9c1c-4e7a-abf6-3e3c4cddac11.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/13-5bda9382-a06e-493d-85cb-e066172778ce.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/14-6f9c669f-25e2-4096-b7ea-9b421a37e110.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/15-2068cca9-31e8-45a3-86d1-bcb8924c72b9.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/16-72356bb2-5c98-424e-97aa-a92fa3453da6.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/17-9baa67ce-f6d3-478c-9511-20d01988d4d5.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/18-b9f2e28e-c4c5-4ce7-bf58-402d53a39558.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/19-d199d9f9-7990-4ec0-adde-e98c1c927202.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/2-3827747c-095e-41cb-af69-3814bab3a588.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/20-31c197a3-7a23-472f-a7e3-056c0ff11e3a.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/21-066e3024-36f8-4557-83ae-d2f338ec045c.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/22-1d1ccbe5-7c4c-4882-986a-c61ec2f7925e.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/23-b2c41628-b2d6-49f1-81b5-3cd9100894b4.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/24-e43e2e8d-9dd8-479f-b63c-d147e737c49f.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/25-188708e9-5ee1-4b5c-8e13-45dec8efd60d.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/26-4f4b6316-5680-4b31-8dd6-215cce66d7b5.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/27-c1855f86-abab-44ef-9e61-1312dffc9b06.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/28-650d2be0-e977-4177-b457-b733eea8b6ea.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/29-e47751d8-0e44-46da-82bd-4836b00a8431.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/3-518fc9b8-67de-48f7-94c8-f2398c63dbc5.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/30-0db3ea0f-deca-4b5b-9d70-9fb5f741f90c.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/31-ef76f0bb-bcfa-4031-b3ad-94b51ee818a9.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/32-a763e0f1-5c8d-460f-a455-0c6f6c4f1450.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/33-30bce2aa-8e6f-4f42-a323-c420133aa20f.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/34-f91ec2f9-d34b-4fcf-8bc7-564c28e50538.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/35-7f36a75c-96a7-4868-a4db-5d5f78ecf850.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/36-f2df7f99-a37c-458a-958d-7eb5e81eee18.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/37-e0af7415-955b-4167-8705-fa9ddb643e9a.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/38-6c24a9f0-ce71-4dda-8193-479aa23c5456.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/39-72b8a20c-3112-4cf1-8b05-b74a2c02c3f2.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/4-42904942-5a79-4f28-90ce-35a4ae8c40d1.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/40-95ac7526-6a2e-4914-9654-288c41bff370.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/41-13430464-5e62-4aa8-9709-513693a75095.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/42-cbb1ad83-a906-4540-bc37-4db158eac618.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/43-3c246401-d742-49a9-b24d-cfc457685461.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/44-11315c14-ecf4-4e3d-8690-46d57cb3e8c0.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/45-7bbf4bc6-96d4-425a-afa2-34aec7121c85.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/5-82dda0b4-7838-4f04-90f3-4b1e932c6891.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/6-c78352d8-16ba-4814-bd7f-74b8c0c5efe7.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/7-bb882b35-63f3-4c52-870f-6a64e3ac7f3c.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/8-fc84ad1b-1b59-4822-8fc7-70f4eb18f6d9.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_transactions/9-3404dcf1-bb17-40e6-9e5d-d9942dff90b2.txn +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/1.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/10.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/11.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/12.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/13.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/14.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/15.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/16.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/17.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/18.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/19.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/2.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/20.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/21.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/22.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/23.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/24.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/25.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/26.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/27.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/28.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/29.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/3.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/30.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/31.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/32.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/33.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/34.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/35.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/36.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/37.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/38.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/39.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/4.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/40.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/41.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/42.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/43.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/44.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/45.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/46.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/5.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/6.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/7.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/8.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/_versions/9.manifest +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/0cc94dc3-2ca3-403c-a9df-59753f24b3f2.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/254a1a71-cdd2-4cca-b7ec-a50540fed62c.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/2574d216-5f05-4794-9e1c-986fafde6ab4.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/26c7bbe7-5f97-4453-b065-123b764448b3.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/286595a6-88f6-4b05-861e-e4f607a6fcdb.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/33219b1a-7575-46ef-bb64-2bdbde1e692b.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/344ad7dd-98bb-41de-b347-2f17bf5735cb.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/395b1ecb-68fe-4dd3-a770-4b3ed393ae0c.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/3db97f4c-9c35-44b7-9042-82b4006c5a22.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/4540246e-b0bb-4f4d-8f98-60a64f1c42ed.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/4643dbc0-9e45-4b63-81e1-e06cf9bddcec.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/4f28eb52-d409-43f2-ae17-d1826f209006.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/4fda4a22-35f0-4897-b4c5-6cedefba66e6.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/51ee77b6-ab24-44c0-916e-b81ff3912731.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/539d15c9-e88b-400c-9ab7-08f5e8dca10d.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/54007132-91f5-4909-8678-c471ef4d100f.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/546d88ec-0d5c-42bb-bccc-3271f3f183a4.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/6912ad8a-343c-4ca1-b1b7-4300125e688e.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/6b72e4f7-3051-40a4-a492-6d9eff1c647d.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/6d7ee320-ae1c-4e49-8ce5-c85971b11ce6.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/6ea47b70-69d4-43e9-b2c6-442fe50e4dd1.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/72adb5ed-bf11-4d06-b146-0272d333db08.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/745907df-e261-4f4b-a757-2c01c058bf27.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/78988307-4c66-4ad7-b295-7463ecd53609.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/798ce305-6d60-4f28-b82a-e1f647907abf.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/7c159cce-2741-442b-9c63-f44bf2996718.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/7cd7a818-e68b-4fa8-bad3-23b60c386670.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/7ec553ed-0c7a-4bac-99b2-2ad976b40466.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/83efdc85-d990-4762-b69a-fb1c3938f60f.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/8c1613b3-8d69-49c5-bfd0-a021bb516faf.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/95cd1b22-1f93-4133-9841-de21549ad8c5.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/9a2ea5d4-087e-4d3a-b64b-6c568b8a0010.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/b1c47dc6-450a-4dca-b465-badb6a3619c2.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/b21d183a-c51d-463b-932e-9beb2e0da9aa.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/b2598625-8683-4c33-be40-6f1a7555dc2c.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/b7297b39-1fc5-4886-be21-708b369bef59.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/b7d90085-5bd6-48f9-8a73-17eb7cf556fa.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/b988ceee-57fc-423b-8e67-5729086c6946.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/bfd68ea6-ddf4-44bb-aa87-2669f0462f7d.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/cb8ac58e-0e59-4391-95ab-6195e71b9625.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/d0f10434-afb5-49c5-9e77-d39a4f8cca94.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/d3f89fec-5795-4e11-8c15-bc2206a7fae2.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/e063c8a4-5ef1-4933-a049-b41049d9be5f.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/e2348b24-f290-4fe2-a6c8-e98009ae4c1b.lance +0 -0
- scmcp_shared/vector_db/decoupler.lance/data/e5d3f893-6763-40dc-9d02-04e2f56a4883.lance +0 -0
- {scmcp_shared-0.4.0.dist-info → scmcp_shared-0.5.0.dist-info}/METADATA +2 -1
- scmcp_shared-0.5.0.dist-info/RECORD +171 -0
- scmcp_shared/server/base.py +0 -148
- scmcp_shared-0.4.0.dist-info/RECORD +0 -24
- {scmcp_shared-0.4.0.dist-info → scmcp_shared-0.5.0.dist-info}/WHEEL +0 -0
- {scmcp_shared-0.4.0.dist-info → scmcp_shared-0.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,21 +1,28 @@
|
|
1
|
-
from fastmcp import FastMCP, Context
|
2
|
-
import os
|
3
|
-
import inspect
|
4
|
-
from fastmcp import FastMCP
|
5
1
|
import scanpy as sc
|
6
2
|
from fastmcp.exceptions import ToolError
|
7
3
|
from fastmcp.tools.tool import Tool
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from scmcp_shared.util import
|
11
|
-
|
4
|
+
from scmcp_shared.schema.preset.tl import *
|
5
|
+
from scmcp_shared.schema.preset import AdataInfo
|
6
|
+
from scmcp_shared.util import (
|
7
|
+
filter_args,
|
8
|
+
add_op_log,
|
9
|
+
forward_request,
|
10
|
+
get_ads,
|
11
|
+
generate_msg,
|
12
|
+
)
|
13
|
+
from scmcp_shared.mcp_base import BaseMCP
|
12
14
|
|
13
15
|
|
14
16
|
class ScanpyToolsMCP(BaseMCP):
|
15
|
-
def __init__(
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
include_tools: list = None,
|
20
|
+
exclude_tools: list = None,
|
21
|
+
AdataInfo: AdataInfo = AdataInfo,
|
22
|
+
):
|
16
23
|
"""
|
17
24
|
Initialize ScanpyMCP with optional tool filtering.
|
18
|
-
|
25
|
+
|
19
26
|
Args:
|
20
27
|
include_tools (list, optional): List of tool names to include. If None, all tools are included.
|
21
28
|
exclude_tools (list, optional): List of tool names to exclude. If None, no tools are excluded.
|
@@ -24,7 +31,9 @@ class ScanpyToolsMCP(BaseMCP):
|
|
24
31
|
super().__init__("ScanpyMCP-TL-Server", include_tools, exclude_tools, AdataInfo)
|
25
32
|
|
26
33
|
def _tool_tsne(self):
|
27
|
-
def _tsne(
|
34
|
+
def _tsne(
|
35
|
+
request: TSNEParam = TSNEParam(), adinfo: self.AdataInfo = self.AdataInfo()
|
36
|
+
):
|
28
37
|
"""t-distributed stochastic neighborhood embedding (t-SNE) for visualization"""
|
29
38
|
try:
|
30
39
|
result = forward_request("tl_tsne", request, adinfo)
|
@@ -39,14 +48,17 @@ class ScanpyToolsMCP(BaseMCP):
|
|
39
48
|
except ToolError as e:
|
40
49
|
raise ToolError(e)
|
41
50
|
except Exception as e:
|
42
|
-
if hasattr(e,
|
51
|
+
if hasattr(e, "__context__") and e.__context__:
|
43
52
|
raise ToolError(e.__context__)
|
44
53
|
else:
|
45
54
|
raise ToolError(e)
|
46
|
-
|
55
|
+
|
56
|
+
return Tool.from_function(_tsne, name="tsne", enabled=True)
|
47
57
|
|
48
58
|
def _tool_umap(self):
|
49
|
-
def _umap(
|
59
|
+
def _umap(
|
60
|
+
request: UMAPParam = UMAPParam(), adinfo: self.AdataInfo = self.AdataInfo()
|
61
|
+
):
|
50
62
|
"""Uniform Manifold Approximation and Projection (UMAP) for visualization"""
|
51
63
|
try:
|
52
64
|
result = forward_request("tl_umap", request, adinfo)
|
@@ -61,19 +73,22 @@ class ScanpyToolsMCP(BaseMCP):
|
|
61
73
|
except ToolError as e:
|
62
74
|
raise ToolError(e)
|
63
75
|
except Exception as e:
|
64
|
-
if hasattr(e,
|
76
|
+
if hasattr(e, "__context__") and e.__context__:
|
65
77
|
raise ToolError(e.__context__)
|
66
78
|
else:
|
67
79
|
raise ToolError(e)
|
68
|
-
|
80
|
+
|
81
|
+
return Tool.from_function(_umap, name="umap", enabled=True)
|
69
82
|
|
70
83
|
def _tool_draw_graph(self):
|
71
|
-
def _draw_graph(
|
84
|
+
def _draw_graph(
|
85
|
+
request: DrawGraphParam, adinfo: self.AdataInfo = self.AdataInfo()
|
86
|
+
):
|
72
87
|
"""Force-directed graph drawing"""
|
73
88
|
try:
|
74
89
|
result = forward_request("tl_draw_graph", request, adinfo)
|
75
90
|
if result is not None:
|
76
|
-
return result
|
91
|
+
return result
|
77
92
|
func_kwargs = filter_args(request, sc.tl.draw_graph)
|
78
93
|
ads = get_ads()
|
79
94
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -83,42 +98,46 @@ class ScanpyToolsMCP(BaseMCP):
|
|
83
98
|
except ToolError as e:
|
84
99
|
raise ToolError(e)
|
85
100
|
except Exception as e:
|
86
|
-
if hasattr(e,
|
101
|
+
if hasattr(e, "__context__") and e.__context__:
|
87
102
|
raise ToolError(e.__context__)
|
88
103
|
else:
|
89
104
|
raise ToolError(e)
|
90
|
-
|
105
|
+
|
106
|
+
return Tool.from_function(_draw_graph, name="draw_graph", enabled=True)
|
91
107
|
|
92
108
|
def _tool_diffmap(self):
|
93
|
-
def _diffmap(request:
|
109
|
+
def _diffmap(request: DiffMapParam, adinfo: self.AdataInfo = self.AdataInfo()):
|
94
110
|
"""Diffusion Maps for dimensionality reduction"""
|
95
111
|
try:
|
96
112
|
result = forward_request("tl_diffmap", request, adinfo)
|
97
113
|
if result is not None:
|
98
|
-
return result
|
114
|
+
return result
|
99
115
|
func_kwargs = filter_args(request, sc.tl.diffmap)
|
100
116
|
ads = get_ads()
|
101
117
|
adata = ads.get_adata(adinfo=adinfo)
|
102
118
|
sc.tl.diffmap(adata, **func_kwargs)
|
103
|
-
adata.obsm["X_diffmap"] = adata.obsm["X_diffmap"][:,1:]
|
119
|
+
adata.obsm["X_diffmap"] = adata.obsm["X_diffmap"][:, 1:]
|
104
120
|
add_op_log(adata, sc.tl.diffmap, func_kwargs, adinfo)
|
105
121
|
return [generate_msg(adinfo, adata, ads)]
|
106
122
|
except ToolError as e:
|
107
123
|
raise ToolError(e)
|
108
124
|
except Exception as e:
|
109
|
-
if hasattr(e,
|
125
|
+
if hasattr(e, "__context__") and e.__context__:
|
110
126
|
raise ToolError(e.__context__)
|
111
127
|
else:
|
112
128
|
raise ToolError(e)
|
113
|
-
return Tool.from_function(_diffmap, name="diffmap")
|
114
129
|
|
115
|
-
|
116
|
-
|
130
|
+
return Tool.from_function(_diffmap, name="diffmap", enabled=True)
|
131
|
+
|
132
|
+
def _tool_embedding_density(self):
|
133
|
+
def _embedding_density(
|
134
|
+
request: EmbeddingDensityParam, adinfo: self.AdataInfo = self.AdataInfo()
|
135
|
+
):
|
117
136
|
"""Calculate the density of cells in an embedding"""
|
118
137
|
try:
|
119
138
|
result = forward_request("tl_embedding_density", request, adinfo)
|
120
139
|
if result is not None:
|
121
|
-
return result
|
140
|
+
return result
|
122
141
|
func_kwargs = filter_args(request, sc.tl.embedding_density)
|
123
142
|
ads = get_ads()
|
124
143
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -128,19 +147,25 @@ class ScanpyToolsMCP(BaseMCP):
|
|
128
147
|
except ToolError as e:
|
129
148
|
raise ToolError(e)
|
130
149
|
except Exception as e:
|
131
|
-
if hasattr(e,
|
150
|
+
if hasattr(e, "__context__") and e.__context__:
|
132
151
|
raise ToolError(e.__context__)
|
133
152
|
else:
|
134
153
|
raise ToolError(e)
|
135
|
-
|
154
|
+
|
155
|
+
return Tool.from_function(
|
156
|
+
_embedding_density, name="embedding_density", enabled=True
|
157
|
+
)
|
136
158
|
|
137
159
|
def _tool_leiden(self):
|
138
|
-
def _leiden(
|
160
|
+
def _leiden(
|
161
|
+
request: LeidenParam = LeidenParam(),
|
162
|
+
adinfo: self.AdataInfo = self.AdataInfo(),
|
163
|
+
):
|
139
164
|
"""Leiden clustering algorithm for community detection"""
|
140
165
|
try:
|
141
166
|
result = forward_request("tl_leiden", request, adinfo)
|
142
167
|
if result is not None:
|
143
|
-
return result
|
168
|
+
return result
|
144
169
|
func_kwargs = filter_args(request, sc.tl.leiden)
|
145
170
|
ads = get_ads()
|
146
171
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -150,19 +175,23 @@ class ScanpyToolsMCP(BaseMCP):
|
|
150
175
|
except ToolError as e:
|
151
176
|
raise ToolError(e)
|
152
177
|
except Exception as e:
|
153
|
-
if hasattr(e,
|
178
|
+
if hasattr(e, "__context__") and e.__context__:
|
154
179
|
raise ToolError(e.__context__)
|
155
180
|
else:
|
156
181
|
raise ToolError(e)
|
157
|
-
|
182
|
+
|
183
|
+
return Tool.from_function(_leiden, name="leiden", enabled=True)
|
158
184
|
|
159
185
|
def _tool_louvain(self):
|
160
|
-
def _louvain(
|
186
|
+
def _louvain(
|
187
|
+
request: LouvainParam = LouvainParam(),
|
188
|
+
adinfo: self.AdataInfo = self.AdataInfo(),
|
189
|
+
):
|
161
190
|
"""Louvain clustering algorithm for community detection"""
|
162
191
|
try:
|
163
192
|
result = forward_request("tl_louvain", request, adinfo)
|
164
193
|
if result is not None:
|
165
|
-
return result
|
194
|
+
return result
|
166
195
|
func_kwargs = filter_args(request, sc.tl.louvain)
|
167
196
|
ads = get_ads()
|
168
197
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -172,19 +201,22 @@ class ScanpyToolsMCP(BaseMCP):
|
|
172
201
|
except ToolError as e:
|
173
202
|
raise ToolError(e)
|
174
203
|
except Exception as e:
|
175
|
-
if hasattr(e,
|
204
|
+
if hasattr(e, "__context__") and e.__context__:
|
176
205
|
raise ToolError(e.__context__)
|
177
206
|
else:
|
178
207
|
raise ToolError(e)
|
179
|
-
|
208
|
+
|
209
|
+
return Tool.from_function(_louvain, name="louvain", enabled=True)
|
180
210
|
|
181
211
|
def _tool_dendrogram(self):
|
182
|
-
def _dendrogram(
|
212
|
+
def _dendrogram(
|
213
|
+
request: DendrogramParam, adinfo: self.AdataInfo = self.AdataInfo()
|
214
|
+
):
|
183
215
|
"""Hierarchical clustering dendrogram"""
|
184
216
|
try:
|
185
217
|
result = forward_request("tl_dendrogram", request, adinfo)
|
186
218
|
if result is not None:
|
187
|
-
return result
|
219
|
+
return result
|
188
220
|
func_kwargs = filter_args(request, sc.tl.dendrogram)
|
189
221
|
ads = get_ads()
|
190
222
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -194,19 +226,20 @@ class ScanpyToolsMCP(BaseMCP):
|
|
194
226
|
except ToolError as e:
|
195
227
|
raise ToolError(e)
|
196
228
|
except Exception as e:
|
197
|
-
if hasattr(e,
|
229
|
+
if hasattr(e, "__context__") and e.__context__:
|
198
230
|
raise ToolError(e.__context__)
|
199
231
|
else:
|
200
232
|
raise ToolError(e)
|
201
|
-
|
233
|
+
|
234
|
+
return Tool.from_function(_dendrogram, name="dendrogram", enabled=True)
|
202
235
|
|
203
236
|
def _tool_dpt(self):
|
204
|
-
def _dpt(request:
|
237
|
+
def _dpt(request: DPTParam, adinfo: self.AdataInfo = self.AdataInfo()):
|
205
238
|
"""Diffusion Pseudotime (DPT) analysis"""
|
206
239
|
try:
|
207
240
|
result = forward_request("tl_dpt", request, adinfo)
|
208
241
|
if result is not None:
|
209
|
-
return result
|
242
|
+
return result
|
210
243
|
func_kwargs = filter_args(request, sc.tl.dpt)
|
211
244
|
ads = get_ads()
|
212
245
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -216,63 +249,68 @@ class ScanpyToolsMCP(BaseMCP):
|
|
216
249
|
except ToolError as e:
|
217
250
|
raise ToolError(e)
|
218
251
|
except Exception as e:
|
219
|
-
if hasattr(e,
|
252
|
+
if hasattr(e, "__context__") and e.__context__:
|
220
253
|
raise ToolError(e.__context__)
|
221
254
|
else:
|
222
255
|
raise ToolError(e)
|
223
|
-
|
256
|
+
|
257
|
+
return Tool.from_function(_dpt, name="dpt", enabled=True)
|
224
258
|
|
225
259
|
def _tool_paga(self):
|
226
|
-
def _paga(request:
|
260
|
+
def _paga(request: PAGAParam, adinfo: self.AdataInfo = self.AdataInfo()):
|
227
261
|
"""Partition-based graph abstraction"""
|
228
262
|
try:
|
229
263
|
result = forward_request("tl_paga", request, adinfo)
|
230
264
|
if result is not None:
|
231
|
-
return result
|
265
|
+
return result
|
232
266
|
func_kwargs = filter_args(request, sc.tl.paga)
|
233
267
|
ads = get_ads()
|
234
|
-
adata = ads.get_adata(adinfo=adinfo)
|
268
|
+
adata = ads.get_adata(adinfo=adinfo)
|
235
269
|
sc.tl.paga(adata, **func_kwargs)
|
236
270
|
add_op_log(adata, sc.tl.paga, func_kwargs, adinfo)
|
237
271
|
return [generate_msg(adinfo, adata, ads)]
|
238
272
|
except ToolError as e:
|
239
273
|
raise ToolError(e)
|
240
274
|
except Exception as e:
|
241
|
-
if hasattr(e,
|
275
|
+
if hasattr(e, "__context__") and e.__context__:
|
242
276
|
raise ToolError(e.__context__)
|
243
277
|
else:
|
244
278
|
raise ToolError(e)
|
245
|
-
|
279
|
+
|
280
|
+
return Tool.from_function(_paga, name="paga", enabled=True)
|
246
281
|
|
247
282
|
def _tool_ingest(self):
|
248
|
-
def _ingest(request:
|
283
|
+
def _ingest(request: IngestParam, adinfo: self.AdataInfo = self.AdataInfo()):
|
249
284
|
"""Map labels and embeddings from reference data to new data"""
|
250
285
|
try:
|
251
286
|
result = forward_request("tl_ingest", request, adinfo)
|
252
287
|
if result is not None:
|
253
|
-
return result
|
288
|
+
return result
|
254
289
|
func_kwargs = filter_args(request, sc.tl.ingest)
|
255
290
|
ads = get_ads()
|
256
|
-
adata = ads.get_adata(adinfo=adinfo)
|
291
|
+
adata = ads.get_adata(adinfo=adinfo)
|
257
292
|
sc.tl.ingest(adata, **func_kwargs)
|
258
293
|
add_op_log(adata, sc.tl.ingest, func_kwargs, adinfo)
|
259
294
|
return [generate_msg(adinfo, adata, ads)]
|
260
295
|
except ToolError as e:
|
261
296
|
raise ToolError(e)
|
262
297
|
except Exception as e:
|
263
|
-
if hasattr(e,
|
298
|
+
if hasattr(e, "__context__") and e.__context__:
|
264
299
|
raise ToolError(e.__context__)
|
265
300
|
else:
|
266
301
|
raise ToolError(e)
|
267
|
-
|
302
|
+
|
303
|
+
return Tool.from_function(_ingest, name="ingest", enabled=True)
|
268
304
|
|
269
305
|
def _tool_rank_genes_groups(self):
|
270
|
-
def _rank_genes_groups(
|
306
|
+
def _rank_genes_groups(
|
307
|
+
request: RankGenesGroupsParam, adinfo: self.AdataInfo = self.AdataInfo()
|
308
|
+
):
|
271
309
|
"""Rank genes for characterizing groups, for differentially expressison analysis"""
|
272
310
|
try:
|
273
311
|
result = forward_request("tl_rank_genes_groups", request, adinfo)
|
274
312
|
if result is not None:
|
275
|
-
return result
|
313
|
+
return result
|
276
314
|
func_kwargs = filter_args(request, sc.tl.rank_genes_groups)
|
277
315
|
ads = get_ads()
|
278
316
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -282,19 +320,25 @@ class ScanpyToolsMCP(BaseMCP):
|
|
282
320
|
except ToolError as e:
|
283
321
|
raise ToolError(e)
|
284
322
|
except Exception as e:
|
285
|
-
if hasattr(e,
|
323
|
+
if hasattr(e, "__context__") and e.__context__:
|
286
324
|
raise ToolError(e.__context__)
|
287
325
|
else:
|
288
326
|
raise ToolError(e)
|
289
|
-
|
327
|
+
|
328
|
+
return Tool.from_function(
|
329
|
+
_rank_genes_groups, name="rank_genes_groups", enabled=True
|
330
|
+
)
|
290
331
|
|
291
332
|
def _tool_filter_rank_genes_groups(self):
|
292
|
-
def _filter_rank_genes_groups(
|
333
|
+
def _filter_rank_genes_groups(
|
334
|
+
request: FilterRankGenesGroupsParam,
|
335
|
+
adinfo: self.AdataInfo = self.AdataInfo(),
|
336
|
+
):
|
293
337
|
"""Filter out genes based on fold change and fraction of genes"""
|
294
338
|
try:
|
295
339
|
result = forward_request("tl_filter_rank_genes_groups", request, adinfo)
|
296
340
|
if result is not None:
|
297
|
-
return result
|
341
|
+
return result
|
298
342
|
func_kwargs = filter_args(request, sc.tl.filter_rank_genes_groups)
|
299
343
|
ads = get_ads()
|
300
344
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -304,19 +348,24 @@ class ScanpyToolsMCP(BaseMCP):
|
|
304
348
|
except ToolError as e:
|
305
349
|
raise ToolError(e)
|
306
350
|
except Exception as e:
|
307
|
-
if hasattr(e,
|
351
|
+
if hasattr(e, "__context__") and e.__context__:
|
308
352
|
raise ToolError(e.__context__)
|
309
353
|
else:
|
310
354
|
raise ToolError(e)
|
311
|
-
|
355
|
+
|
356
|
+
return Tool.from_function(
|
357
|
+
_filter_rank_genes_groups, name="filter_rank_genes_groups", enabled=True
|
358
|
+
)
|
312
359
|
|
313
360
|
def _tool_marker_gene_overlap(self):
|
314
|
-
def _marker_gene_overlap(
|
361
|
+
def _marker_gene_overlap(
|
362
|
+
request: MarkerGeneOverlapParam, adinfo: self.AdataInfo = self.AdataInfo()
|
363
|
+
):
|
315
364
|
"""Calculate overlap between data-derived marker genes and reference markers"""
|
316
365
|
try:
|
317
366
|
result = forward_request("tl_marker_gene_overlap", request, adinfo)
|
318
367
|
if result is not None:
|
319
|
-
return result
|
368
|
+
return result
|
320
369
|
func_kwargs = filter_args(request, sc.tl.marker_gene_overlap)
|
321
370
|
ads = get_ads()
|
322
371
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -326,19 +375,24 @@ class ScanpyToolsMCP(BaseMCP):
|
|
326
375
|
except ToolError as e:
|
327
376
|
raise ToolError(e)
|
328
377
|
except Exception as e:
|
329
|
-
if hasattr(e,
|
378
|
+
if hasattr(e, "__context__") and e.__context__:
|
330
379
|
raise ToolError(e.__context__)
|
331
380
|
else:
|
332
381
|
raise ToolError(e)
|
333
|
-
|
382
|
+
|
383
|
+
return Tool.from_function(
|
384
|
+
_marker_gene_overlap, name="marker_gene_overlap", enabled=True
|
385
|
+
)
|
334
386
|
|
335
387
|
def _tool_score_genes(self):
|
336
|
-
def _score_genes(
|
388
|
+
def _score_genes(
|
389
|
+
request: ScoreGenesParam, adinfo: self.AdataInfo = self.AdataInfo()
|
390
|
+
):
|
337
391
|
"""Score a set of genes based on their average expression"""
|
338
392
|
try:
|
339
393
|
result = forward_request("tl_score_genes", request, adinfo)
|
340
394
|
if result is not None:
|
341
|
-
return result
|
395
|
+
return result
|
342
396
|
func_kwargs = filter_args(request, sc.tl.score_genes)
|
343
397
|
ads = get_ads()
|
344
398
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -348,19 +402,22 @@ class ScanpyToolsMCP(BaseMCP):
|
|
348
402
|
except ToolError as e:
|
349
403
|
raise ToolError(e)
|
350
404
|
except Exception as e:
|
351
|
-
if hasattr(e,
|
405
|
+
if hasattr(e, "__context__") and e.__context__:
|
352
406
|
raise ToolError(e.__context__)
|
353
407
|
else:
|
354
408
|
raise ToolError(e)
|
355
|
-
|
409
|
+
|
410
|
+
return Tool.from_function(_score_genes, name="score_genes", enabled=True)
|
356
411
|
|
357
412
|
def _tool_score_genes_cell_cycle(self):
|
358
|
-
def _score_genes_cell_cycle(
|
413
|
+
def _score_genes_cell_cycle(
|
414
|
+
request: ScoreGenesCellCycleParam, adinfo: self.AdataInfo = self.AdataInfo()
|
415
|
+
):
|
359
416
|
"""Score cell cycle genes and assign cell cycle phases"""
|
360
417
|
try:
|
361
418
|
result = forward_request("tl_score_genes_cell_cycle", request, adinfo)
|
362
419
|
if result is not None:
|
363
|
-
return result
|
420
|
+
return result
|
364
421
|
func_kwargs = filter_args(request, sc.tl.score_genes_cell_cycle)
|
365
422
|
ads = get_ads()
|
366
423
|
adata = ads.get_adata(adinfo=adinfo)
|
@@ -370,14 +427,19 @@ class ScanpyToolsMCP(BaseMCP):
|
|
370
427
|
except ToolError as e:
|
371
428
|
raise ToolError(e)
|
372
429
|
except Exception as e:
|
373
|
-
if hasattr(e,
|
430
|
+
if hasattr(e, "__context__") and e.__context__:
|
374
431
|
raise ToolError(e.__context__)
|
375
432
|
else:
|
376
433
|
raise ToolError(e)
|
377
|
-
|
434
|
+
|
435
|
+
return Tool.from_function(
|
436
|
+
_score_genes_cell_cycle, name="score_genes_cell_cycle", enabled=True
|
437
|
+
)
|
378
438
|
|
379
439
|
def _tool_pca(self):
|
380
|
-
def _pca(
|
440
|
+
def _pca(
|
441
|
+
request: PCAParam = PCAParam(), adinfo: self.AdataInfo = self.AdataInfo()
|
442
|
+
):
|
381
443
|
"""Compute PCA (Principal Component Analysis)."""
|
382
444
|
try:
|
383
445
|
result = forward_request("tl_pca", request, adinfo)
|
@@ -392,8 +454,9 @@ class ScanpyToolsMCP(BaseMCP):
|
|
392
454
|
except ToolError as e:
|
393
455
|
raise ToolError(e)
|
394
456
|
except Exception as e:
|
395
|
-
if hasattr(e,
|
457
|
+
if hasattr(e, "__context__") and e.__context__:
|
396
458
|
raise ToolError(e.__context__)
|
397
459
|
else:
|
398
460
|
raise ToolError(e)
|
399
|
-
|
461
|
+
|
462
|
+
return Tool.from_function(_pca, name="pca", enabled=True)
|