Spaces:
Sleeping
Sleeping
Update biopython/mcp_output/mcp_plugin/mcp_service.py
Browse files
biopython/mcp_output/mcp_plugin/mcp_service.py
CHANGED
|
@@ -48,11 +48,31 @@ def lazy_import_script(module_path, attr_name):
|
|
| 48 |
|
| 49 |
# Biopython top-level imports (这些是安全的)
|
| 50 |
from Bio import __version__ as bio_version
|
| 51 |
-
from Bio import Entrez, SeqIO,
|
| 52 |
from Bio.PDB import PDBParser
|
| 53 |
-
from Bio.Align import MultipleSeqAlignment
|
| 54 |
from Bio.Seq import Seq
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
mcp = FastMCP("biopython")
|
| 58 |
|
|
@@ -335,17 +355,38 @@ def pairwise_align_globalxx(payload: dict):
|
|
| 335 |
seq1 = payload.get("seq1", "")
|
| 336 |
seq2 = payload.get("seq2", "")
|
| 337 |
limit = int(payload.get("limit", 3))
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
return {"success": True, "result": result, "error": None}
|
| 350 |
except Exception as e:
|
| 351 |
return {"success": False, "result": None, "error": str(e)}
|
|
|
|
| 48 |
|
| 49 |
# Biopython top-level imports (这些是安全的)
|
| 50 |
from Bio import __version__ as bio_version
|
| 51 |
+
from Bio import Entrez, SeqIO, Phylo, AlignIO
|
| 52 |
from Bio.PDB import PDBParser
|
| 53 |
+
from Bio.Align import MultipleSeqAlignment, PairwiseAligner
|
| 54 |
from Bio.Seq import Seq
|
| 55 |
+
|
| 56 |
+
# GC function location varies by Biopython version
|
| 57 |
+
try:
|
| 58 |
+
from Bio.SeqUtils import GC
|
| 59 |
+
except ImportError:
|
| 60 |
+
try:
|
| 61 |
+
from Bio.SeqUtils import gc_fraction as GC
|
| 62 |
+
except ImportError:
|
| 63 |
+
# Fallback implementation
|
| 64 |
+
def GC(seq):
|
| 65 |
+
"""Calculate GC content percentage"""
|
| 66 |
+
seq = str(seq).upper()
|
| 67 |
+
gc = seq.count('G') + seq.count('C')
|
| 68 |
+
return (gc / len(seq)) * 100 if len(seq) > 0 else 0
|
| 69 |
+
|
| 70 |
+
# pairwise2 is deprecated, but keep for compatibility
|
| 71 |
+
try:
|
| 72 |
+
from Bio import pairwise2
|
| 73 |
+
HAS_PAIRWISE2 = True
|
| 74 |
+
except (ImportError, AttributeError):
|
| 75 |
+
HAS_PAIRWISE2 = False
|
| 76 |
|
| 77 |
mcp = FastMCP("biopython")
|
| 78 |
|
|
|
|
| 355 |
seq1 = payload.get("seq1", "")
|
| 356 |
seq2 = payload.get("seq2", "")
|
| 357 |
limit = int(payload.get("limit", 3))
|
| 358 |
+
|
| 359 |
+
if HAS_PAIRWISE2:
|
| 360 |
+
# Use deprecated pairwise2 if available
|
| 361 |
+
aligns = pairwise2.align.globalxx(seq1, seq2)[:limit]
|
| 362 |
+
result = [
|
| 363 |
+
{
|
| 364 |
+
"seqA": a.seqA,
|
| 365 |
+
"seqB": a.seqB,
|
| 366 |
+
"score": a.score,
|
| 367 |
+
"start": a.start,
|
| 368 |
+
"end": a.end,
|
| 369 |
+
}
|
| 370 |
+
for a in aligns
|
| 371 |
+
]
|
| 372 |
+
else:
|
| 373 |
+
# Use modern PairwiseAligner
|
| 374 |
+
aligner = PairwiseAligner()
|
| 375 |
+
aligner.mode = 'global'
|
| 376 |
+
aligner.match_score = 1
|
| 377 |
+
aligner.mismatch_score = 0
|
| 378 |
+
alignments = list(aligner.align(seq1, seq2))[:limit]
|
| 379 |
+
result = [
|
| 380 |
+
{
|
| 381 |
+
"seqA": str(alignment).split('\n')[0],
|
| 382 |
+
"seqB": str(alignment).split('\n')[2] if len(str(alignment).split('\n')) > 2 else "",
|
| 383 |
+
"score": alignment.score,
|
| 384 |
+
"start": 0,
|
| 385 |
+
"end": len(seq1),
|
| 386 |
+
}
|
| 387 |
+
for alignment in alignments
|
| 388 |
+
]
|
| 389 |
+
|
| 390 |
return {"success": True, "result": result, "error": None}
|
| 391 |
except Exception as e:
|
| 392 |
return {"success": False, "result": None, "error": str(e)}
|