scmcp-shared 0.2.0__py3-none-any.whl → 0.2.5__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 -1
- scmcp_shared/schema/__init__.py +13 -1
- scmcp_shared/schema/io.py +4 -4
- scmcp_shared/schema/pl.py +2 -3
- scmcp_shared/schema/pp.py +15 -15
- scmcp_shared/schema/tl.py +18 -19
- scmcp_shared/schema/util.py +11 -11
- scmcp_shared/server/__init__.py +6 -6
- scmcp_shared/server/io.py +26 -16
- scmcp_shared/server/pl.py +171 -126
- scmcp_shared/server/pp.py +120 -104
- scmcp_shared/server/tl.py +168 -128
- scmcp_shared/server/util.py +72 -61
- scmcp_shared/util.py +32 -30
- {scmcp_shared-0.2.0.dist-info → scmcp_shared-0.2.5.dist-info}/METADATA +1 -1
- scmcp_shared-0.2.5.dist-info/RECORD +19 -0
- scmcp_shared/schema/base.py +0 -11
- scmcp_shared-0.2.0.dist-info/RECORD +0 -20
- {scmcp_shared-0.2.0.dist-info → scmcp_shared-0.2.5.dist-info}/WHEEL +0 -0
- {scmcp_shared-0.2.0.dist-info → scmcp_shared-0.2.5.dist-info}/licenses/LICENSE +0 -0
scmcp_shared/server/util.py
CHANGED
@@ -3,7 +3,9 @@ import inspect
|
|
3
3
|
from pathlib import Path
|
4
4
|
import scanpy as sc
|
5
5
|
from fastmcp import FastMCP , Context
|
6
|
+
from fastmcp.exceptions import ToolError
|
6
7
|
from ..schema.util import *
|
8
|
+
from ..schema import AdataModel
|
7
9
|
from ..util import filter_args, forward_request, get_ads, generate_msg,add_op_log
|
8
10
|
|
9
11
|
|
@@ -11,9 +13,12 @@ ul_mcp = FastMCP("SCMCP-Util-Server")
|
|
11
13
|
|
12
14
|
|
13
15
|
@ul_mcp.tool()
|
14
|
-
async def query_op_log(
|
16
|
+
async def query_op_log(
|
17
|
+
request: QueryOpLogModel = QueryOpLogModel(),
|
18
|
+
adinfo: AdataModel = AdataModel()
|
19
|
+
):
|
15
20
|
"""Query the adata operation log"""
|
16
|
-
adata = get_ads().get_adata(
|
21
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
17
22
|
op_dic = adata.uns["operation"]["op"]
|
18
23
|
opids = adata.uns["operation"]["opid"][-n:]
|
19
24
|
op_list = []
|
@@ -24,7 +29,8 @@ async def query_op_log(request: QueryOpLogModel = QueryOpLogModel()):
|
|
24
29
|
|
25
30
|
@ul_mcp.tool()
|
26
31
|
async def mark_var(
|
27
|
-
request: MarkVarModel = MarkVarModel()
|
32
|
+
request: MarkVarModel = MarkVarModel(),
|
33
|
+
adinfo: AdataModel = AdataModel()
|
28
34
|
):
|
29
35
|
"""
|
30
36
|
Determine if each gene meets specific conditions and store results in adata.var as boolean values.
|
@@ -32,10 +38,10 @@ async def mark_var(
|
|
32
38
|
The tool should be called first when calculate quality control metrics for mitochondrion, ribosomal, harhemoglobin genes, or other qc_vars.
|
33
39
|
"""
|
34
40
|
try:
|
35
|
-
result = await forward_request("ul_mark_var", request)
|
41
|
+
result = await forward_request("ul_mark_var", request, adinfo)
|
36
42
|
if result is not None:
|
37
43
|
return result
|
38
|
-
adata = get_ads().get_adata(
|
44
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
39
45
|
var_name = request.var_name
|
40
46
|
gene_class = request.gene_class
|
41
47
|
pattern_type = request.pattern_type
|
@@ -64,120 +70,124 @@ async def mark_var(
|
|
64
70
|
|
65
71
|
res = {var_name: adata.var[var_name].value_counts().to_dict(), "msg": f"add '{var_name}' column in adata.var"}
|
66
72
|
func_kwargs = {"var_name": var_name, "gene_class": gene_class, "pattern_type": pattern_type, "patterns": patterns}
|
67
|
-
add_op_log(adata, "mark_var", func_kwargs)
|
73
|
+
add_op_log(adata, "mark_var", func_kwargs, adinfo)
|
68
74
|
return res
|
69
|
-
except
|
70
|
-
raise e
|
75
|
+
except ToolError as e:
|
76
|
+
raise ToolError(e)
|
71
77
|
except Exception as e:
|
72
78
|
if hasattr(e, '__context__') and e.__context__:
|
73
|
-
raise
|
79
|
+
raise ToolError(e.__context__)
|
74
80
|
else:
|
75
|
-
raise e
|
81
|
+
raise ToolError(e)
|
76
82
|
|
77
83
|
|
78
84
|
@ul_mcp.tool()
|
79
85
|
async def list_var(
|
80
|
-
request: ListVarModel = ListVarModel()
|
86
|
+
request: ListVarModel = ListVarModel(),
|
87
|
+
adinfo: AdataModel = AdataModel()
|
81
88
|
):
|
82
89
|
"""List key columns in adata.var. It should be called for checking when other tools need var key column names as input."""
|
83
90
|
try:
|
84
|
-
result = await forward_request("ul_list_var", request)
|
91
|
+
result = await forward_request("ul_list_var", request, adinfo)
|
85
92
|
if result is not None:
|
86
93
|
return result
|
87
|
-
adata = get_ads().get_adata(
|
94
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
88
95
|
columns = list(adata.var.columns)
|
89
|
-
add_op_log(adata, list_var, {})
|
96
|
+
add_op_log(adata, list_var, {}, adinfo)
|
90
97
|
return columns
|
91
|
-
except
|
92
|
-
raise e
|
98
|
+
except ToolError as e:
|
99
|
+
raise ToolError(e)
|
93
100
|
except Exception as e:
|
94
101
|
if hasattr(e, '__context__') and e.__context__:
|
95
|
-
raise
|
102
|
+
raise ToolError(e.__context__)
|
96
103
|
else:
|
97
|
-
raise e
|
104
|
+
raise ToolError(e)
|
98
105
|
|
99
106
|
@ul_mcp.tool()
|
100
107
|
async def list_obs(
|
101
|
-
request: ListObsModel = ListObsModel()
|
108
|
+
request: ListObsModel = ListObsModel(),
|
109
|
+
adinfo: AdataModel = AdataModel()
|
102
110
|
):
|
103
111
|
"""List key columns in adata.obs. It should be called before other tools need obs key column names input."""
|
104
112
|
try:
|
105
|
-
result = await forward_request("ul_list_obs", request)
|
113
|
+
result = await forward_request("ul_list_obs", request, adinfo)
|
106
114
|
if result is not None:
|
107
115
|
return result
|
108
|
-
adata = get_ads().get_adata(
|
116
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
109
117
|
columns = list(adata.obs.columns)
|
110
|
-
add_op_log(adata, list_obs, {})
|
118
|
+
add_op_log(adata, list_obs, {}, adinfo)
|
111
119
|
return columns
|
112
|
-
except
|
113
|
-
raise e
|
120
|
+
except ToolError as e:
|
121
|
+
raise ToolError(e)
|
114
122
|
except Exception as e:
|
115
123
|
if hasattr(e, '__context__') and e.__context__:
|
116
|
-
raise
|
124
|
+
raise ToolError(e.__context__)
|
117
125
|
else:
|
118
|
-
raise e
|
126
|
+
raise ToolError(e)
|
119
127
|
|
120
128
|
@ul_mcp.tool()
|
121
129
|
async def check_var(
|
122
|
-
request: VarNamesModel = VarNamesModel()
|
130
|
+
request: VarNamesModel = VarNamesModel(),
|
131
|
+
adinfo: AdataModel = AdataModel()
|
123
132
|
):
|
124
133
|
"""Check if genes/variables exist in adata.var_names. This tool should be called before gene expression visualizations or color by genes."""
|
125
134
|
try:
|
126
|
-
result = await forward_request("ul_check_var", request)
|
135
|
+
result = await forward_request("ul_check_var", request, adinfo)
|
127
136
|
if result is not None:
|
128
137
|
return result
|
129
|
-
adata = get_ads().get_adata(
|
138
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
130
139
|
var_names = request.var_names
|
131
140
|
result = {v: v in adata.var_names for v in var_names}
|
132
|
-
add_op_log(adata, check_var, {"var_names": var_names})
|
141
|
+
add_op_log(adata, check_var, {"var_names": var_names}, adinfo)
|
133
142
|
return result
|
134
|
-
except
|
135
|
-
raise e
|
143
|
+
except ToolError as e:
|
144
|
+
raise ToolError(e)
|
136
145
|
except Exception as e:
|
137
146
|
if hasattr(e, '__context__') and e.__context__:
|
138
|
-
raise
|
147
|
+
raise ToolError(e.__context__)
|
139
148
|
else:
|
140
|
-
raise e
|
149
|
+
raise ToolError(e)
|
141
150
|
|
142
151
|
@ul_mcp.tool()
|
143
152
|
async def merge_adata(
|
144
|
-
request:
|
153
|
+
request: ConcatBaseModel = ConcatBaseModel(),
|
154
|
+
adinfo: AdataModel = AdataModel()
|
145
155
|
):
|
146
156
|
"""Merge multiple adata objects."""
|
147
157
|
|
148
158
|
try:
|
149
|
-
result = await forward_request("ul_merge_adata", request)
|
159
|
+
result = await forward_request("ul_merge_adata", request, adinfo)
|
150
160
|
if result is not None:
|
151
161
|
return result
|
152
162
|
ads = get_ads()
|
153
|
-
adata = ads.get_adata(
|
163
|
+
adata = ads.get_adata(adinfo=adinfo)
|
154
164
|
kwargs = {k: v for k, v in request.model_dump().items() if v is not None}
|
155
165
|
merged_adata = adata.concat(list(ads.adata_dic[dtype].values()), **kwargs)
|
156
166
|
ads.adata_dic[dtype] = {}
|
157
167
|
ads.active_id = "merged_adata"
|
158
|
-
add_op_log(merged_adata, ad.concat, kwargs)
|
168
|
+
add_op_log(merged_adata, ad.concat, kwargs, adinfo)
|
159
169
|
ads.adata_dic[ads.active_id] = merged_adata
|
160
170
|
return {"status": "success", "message": "Successfully merged all AnnData objects"}
|
161
|
-
except
|
162
|
-
raise e
|
171
|
+
except ToolError as e:
|
172
|
+
raise ToolError(e)
|
163
173
|
except Exception as e:
|
164
174
|
if hasattr(e, '__context__') and e.__context__:
|
165
|
-
raise
|
175
|
+
raise ToolError(e.__context__)
|
166
176
|
else:
|
167
|
-
raise e
|
177
|
+
raise ToolError(e)
|
168
178
|
|
169
179
|
|
170
180
|
@ul_mcp.tool()
|
171
181
|
async def set_dpt_iroot(
|
172
182
|
request: DPTIROOTModel,
|
173
|
-
|
183
|
+
adinfo: AdataModel = AdataModel()
|
174
184
|
):
|
175
185
|
"""Set the iroot cell"""
|
176
186
|
try:
|
177
|
-
result = await forward_request("ul_set_dpt_iroot", request)
|
187
|
+
result = await forward_request("ul_set_dpt_iroot", request, adinfo)
|
178
188
|
if result is not None:
|
179
189
|
return result
|
180
|
-
adata = get_ads().get_adata(
|
190
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
181
191
|
diffmap_key = request.diffmap_key
|
182
192
|
dimension = request.dimension
|
183
193
|
direction = request.direction
|
@@ -189,28 +199,29 @@ async def set_dpt_iroot(
|
|
189
199
|
adata.uns["iroot"] = adata.obsm[diffmap_key][:, dimension].argmax()
|
190
200
|
|
191
201
|
func_kwargs = {"diffmap_key": diffmap_key, "dimension": dimension, "direction": direction}
|
192
|
-
add_op_log(adata, "set_dpt_iroot", func_kwargs)
|
202
|
+
add_op_log(adata, "set_dpt_iroot", func_kwargs, adinfo)
|
193
203
|
|
194
204
|
return {"status": "success", "message": f"Successfully set root cell for DPT using {direction} of dimension {dimension}"}
|
195
|
-
except
|
196
|
-
raise e
|
205
|
+
except ToolError as e:
|
206
|
+
raise ToolError(e)
|
197
207
|
except Exception as e:
|
198
208
|
if hasattr(e, '__context__') and e.__context__:
|
199
|
-
raise
|
209
|
+
raise ToolError(e.__context__)
|
200
210
|
else:
|
201
|
-
raise e
|
211
|
+
raise ToolError(e)
|
202
212
|
|
203
213
|
@ul_mcp.tool()
|
204
214
|
async def add_layer(
|
205
215
|
request: AddLayerModel,
|
216
|
+
adinfo: AdataModel = AdataModel()
|
206
217
|
):
|
207
218
|
"""Add a layer to the AnnData object.
|
208
219
|
"""
|
209
220
|
try:
|
210
|
-
result = await forward_request("ul_add_layer", request)
|
221
|
+
result = await forward_request("ul_add_layer", request, adinfo)
|
211
222
|
if result is not None:
|
212
223
|
return result
|
213
|
-
adata = get_ads().get_adata(
|
224
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
214
225
|
layer_name = request.layer_name
|
215
226
|
|
216
227
|
# Check if layer already exists
|
@@ -220,19 +231,19 @@ async def add_layer(
|
|
220
231
|
adata.layers[layer_name] = adata.X.copy()
|
221
232
|
|
222
233
|
func_kwargs = {"layer_name": layer_name}
|
223
|
-
add_op_log(adata, "add_layer", func_kwargs)
|
234
|
+
add_op_log(adata, "add_layer", func_kwargs, adinfo)
|
224
235
|
|
225
236
|
return {
|
226
237
|
"status": "success",
|
227
238
|
"message": f"Successfully added layer '{layer_name}' to adata.layers"
|
228
239
|
}
|
229
|
-
except
|
230
|
-
raise e
|
240
|
+
except ToolError as e:
|
241
|
+
raise ToolError(e)
|
231
242
|
except Exception as e:
|
232
243
|
if hasattr(e, '__context__') and e.__context__:
|
233
|
-
raise
|
244
|
+
raise ToolError(e.__context__)
|
234
245
|
else:
|
235
|
-
raise e
|
246
|
+
raise ToolError(e)
|
236
247
|
|
237
248
|
@ul_mcp.tool()
|
238
249
|
async def check_samples():
|
@@ -241,10 +252,10 @@ async def check_samples():
|
|
241
252
|
try:
|
242
253
|
ads = get_ads()
|
243
254
|
return {"sampleid": [list(ads.adata_dic[dk].keys()) for dk in ads.adata_dic.keys()]}
|
244
|
-
except
|
245
|
-
raise e
|
255
|
+
except ToolError as e:
|
256
|
+
raise ToolError(e)
|
246
257
|
except Exception as e:
|
247
258
|
if hasattr(e, '__context__') and e.__context__:
|
248
|
-
raise
|
259
|
+
raise ToolError(e.__context__)
|
249
260
|
else:
|
250
|
-
raise e
|
261
|
+
raise ToolError(e)
|
scmcp_shared/util.py
CHANGED
@@ -2,7 +2,7 @@ import inspect
|
|
2
2
|
import os
|
3
3
|
from pathlib import Path
|
4
4
|
from fastmcp.server.dependencies import get_context
|
5
|
-
|
5
|
+
from fastmcp.exceptions import ToolError
|
6
6
|
|
7
7
|
|
8
8
|
def get_env(key):
|
@@ -19,7 +19,7 @@ def filter_args(request, func, **extra_kwargs):
|
|
19
19
|
return func_kwargs
|
20
20
|
|
21
21
|
|
22
|
-
def add_op_log(adata, func, kwargs):
|
22
|
+
def add_op_log(adata, func, kwargs, adinfo):
|
23
23
|
import hashlib
|
24
24
|
import json
|
25
25
|
|
@@ -37,7 +37,7 @@ def add_op_log(adata, func, kwargs):
|
|
37
37
|
func_name = func.__class__.__name__
|
38
38
|
else:
|
39
39
|
func_name = str(func)
|
40
|
-
new_kwargs = {}
|
40
|
+
new_kwargs = {**adinfo.model_dump()}
|
41
41
|
for k,v in kwargs.items():
|
42
42
|
if isinstance(v, tuple):
|
43
43
|
new_kwargs[k] = list(v)
|
@@ -50,6 +50,7 @@ def add_op_log(adata, func, kwargs):
|
|
50
50
|
hash_input = f"{func_name}:{kwargs_str}"
|
51
51
|
hash_key = hashlib.md5(hash_input.encode()).hexdigest()
|
52
52
|
adata.uns["operation"]["op"][hash_key] = {func_name: new_kwargs}
|
53
|
+
adata.uns["operation"]["opid"] = list(adata.uns["operation"]["opid"])
|
53
54
|
adata.uns["operation"]["opid"].append(hash_key)
|
54
55
|
from .logging_config import setup_logger
|
55
56
|
logger = setup_logger(log_file=get_env("LOG_FILE"))
|
@@ -103,7 +104,7 @@ def set_fig_path(axes, func=None, **kwargs):
|
|
103
104
|
args.append(f"{k}-{'-'.join([str(i) for i in v])}")
|
104
105
|
else:
|
105
106
|
args.append(f"{k}-{v}")
|
106
|
-
args_str = "_".join(args)
|
107
|
+
args_str = "_".join(args).replace(" ", "")
|
107
108
|
fig_path = fig_dir / f"{func_name}_{args_str}.png"
|
108
109
|
try:
|
109
110
|
savefig(axes, fig_path)
|
@@ -134,13 +135,22 @@ async def get_figure(request):
|
|
134
135
|
return FileResponse(figure_path)
|
135
136
|
|
136
137
|
|
137
|
-
|
138
|
+
def add_figure_route(server):
|
139
|
+
from starlette.routing import Route
|
140
|
+
server._additional_http_routes = [Route("/figures/{figure_name}", endpoint=get_figure)]
|
141
|
+
|
142
|
+
|
143
|
+
async def forward_request(func, request, adinfo, **kwargs):
|
138
144
|
from fastmcp import Client
|
139
145
|
forward_url = get_env("FORWARD")
|
140
146
|
request_kwargs = request.model_dump()
|
141
147
|
request_args = request.model_fields_set
|
142
|
-
func_kwargs = {
|
143
|
-
|
148
|
+
func_kwargs = {
|
149
|
+
"request": {k: request_kwargs.get(k) for k in request_args},
|
150
|
+
"adinfo": adinfo.model_dump()
|
151
|
+
}
|
152
|
+
print(func_kwargs)
|
153
|
+
# func_kwargs.update({k:v for k,v in kwargs.items() if v is not None})
|
144
154
|
if not forward_url:
|
145
155
|
return None
|
146
156
|
|
@@ -151,8 +161,14 @@ async def forward_request(func, request, **kwargs):
|
|
151
161
|
try:
|
152
162
|
result = await client.call_tool(func, func_kwargs)
|
153
163
|
return result
|
164
|
+
except ToolError as e:
|
165
|
+
raise ToolError(e)
|
154
166
|
except Exception as e:
|
155
|
-
|
167
|
+
if hasattr(e, '__context__') and e.__context__:
|
168
|
+
raise Exception(f"{str(e.__context__)}")
|
169
|
+
else:
|
170
|
+
raise e
|
171
|
+
|
156
172
|
|
157
173
|
def obsm2adata(adata, obsm_key):
|
158
174
|
from anndata import AnnData
|
@@ -163,39 +179,25 @@ def obsm2adata(adata, obsm_key):
|
|
163
179
|
return AnnData(adata.obsm[obsm_key], obs=adata.obs, obsm=adata.obsm)
|
164
180
|
|
165
181
|
|
166
|
-
async def get_figure(request):
|
167
|
-
figure_name = request.path_params["figure_name"]
|
168
|
-
figure_path = f"./figures/{figure_name}"
|
169
|
-
|
170
|
-
if not os.path.isfile(figure_path):
|
171
|
-
return Response(content={"error": "figure not found"}, media_type="application/json")
|
172
|
-
|
173
|
-
return FileResponse(figure_path)
|
174
|
-
|
175
|
-
|
176
|
-
def add_figure_route(server):
|
177
|
-
from starlette.routing import Route
|
178
|
-
server._additional_http_routes = [Route("/figures/{figure_name}", endpoint=get_figure)]
|
179
|
-
|
180
|
-
|
181
182
|
def get_ads():
|
182
183
|
ctx = get_context()
|
183
184
|
ads = ctx.request_context.lifespan_context
|
184
185
|
return ads
|
185
186
|
|
186
187
|
|
187
|
-
def generate_msg(
|
188
|
-
|
189
|
-
|
190
|
-
dtype = kwargs.get("dtype", "exp")
|
191
|
-
return {"sampleid": sampleid or ads.active_id, "dtype": dtype, "adata": adata}
|
188
|
+
def generate_msg(adinfo, adata, ads):
|
189
|
+
return {"sampleid": adinfo.sampleid or ads.active_id, "dtype": adinfo.adtype, "adata": adata}
|
190
|
+
|
192
191
|
|
192
|
+
def sc_like_plot(plot_func, adata, request, adinfo, **kwargs):
|
193
|
+
from matplotlib import pyplot as plt
|
193
194
|
|
194
|
-
def sc_like_plot(plot_func, adata, request, **kwargs):
|
195
195
|
func_kwargs = filter_args(request, plot_func, show=False, save=False)
|
196
196
|
axes = plot_func(adata, **func_kwargs)
|
197
|
+
if axes is None:
|
198
|
+
axes = plt.gca()
|
197
199
|
fig_path = set_fig_path(axes, plot_func, **func_kwargs)
|
198
|
-
add_op_log(adata, plot_func, func_kwargs)
|
200
|
+
add_op_log(adata, plot_func, func_kwargs, adinfo)
|
199
201
|
return fig_path
|
200
202
|
|
201
203
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
scmcp_shared/__init__.py,sha256=9WXFueskl8xksdIA9MJUyauJD-k4jXiK79wuJfC3MuI,24
|
2
|
+
scmcp_shared/logging_config.py,sha256=eCuLuyxMmbj8A1E0VqYWoKA5JPTSbo6cmjS4LOyd0RQ,872
|
3
|
+
scmcp_shared/util.py,sha256=pQFqFVf8leGqKK38RgXzgtEvXWi8dZBjTuJB0rKTOnw,6957
|
4
|
+
scmcp_shared/schema/__init__.py,sha256=iwFLgyjBFYDS2OMCXhv54Jb3LUQr2EH5POqaqN5gBX0,412
|
5
|
+
scmcp_shared/schema/io.py,sha256=jpWcw4nUKsCRkG9ybOHLb2kS4wyN16Rj1AuzR-8Sm6U,4893
|
6
|
+
scmcp_shared/schema/pl.py,sha256=rzE09wHMY3JR56HZc-QfIUUM0fGXRKd-7Dh3CrQrFB0,29547
|
7
|
+
scmcp_shared/schema/pp.py,sha256=48F6oKf-I8IZuNQDfq_Lpp3fLLKA4PruqRje_ZrtTyw,21664
|
8
|
+
scmcp_shared/schema/tl.py,sha256=9mYTwdk3XSJ2A_TdqS_974VSS7Nl4NKyewVN1bwnJBg,34450
|
9
|
+
scmcp_shared/schema/util.py,sha256=x_2GPsmliHabi9V5C6YEv_M8ZHJsinDZJ6ePWrLPmcI,4815
|
10
|
+
scmcp_shared/server/__init__.py,sha256=zLV89TwMICoaAIqx65_Vbh1RP72Z0EgSvqBMFZhYBpc,1790
|
11
|
+
scmcp_shared/server/io.py,sha256=0XzQoxipwK4ml2gmPfrZqMYyy37kqyUyr8hSCnjzyVE,2631
|
12
|
+
scmcp_shared/server/pl.py,sha256=9DGF7PM-rB1CDMdv_vHiSZmI-ggMWcRKEZwB1GVenxI,12426
|
13
|
+
scmcp_shared/server/pp.py,sha256=6p6jGTunU858uuGoXHodiWTdHRufKs9-_WlWtS82esQ,12976
|
14
|
+
scmcp_shared/server/tl.py,sha256=OAF-dFQ5Lhw8RrAUir860IWgbPcaeAyQbFdKcP_tlQ4,14912
|
15
|
+
scmcp_shared/server/util.py,sha256=MXDpJA1Zn2eFE_LpW5t4eVUdGr6dUOXIM8KoyfweJUA,9607
|
16
|
+
scmcp_shared-0.2.5.dist-info/METADATA,sha256=dTs0LfEmYxRWQpv9rkvfnkeqzCRTGrHfzhZZCYBLdeE,2099
|
17
|
+
scmcp_shared-0.2.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
18
|
+
scmcp_shared-0.2.5.dist-info/licenses/LICENSE,sha256=YNr1hpea195yq-wGtB8j-2dGtt7A5G00WENmxa7JGco,1495
|
19
|
+
scmcp_shared-0.2.5.dist-info/RECORD,,
|
scmcp_shared/schema/base.py
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
from pydantic import Field, BaseModel,ConfigDict
|
2
|
-
|
3
|
-
|
4
|
-
class AdataModel(BaseModel):
|
5
|
-
"""Input schema for the adata tool."""
|
6
|
-
sampleid: str = Field(default=None, description="adata sampleid")
|
7
|
-
adtype: str = Field(default="exp", description="adata.X data type")
|
8
|
-
|
9
|
-
model_config = ConfigDict(
|
10
|
-
extra="ignore"
|
11
|
-
)
|
@@ -1,20 +0,0 @@
|
|
1
|
-
scmcp_shared/__init__.py,sha256=ZJMoFGVU2-tXepjhh5Fhy8ZyNHtOIGZWbJygHmqwmCA,24
|
2
|
-
scmcp_shared/logging_config.py,sha256=eCuLuyxMmbj8A1E0VqYWoKA5JPTSbo6cmjS4LOyd0RQ,872
|
3
|
-
scmcp_shared/util.py,sha256=Ul88pY0aHFN42tiWwexO5LfQJgNslyOD4Jb9HTMy3uI,6814
|
4
|
-
scmcp_shared/schema/__init__.py,sha256=fwMJT4mQ3rvRJpSz9ruwwZU1GbXsUYPVQRpP56Az_JM,28
|
5
|
-
scmcp_shared/schema/base.py,sha256=hWh0534xon4gyIxwXUBVR067uFiW73nZccSs6DkcwYc,326
|
6
|
-
scmcp_shared/schema/io.py,sha256=yxa0BGQXuHCUvv6ZGQApPqMOlyJuC-eQNk7jlRGsMJ8,4913
|
7
|
-
scmcp_shared/schema/pl.py,sha256=I9SCJgjmfB0VTNio4uNnP26ajWCnsHPsDoO-yMuzYVo,29578
|
8
|
-
scmcp_shared/schema/pp.py,sha256=Uhe28zD71UDZbziesH6bgQXIRXQz_HHrr8-Hb4RQsKI,21696
|
9
|
-
scmcp_shared/schema/tl.py,sha256=QV0dP-5ZtEKUDmSV9m5ryx7uQub4rw4in7PYsxId5nU,34485
|
10
|
-
scmcp_shared/schema/util.py,sha256=R0MThHKKGYGGJu-hMc-i7fomW-6ugaoQqPi_hbKrB5A,4844
|
11
|
-
scmcp_shared/server/__init__.py,sha256=vGYGUpLt8XHRbJI84Ox6WnK4ntzsbTal99Uu14nav60,1796
|
12
|
-
scmcp_shared/server/io.py,sha256=agioBQeTREqOX8qJsP2aOTkaU3dT04uvObWhUSfOPTg,2422
|
13
|
-
scmcp_shared/server/pl.py,sha256=0KIB9n-h5L3F4TOO_ezPAEX7TVCVBOsiZd6bqD5WbGQ,11126
|
14
|
-
scmcp_shared/server/pp.py,sha256=iS-GrU2-Fyw0phLI4A44g2Y3LpFfYF7AWU5ueyzLFxY,12116
|
15
|
-
scmcp_shared/server/tl.py,sha256=k8GCTmrFh63jI5REO4-BmfCgyvcGgNpvtsxrn_0K67k,13228
|
16
|
-
scmcp_shared/server/util.py,sha256=eBkwWUSrndTb6RHujgXGZYU1aitJEocEuV6U5IOLsws,9030
|
17
|
-
scmcp_shared-0.2.0.dist-info/METADATA,sha256=Ayh--1Js_wfAHx1Wep-tw0fxihV9ikUYRWttSwAZL88,2099
|
18
|
-
scmcp_shared-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
19
|
-
scmcp_shared-0.2.0.dist-info/licenses/LICENSE,sha256=YNr1hpea195yq-wGtB8j-2dGtt7A5G00WENmxa7JGco,1495
|
20
|
-
scmcp_shared-0.2.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|