seqevi 0.2.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.
- seqevi/__init__.py +7 -0
- seqevi/__main__.py +6 -0
- seqevi/adapters/__init__.py +41 -0
- seqevi/adapters/base.py +131 -0
- seqevi/adapters/dbcan_cazyme.py +588 -0
- seqevi/adapters/eggnog.py +674 -0
- seqevi/adapters/interpro_pfam.py +757 -0
- seqevi/adapters/registry.py +68 -0
- seqevi/annotate.py +413 -0
- seqevi/api.py +390 -0
- seqevi/cli.py +610 -0
- seqevi/distribution/__init__.py +13 -0
- seqevi/distribution/manifest.py +199 -0
- seqevi/distribution/oci.py +490 -0
- seqevi/distribution/setup.py +752 -0
- seqevi/errors.py +73 -0
- seqevi/evidence.py +295 -0
- seqevi/execution_profile.py +526 -0
- seqevi/hashing.py +13 -0
- seqevi/kits/__init__.py +1 -0
- seqevi/kits/dbcan-cazyme.toml +35 -0
- seqevi/resource_lock.py +438 -0
- seqevi/result.py +682 -0
- seqevi/runner.py +163 -0
- seqevi/runtime_identity.py +104 -0
- seqevi/sequence.py +383 -0
- seqevi/service/__init__.py +11 -0
- seqevi/service/app.py +213 -0
- seqevi/service/config.py +38 -0
- seqevi/service/persistence.py +360 -0
- seqevi/store/__init__.py +14 -0
- seqevi/store/artifact.py +225 -0
- seqevi/store/client.py +311 -0
- seqevi/store/contract.py +33 -0
- seqevi/store/factory.py +38 -0
- seqevi/store/local.py +479 -0
- seqevi/store/migration.py +62 -0
- seqevi/store/migrations/__init__.py +1 -0
- seqevi/store/migrations/env.py +30 -0
- seqevi/store/migrations/versions/0001_initial_store.py +103 -0
- seqevi/store/migrations/versions/0002_artifact_byte_size_bigint.py +40 -0
- seqevi/store/migrations/versions/__init__.py +1 -0
- seqevi/store/schema.py +86 -0
- seqevi/store/transport.py +224 -0
- seqevi-0.2.0.dist-info/METADATA +333 -0
- seqevi-0.2.0.dist-info/RECORD +49 -0
- seqevi-0.2.0.dist-info/WHEEL +4 -0
- seqevi-0.2.0.dist-info/entry_points.txt +5 -0
- seqevi-0.2.0.dist-info/licenses/LICENSE +21 -0
seqevi/__init__.py
ADDED
seqevi/__main__.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Explicit first-party annotation adapter boundaries."""
|
|
2
|
+
|
|
3
|
+
from .base import (
|
|
4
|
+
AdapterBatchResult,
|
|
5
|
+
AdapterContract,
|
|
6
|
+
AdapterSequenceResult,
|
|
7
|
+
AnnotationAdapter,
|
|
8
|
+
)
|
|
9
|
+
from .dbcan_cazyme import DBCAN_EVIDENCE_SCHEMA, DBCanCazymeAdapter, DBCanParameters
|
|
10
|
+
from .eggnog import (
|
|
11
|
+
EGGNOG_EVIDENCE_SCHEMA,
|
|
12
|
+
EggnogAdapter,
|
|
13
|
+
EggnogParameters,
|
|
14
|
+
)
|
|
15
|
+
from .interpro_pfam import (
|
|
16
|
+
ADAPTER_CONTRACT_VERSION,
|
|
17
|
+
INTERPRO_PFAM_EVIDENCE_SCHEMA,
|
|
18
|
+
InterProPfamAdapter,
|
|
19
|
+
InterProPfamParameters,
|
|
20
|
+
)
|
|
21
|
+
from .registry import AdapterConfiguration, AdapterName, create_adapter
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"AdapterBatchResult",
|
|
25
|
+
"AdapterConfiguration",
|
|
26
|
+
"AdapterContract",
|
|
27
|
+
"AdapterName",
|
|
28
|
+
"AdapterSequenceResult",
|
|
29
|
+
"AnnotationAdapter",
|
|
30
|
+
"DBCAN_EVIDENCE_SCHEMA",
|
|
31
|
+
"DBCanCazymeAdapter",
|
|
32
|
+
"DBCanParameters",
|
|
33
|
+
"EGGNOG_EVIDENCE_SCHEMA",
|
|
34
|
+
"EggnogAdapter",
|
|
35
|
+
"EggnogParameters",
|
|
36
|
+
"ADAPTER_CONTRACT_VERSION",
|
|
37
|
+
"INTERPRO_PFAM_EVIDENCE_SCHEMA",
|
|
38
|
+
"InterProPfamAdapter",
|
|
39
|
+
"InterProPfamParameters",
|
|
40
|
+
"create_adapter",
|
|
41
|
+
]
|
seqevi/adapters/base.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Typed boundary shared by SeqEvi's official adapters."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Protocol
|
|
10
|
+
|
|
11
|
+
import polars as pl
|
|
12
|
+
|
|
13
|
+
from seqevi.evidence import (
|
|
14
|
+
ArtifactFile,
|
|
15
|
+
EvidenceKey,
|
|
16
|
+
EvidenceStatus,
|
|
17
|
+
canonical_semantic_parameters,
|
|
18
|
+
)
|
|
19
|
+
from seqevi.runner import ToolRunner
|
|
20
|
+
from seqevi.sequence import SequenceIdentity
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True, slots=True)
|
|
24
|
+
class AdapterContract:
|
|
25
|
+
"""Resolved immutable identity shared by one adapter invocation."""
|
|
26
|
+
|
|
27
|
+
name: str
|
|
28
|
+
version: str
|
|
29
|
+
tool_runtime_digest: str
|
|
30
|
+
resource_id: str
|
|
31
|
+
semantic_parameters_json: str
|
|
32
|
+
|
|
33
|
+
def __post_init__(self) -> None:
|
|
34
|
+
for field_name in ("name", "version", "tool_runtime_digest", "resource_id"):
|
|
35
|
+
if not getattr(self, field_name):
|
|
36
|
+
raise ValueError(f"adapter contract {field_name} must not be empty")
|
|
37
|
+
parsed = json.loads(self.semantic_parameters_json)
|
|
38
|
+
if not isinstance(parsed, dict):
|
|
39
|
+
raise ValueError("adapter semantic parameters must be a JSON object")
|
|
40
|
+
if canonical_semantic_parameters(parsed) != self.semantic_parameters_json:
|
|
41
|
+
raise ValueError("adapter semantic parameters are not canonical")
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def from_parameters(
|
|
45
|
+
cls,
|
|
46
|
+
*,
|
|
47
|
+
name: str,
|
|
48
|
+
version: str,
|
|
49
|
+
tool_runtime_digest: str,
|
|
50
|
+
resource_id: str,
|
|
51
|
+
semantic_parameters: Mapping[str, object],
|
|
52
|
+
) -> AdapterContract:
|
|
53
|
+
"""Construct a resolved contract with canonical semantic parameters."""
|
|
54
|
+
|
|
55
|
+
return cls(
|
|
56
|
+
name=name,
|
|
57
|
+
version=version,
|
|
58
|
+
tool_runtime_digest=tool_runtime_digest,
|
|
59
|
+
resource_id=resource_id,
|
|
60
|
+
semantic_parameters_json=canonical_semantic_parameters(semantic_parameters),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def semantic_parameters(self) -> dict[str, object]:
|
|
65
|
+
"""Return a fresh JSON-compatible semantic-parameter mapping."""
|
|
66
|
+
|
|
67
|
+
parameters = json.loads(self.semantic_parameters_json)
|
|
68
|
+
assert isinstance(parameters, dict)
|
|
69
|
+
return parameters
|
|
70
|
+
|
|
71
|
+
def evidence_key(self, identity: SequenceIdentity) -> EvidenceKey:
|
|
72
|
+
"""Build the exact evidence key for one canonical sequence."""
|
|
73
|
+
|
|
74
|
+
return EvidenceKey(
|
|
75
|
+
sequence_id=identity.sequence_id,
|
|
76
|
+
adapter_contract_version=self.version,
|
|
77
|
+
tool_runtime_digest=self.tool_runtime_digest,
|
|
78
|
+
resource_id=self.resource_id,
|
|
79
|
+
semantic_parameters_json=self.semantic_parameters_json,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(frozen=True, slots=True)
|
|
84
|
+
class AdapterSequenceResult:
|
|
85
|
+
"""Terminal adapter result for one requested sequence."""
|
|
86
|
+
|
|
87
|
+
sequence_id: str
|
|
88
|
+
status: EvidenceStatus
|
|
89
|
+
payload_digest: str
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(frozen=True, slots=True)
|
|
93
|
+
class AdapterBatchResult:
|
|
94
|
+
"""Validated batch artifacts and per-sequence terminal states."""
|
|
95
|
+
|
|
96
|
+
sequences: tuple[AdapterSequenceResult, ...]
|
|
97
|
+
raw_artifact: ArtifactFile
|
|
98
|
+
normalized_artifact: ArtifactFile | None = None
|
|
99
|
+
|
|
100
|
+
def __post_init__(self) -> None:
|
|
101
|
+
if not self.sequences:
|
|
102
|
+
raise ValueError("adapter batch result must not be empty")
|
|
103
|
+
sequence_ids = [result.sequence_id for result in self.sequences]
|
|
104
|
+
if len(sequence_ids) != len(set(sequence_ids)):
|
|
105
|
+
raise ValueError("adapter batch result contains duplicate SequenceIDs")
|
|
106
|
+
if (
|
|
107
|
+
any(result.status is EvidenceStatus.HIT for result in self.sequences)
|
|
108
|
+
and self.normalized_artifact is None
|
|
109
|
+
):
|
|
110
|
+
raise ValueError("adapter hits require a normalized artifact")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class AnnotationAdapter(Protocol):
|
|
114
|
+
"""Behavior required by the annotation orchestrator."""
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def contract(self) -> AdapterContract: ...
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def evidence_schema(self) -> Mapping[str, pl.DataType]: ...
|
|
121
|
+
|
|
122
|
+
def run_batch(
|
|
123
|
+
self,
|
|
124
|
+
*,
|
|
125
|
+
identities: tuple[SequenceIdentity, ...],
|
|
126
|
+
input_fasta: Path,
|
|
127
|
+
work_dir: Path,
|
|
128
|
+
runner: ToolRunner,
|
|
129
|
+
timeout_seconds: float | None,
|
|
130
|
+
threads: int,
|
|
131
|
+
) -> AdapterBatchResult: ...
|