seqevi 0.3.5__tar.gz → 0.4.0__tar.gz
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-0.3.5 → seqevi-0.4.0}/PKG-INFO +75 -62
- {seqevi-0.3.5 → seqevi-0.4.0}/README.md +75 -62
- {seqevi-0.3.5 → seqevi-0.4.0}/pyproject.toml +10 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/__init__.py +4 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/annotate.py +6 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/api.py +35 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/cli.py +49 -6
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/distribution/oci.py +61 -4
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/evidence.py +25 -3
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/runner.py +30 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/service/app.py +198 -18
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/service/config.py +48 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/service/persistence.py +55 -30
- seqevi-0.4.0/src/seqevi/store/artifact.py +344 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/client.py +429 -40
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/factory.py +9 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/local.py +2 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migration.py +304 -95
- seqevi-0.4.0/src/seqevi/store/migrations/versions/0005_oci_artifact_storage.py +69 -0
- seqevi-0.4.0/src/seqevi/store/oci.py +557 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/schema.py +13 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/transport.py +117 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_api.py +62 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_architecture_contracts.py +1 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_artifact_store.py +1 -0
- seqevi-0.4.0/tests/test_artifact_upload.py +207 -0
- seqevi-0.4.0/tests/test_ci_change_scope.py +76 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_cli.py +75 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_dbcan_image_assets.py +38 -8
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_deployment_assets.py +6 -5
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_local_store.py +1 -1
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_managed_setup.py +18 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_oci.py +57 -0
- seqevi-0.4.0/tests/test_oci_arg_order.py +45 -0
- seqevi-0.4.0/tests/test_oci_artifact_storage_migration.py +158 -0
- seqevi-0.4.0/tests/test_oci_cancellation.py +424 -0
- seqevi-0.4.0/tests/test_oci_client.py +363 -0
- seqevi-0.4.0/tests/test_oci_native.py +373 -0
- seqevi-0.4.0/tests/test_oci_postgres.py +166 -0
- seqevi-0.4.0/tests/test_oci_registry.py +296 -0
- seqevi-0.4.0/tests/test_oci_service.py +520 -0
- seqevi-0.4.0/tests/test_release_contract.py +193 -0
- seqevi-0.4.0/tests/test_runner_output_limit.py +25 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_shared_store.py +390 -30
- seqevi-0.3.5/src/seqevi/store/artifact.py +0 -225
- {seqevi-0.3.5 → seqevi-0.4.0}/LICENSE +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/__main__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/adapters/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/adapters/base.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/adapters/dbcan_cazyme.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/adapters/eggnog.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/adapters/interpro_pfam.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/adapters/registry.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/distribution/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/distribution/manifest.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/distribution/setup.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/errors.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/execution_profile.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/hashing.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/kits/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/kits/dbcan-cazyme.toml +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/progress.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/resource_lock.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/result.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/runtime_identity.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/sequence.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/service/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/_artifact_reader.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/_resolver.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/contract.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/env.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/versions/0001_initial_store.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/versions/0002_artifact_byte_size_bigint.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/versions/0003_evidence_claim_leases.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/versions/0004_claim_sessions.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/src/seqevi/store/migrations/versions/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/__init__.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/support.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_acceptance_containment.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_acceptance_harnesses.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_annotate.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_claim_leases.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_dbcan_cazyme.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_dbcan_local_candidate_harness.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_eggnog.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_evidence.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_execution_profile.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_incremental_reuse.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_interpro_pfam.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_progress.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_resource_lock.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_result_prototype.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_runner.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_runtime_identity.py +0 -0
- {seqevi-0.3.5 → seqevi-0.4.0}/tests/test_sequence.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seqevi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Content-addressed, reusable protein sequence annotation evidence.
|
|
5
5
|
Author-Email: Fuqing Zhang <fu.qing.zhang.work@gmail.com>, FuqingZhang <103730099+FuqingZh@users.noreply.github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -45,30 +45,53 @@ single-file DuckDB result for the current FASTA.
|
|
|
45
45
|
|
|
46
46
|
## Status
|
|
47
47
|
|
|
48
|
-
The
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
The source tree is a SeqEvi 0.4.0 release candidate. It implements strict
|
|
49
|
+
protein sequence identity, local SQLite/POSIX and shared HTTP/PostgreSQL Stores
|
|
50
|
+
with POSIX or explicit native OCI artifact storage, exact cache-miss
|
|
51
|
+
orchestration, Linux external-tool containment, and immutable single-file
|
|
52
|
+
DuckDB results. Python 3.12 or newer is required; direct adapter execution
|
|
53
|
+
requires Linux. SeqEvi 0.4.0 has not been tagged or published as a Python or
|
|
54
|
+
GitHub release, deployed to production, or used to migrate historical bytes.
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
The 0.4.0 candidate provides managed setup for dbCAN only. The `eggnog` and
|
|
54
57
|
`interpro-pfam` adapters remain supported through explicit runtimes and named
|
|
55
|
-
host profiles; managed setup for them is later feature work.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
58
|
+
host profiles; managed setup for them is later feature work.
|
|
59
|
+
|
|
60
|
+
> **Known incomplete or unavailable work:** the original managed dbCAN public-
|
|
61
|
+
> user Slice D run remains incomplete; managed dispatch has no claim-before-OCI
|
|
62
|
+
> path, so D5 is unavailable; InterPro v2 target-Store refresh remains open;
|
|
63
|
+
> and global cache seeding is incomplete. See the
|
|
64
|
+
> [documentation index](docs/README.md) for the governing records. None of
|
|
65
|
+
> these states is represented as a pass.
|
|
66
|
+
|
|
67
|
+
The `eggnog`, `interpro-pfam`, and `dbcan-cazyme` adapters preserve their native
|
|
68
|
+
schemas and have accepted direct-runtime parity evidence. Shared Store,
|
|
69
|
+
resource-lock, batching, and result-publication details are routed from the
|
|
70
|
+
[current system architecture](docs/architecture/20260825-v1.0-current-system-architecture.md).
|
|
71
|
+
|
|
72
|
+
## Release Channels
|
|
73
|
+
|
|
74
|
+
SeqEvi treats repository CI, nightly packages, version tags, GitHub Releases,
|
|
75
|
+
PyPI publication, and the dbCAN runtime image as distinct states:
|
|
76
|
+
|
|
77
|
+
- pull requests and ordinary pushes run CI but do not publish;
|
|
78
|
+
- an off-minute daily or manually dispatched nightly validates exact `main`
|
|
79
|
+
and retains SHA-named wheel/sdist artifacts for 14 days without publishing;
|
|
80
|
+
- an immutable canonical `vX.Y.Z` tag is a validation candidate only and tag
|
|
81
|
+
push alone never publishes;
|
|
82
|
+
- publishing a stable, non-prerelease GitHub Release for that exact tag starts
|
|
83
|
+
the separately gated PyPI Trusted Publishing path;
|
|
84
|
+
- PyPI publication completes only after the external project/version/files are
|
|
85
|
+
read back successfully; GitHub Release publication necessarily precedes that
|
|
86
|
+
eventual completion; and
|
|
87
|
+
- dbCAN OCI image publication remains an independent, manual dispatch with
|
|
88
|
+
exact source-revision tags and digest readback.
|
|
89
|
+
|
|
90
|
+
Untagged builds use a PEP 440 development version derived from the most recent
|
|
91
|
+
canonical tag, commit distance, and source revision. Installed distribution
|
|
92
|
+
metadata, `seqevi.__version__`, and `seqevi --version` report one identity.
|
|
93
|
+
There is no TestPyPI or release-candidate publishing channel in the current
|
|
94
|
+
contract.
|
|
72
95
|
|
|
73
96
|
## Why SeqEvi
|
|
74
97
|
|
|
@@ -134,8 +157,8 @@ seqevi setup dbcan-cazyme \
|
|
|
134
157
|
`--dry-run` never mutates state. `--yes` pulls the immutable image only when
|
|
135
158
|
needed, verifies the caller-owned four-file resource, creates `seqevi.lock`
|
|
136
159
|
when the resource permits it, runs an ephemeral read-only smoke, and publishes
|
|
137
|
-
the v2 profile atomically. It never downloads or copies the database.
|
|
138
|
-
|
|
160
|
+
the v2 profile atomically. It never downloads or copies the database. A managed
|
|
161
|
+
dbCAN annotation runs through an ephemeral Docker
|
|
139
162
|
container with the same caller UID/GID, read-only FASTA/resource mounts and a
|
|
140
163
|
local-Store `--network none` boundary:
|
|
141
164
|
|
|
@@ -147,6 +170,13 @@ seqevi annotate \
|
|
|
147
170
|
--output results/dbcan.duckdb
|
|
148
171
|
```
|
|
149
172
|
|
|
173
|
+
The bundled managed kit and its selectable digest are unchanged. Separately,
|
|
174
|
+
an immutable SeqEvi 0.3.5 revision image was automatically published at
|
|
175
|
+
`ghcr.io/fuqingzh/seqevi-dbcan@sha256:1914939f1776fee3faac5241fc84f99f4534f37e20cc4d4d48eedf491c38488a`
|
|
176
|
+
from merged revision `f7781c4ce7d642ef46619e6f02c7be3745803ca4`. That
|
|
177
|
+
publication did not register a new managed kit or publish SeqEvi 0.4.0; image
|
|
178
|
+
publication now requires an explicit workflow dispatch.
|
|
179
|
+
|
|
150
180
|
The dispatcher and cleanup boundary are covered by fixture tests. Real
|
|
151
181
|
direct-candidate versus managed-v2 scientific equality and later-process replay
|
|
152
182
|
passed the release gate. A validation harness used an immutable local image ID
|
|
@@ -240,9 +270,11 @@ seqevi resource verify \
|
|
|
240
270
|
- Exact, immutable evidence keys.
|
|
241
271
|
- Explicit `eggnog`, `interpro-pfam`, and official-runtime-validated
|
|
242
272
|
`dbcan-cazyme` adapters. dbCAN direct/local/shared scientific acceptance is
|
|
243
|
-
complete
|
|
244
|
-
|
|
245
|
-
|
|
273
|
+
complete. The bundled managed kit is unchanged; the separately published
|
|
274
|
+
immutable 0.3.5 revision image is not a new selectable kit. Annotation
|
|
275
|
+
databases remain caller supplied.
|
|
276
|
+
- Local SQLite/POSIX Store and shared PostgreSQL Store with legacy POSIX or
|
|
277
|
+
explicitly configured native OCI artifacts.
|
|
246
278
|
- One self-describing DuckDB result per invocation; adapter-native normalized
|
|
247
279
|
evidence remains Parquet inside the incremental Store.
|
|
248
280
|
|
|
@@ -252,31 +284,13 @@ schemas.
|
|
|
252
284
|
|
|
253
285
|
## Documentation
|
|
254
286
|
|
|
255
|
-
Start with
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
- [Storage and deployment architecture](docs/architecture/20260729-v1.1-storage-deployment-architecture.md)
|
|
263
|
-
- [MVP implementation plan](docs/implementation-plan/20260720-v1.0-mvp-implementation-plan.md)
|
|
264
|
-
- [Execution profile implementation plan](docs/implementation-plan/20260724-v1.0-execution-profile-implementation-plan.md)
|
|
265
|
-
- [Validation strategy](docs/testing/20260720-v1.0-validation-strategy.md)
|
|
266
|
-
- [Annotate runtime and bounded-memory plan](docs/implementation-plan/20260722-v1.0-annotate-bounded-memory-plan.md)
|
|
267
|
-
- [Bounded-memory and operational performance](docs/benchmarks/20260722-v1.0-bounded-memory-performance.md)
|
|
268
|
-
- [InterProScan Pfam runtime validation](docs/benchmarks/20260723-v1.0-interproscan-runtime-validation.md)
|
|
269
|
-
- [dbCAN CAZyme adapter implementation plan](docs/implementation-plan/20260804-v1.0-dbcan-cazyme-adapter-implementation-plan.md)
|
|
270
|
-
- [DuckDB result-consumption runtime acceptance](docs/benchmarks/20260805-v1.0-result-consumption-runtime-acceptance.md)
|
|
271
|
-
- [dbCAN runtime image release review](docs/architecture/20260805-v1.1-dbcan-runtime-image-release-review.md)
|
|
272
|
-
|
|
273
|
-
Accepted managed-boundary documents; Slice B setup and smoke plus Slice C OCI
|
|
274
|
-
execution and real candidate acceptance are implemented, while v1 profiles
|
|
275
|
-
remain compatible:
|
|
276
|
-
|
|
277
|
-
- [Managed adapter onboarding roadmap v1.1](docs/implementation-plan/20260805-v1.1-managed-adapter-onboarding-implementation-plan.md)
|
|
278
|
-
- [Managed-distribution architecture v1.2](docs/architecture/20260806-v1.2-managed-adapter-distribution-architecture.md)
|
|
279
|
-
- [Execution profile v2.2 contract](docs/architecture/20260806-v2.2-execution-profile-contract.md)
|
|
287
|
+
Start with the [documentation index](docs/README.md), the
|
|
288
|
+
[current system architecture](docs/architecture/20260825-v1.0-current-system-architecture.md),
|
|
289
|
+
or the [first-annotation guide](docs/how-to-guides/first-annotation.md).
|
|
290
|
+
|
|
291
|
+
The index owns the current contract map, active work, incomplete evidence,
|
|
292
|
+
operations, and historical navigation. Superseded architecture is retained in
|
|
293
|
+
the [documentation archive](docs/archive/README.md), not mixed into onboarding.
|
|
280
294
|
|
|
281
295
|
## Python And Result Discovery
|
|
282
296
|
|
|
@@ -319,18 +333,17 @@ produce the new result file.
|
|
|
319
333
|
|
|
320
334
|
## External Tools
|
|
321
335
|
|
|
322
|
-
Annotation runtimes and databases are supplied by the user.
|
|
323
|
-
|
|
336
|
+
Annotation runtimes and databases are normally supplied by the user. SeqEvi
|
|
337
|
+
targets
|
|
324
338
|
[eggNOG-mapper](https://github.com/eggnogdb/eggnog-mapper) and
|
|
325
339
|
[InterProScan](https://www.ebi.ac.uk/interpro/interproscan.html) with the Pfam
|
|
326
340
|
application, and [dbCAN](https://github.com/bcb-unl/run_dbcan) for protein-level
|
|
327
|
-
CAZyme annotation.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
database path, and internal registry mirrors remain deployment policy.
|
|
341
|
+
CAZyme annotation. Managed `seqevi setup` is implemented only for dbCAN using a
|
|
342
|
+
public, digest-pinned `ghcr.io/fuqingzh/seqevi-dbcan` runtime image built from
|
|
343
|
+
locked upstream inputs. It is SeqEvi-maintained, not an upstream-official dbCAN
|
|
344
|
+
image. Callers still provide the database path; annotation databases are never
|
|
345
|
+
bundled in the wheel or runtime image, and internal registry mirrors remain
|
|
346
|
+
deployment policy.
|
|
334
347
|
|
|
335
348
|
## License
|
|
336
349
|
|
|
@@ -10,30 +10,53 @@ single-file DuckDB result for the current FASTA.
|
|
|
10
10
|
|
|
11
11
|
## Status
|
|
12
12
|
|
|
13
|
-
The
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
SeqEvi 0.
|
|
13
|
+
The source tree is a SeqEvi 0.4.0 release candidate. It implements strict
|
|
14
|
+
protein sequence identity, local SQLite/POSIX and shared HTTP/PostgreSQL Stores
|
|
15
|
+
with POSIX or explicit native OCI artifact storage, exact cache-miss
|
|
16
|
+
orchestration, Linux external-tool containment, and immutable single-file
|
|
17
|
+
DuckDB results. Python 3.12 or newer is required; direct adapter execution
|
|
18
|
+
requires Linux. SeqEvi 0.4.0 has not been tagged or published as a Python or
|
|
19
|
+
GitHub release, deployed to production, or used to migrate historical bytes.
|
|
20
|
+
|
|
21
|
+
The 0.4.0 candidate provides managed setup for dbCAN only. The `eggnog` and
|
|
19
22
|
`interpro-pfam` adapters remain supported through explicit runtimes and named
|
|
20
|
-
host profiles; managed setup for them is later feature work.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
23
|
+
host profiles; managed setup for them is later feature work.
|
|
24
|
+
|
|
25
|
+
> **Known incomplete or unavailable work:** the original managed dbCAN public-
|
|
26
|
+
> user Slice D run remains incomplete; managed dispatch has no claim-before-OCI
|
|
27
|
+
> path, so D5 is unavailable; InterPro v2 target-Store refresh remains open;
|
|
28
|
+
> and global cache seeding is incomplete. See the
|
|
29
|
+
> [documentation index](docs/README.md) for the governing records. None of
|
|
30
|
+
> these states is represented as a pass.
|
|
31
|
+
|
|
32
|
+
The `eggnog`, `interpro-pfam`, and `dbcan-cazyme` adapters preserve their native
|
|
33
|
+
schemas and have accepted direct-runtime parity evidence. Shared Store,
|
|
34
|
+
resource-lock, batching, and result-publication details are routed from the
|
|
35
|
+
[current system architecture](docs/architecture/20260825-v1.0-current-system-architecture.md).
|
|
36
|
+
|
|
37
|
+
## Release Channels
|
|
38
|
+
|
|
39
|
+
SeqEvi treats repository CI, nightly packages, version tags, GitHub Releases,
|
|
40
|
+
PyPI publication, and the dbCAN runtime image as distinct states:
|
|
41
|
+
|
|
42
|
+
- pull requests and ordinary pushes run CI but do not publish;
|
|
43
|
+
- an off-minute daily or manually dispatched nightly validates exact `main`
|
|
44
|
+
and retains SHA-named wheel/sdist artifacts for 14 days without publishing;
|
|
45
|
+
- an immutable canonical `vX.Y.Z` tag is a validation candidate only and tag
|
|
46
|
+
push alone never publishes;
|
|
47
|
+
- publishing a stable, non-prerelease GitHub Release for that exact tag starts
|
|
48
|
+
the separately gated PyPI Trusted Publishing path;
|
|
49
|
+
- PyPI publication completes only after the external project/version/files are
|
|
50
|
+
read back successfully; GitHub Release publication necessarily precedes that
|
|
51
|
+
eventual completion; and
|
|
52
|
+
- dbCAN OCI image publication remains an independent, manual dispatch with
|
|
53
|
+
exact source-revision tags and digest readback.
|
|
54
|
+
|
|
55
|
+
Untagged builds use a PEP 440 development version derived from the most recent
|
|
56
|
+
canonical tag, commit distance, and source revision. Installed distribution
|
|
57
|
+
metadata, `seqevi.__version__`, and `seqevi --version` report one identity.
|
|
58
|
+
There is no TestPyPI or release-candidate publishing channel in the current
|
|
59
|
+
contract.
|
|
37
60
|
|
|
38
61
|
## Why SeqEvi
|
|
39
62
|
|
|
@@ -99,8 +122,8 @@ seqevi setup dbcan-cazyme \
|
|
|
99
122
|
`--dry-run` never mutates state. `--yes` pulls the immutable image only when
|
|
100
123
|
needed, verifies the caller-owned four-file resource, creates `seqevi.lock`
|
|
101
124
|
when the resource permits it, runs an ephemeral read-only smoke, and publishes
|
|
102
|
-
the v2 profile atomically. It never downloads or copies the database.
|
|
103
|
-
|
|
125
|
+
the v2 profile atomically. It never downloads or copies the database. A managed
|
|
126
|
+
dbCAN annotation runs through an ephemeral Docker
|
|
104
127
|
container with the same caller UID/GID, read-only FASTA/resource mounts and a
|
|
105
128
|
local-Store `--network none` boundary:
|
|
106
129
|
|
|
@@ -112,6 +135,13 @@ seqevi annotate \
|
|
|
112
135
|
--output results/dbcan.duckdb
|
|
113
136
|
```
|
|
114
137
|
|
|
138
|
+
The bundled managed kit and its selectable digest are unchanged. Separately,
|
|
139
|
+
an immutable SeqEvi 0.3.5 revision image was automatically published at
|
|
140
|
+
`ghcr.io/fuqingzh/seqevi-dbcan@sha256:1914939f1776fee3faac5241fc84f99f4534f37e20cc4d4d48eedf491c38488a`
|
|
141
|
+
from merged revision `f7781c4ce7d642ef46619e6f02c7be3745803ca4`. That
|
|
142
|
+
publication did not register a new managed kit or publish SeqEvi 0.4.0; image
|
|
143
|
+
publication now requires an explicit workflow dispatch.
|
|
144
|
+
|
|
115
145
|
The dispatcher and cleanup boundary are covered by fixture tests. Real
|
|
116
146
|
direct-candidate versus managed-v2 scientific equality and later-process replay
|
|
117
147
|
passed the release gate. A validation harness used an immutable local image ID
|
|
@@ -205,9 +235,11 @@ seqevi resource verify \
|
|
|
205
235
|
- Exact, immutable evidence keys.
|
|
206
236
|
- Explicit `eggnog`, `interpro-pfam`, and official-runtime-validated
|
|
207
237
|
`dbcan-cazyme` adapters. dbCAN direct/local/shared scientific acceptance is
|
|
208
|
-
complete
|
|
209
|
-
|
|
210
|
-
|
|
238
|
+
complete. The bundled managed kit is unchanged; the separately published
|
|
239
|
+
immutable 0.3.5 revision image is not a new selectable kit. Annotation
|
|
240
|
+
databases remain caller supplied.
|
|
241
|
+
- Local SQLite/POSIX Store and shared PostgreSQL Store with legacy POSIX or
|
|
242
|
+
explicitly configured native OCI artifacts.
|
|
211
243
|
- One self-describing DuckDB result per invocation; adapter-native normalized
|
|
212
244
|
evidence remains Parquet inside the incremental Store.
|
|
213
245
|
|
|
@@ -217,31 +249,13 @@ schemas.
|
|
|
217
249
|
|
|
218
250
|
## Documentation
|
|
219
251
|
|
|
220
|
-
Start with
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
- [Storage and deployment architecture](docs/architecture/20260729-v1.1-storage-deployment-architecture.md)
|
|
228
|
-
- [MVP implementation plan](docs/implementation-plan/20260720-v1.0-mvp-implementation-plan.md)
|
|
229
|
-
- [Execution profile implementation plan](docs/implementation-plan/20260724-v1.0-execution-profile-implementation-plan.md)
|
|
230
|
-
- [Validation strategy](docs/testing/20260720-v1.0-validation-strategy.md)
|
|
231
|
-
- [Annotate runtime and bounded-memory plan](docs/implementation-plan/20260722-v1.0-annotate-bounded-memory-plan.md)
|
|
232
|
-
- [Bounded-memory and operational performance](docs/benchmarks/20260722-v1.0-bounded-memory-performance.md)
|
|
233
|
-
- [InterProScan Pfam runtime validation](docs/benchmarks/20260723-v1.0-interproscan-runtime-validation.md)
|
|
234
|
-
- [dbCAN CAZyme adapter implementation plan](docs/implementation-plan/20260804-v1.0-dbcan-cazyme-adapter-implementation-plan.md)
|
|
235
|
-
- [DuckDB result-consumption runtime acceptance](docs/benchmarks/20260805-v1.0-result-consumption-runtime-acceptance.md)
|
|
236
|
-
- [dbCAN runtime image release review](docs/architecture/20260805-v1.1-dbcan-runtime-image-release-review.md)
|
|
237
|
-
|
|
238
|
-
Accepted managed-boundary documents; Slice B setup and smoke plus Slice C OCI
|
|
239
|
-
execution and real candidate acceptance are implemented, while v1 profiles
|
|
240
|
-
remain compatible:
|
|
241
|
-
|
|
242
|
-
- [Managed adapter onboarding roadmap v1.1](docs/implementation-plan/20260805-v1.1-managed-adapter-onboarding-implementation-plan.md)
|
|
243
|
-
- [Managed-distribution architecture v1.2](docs/architecture/20260806-v1.2-managed-adapter-distribution-architecture.md)
|
|
244
|
-
- [Execution profile v2.2 contract](docs/architecture/20260806-v2.2-execution-profile-contract.md)
|
|
252
|
+
Start with the [documentation index](docs/README.md), the
|
|
253
|
+
[current system architecture](docs/architecture/20260825-v1.0-current-system-architecture.md),
|
|
254
|
+
or the [first-annotation guide](docs/how-to-guides/first-annotation.md).
|
|
255
|
+
|
|
256
|
+
The index owns the current contract map, active work, incomplete evidence,
|
|
257
|
+
operations, and historical navigation. Superseded architecture is retained in
|
|
258
|
+
the [documentation archive](docs/archive/README.md), not mixed into onboarding.
|
|
245
259
|
|
|
246
260
|
## Python And Result Discovery
|
|
247
261
|
|
|
@@ -284,18 +298,17 @@ produce the new result file.
|
|
|
284
298
|
|
|
285
299
|
## External Tools
|
|
286
300
|
|
|
287
|
-
Annotation runtimes and databases are supplied by the user.
|
|
288
|
-
|
|
301
|
+
Annotation runtimes and databases are normally supplied by the user. SeqEvi
|
|
302
|
+
targets
|
|
289
303
|
[eggNOG-mapper](https://github.com/eggnogdb/eggnog-mapper) and
|
|
290
304
|
[InterProScan](https://www.ebi.ac.uk/interpro/interproscan.html) with the Pfam
|
|
291
305
|
application, and [dbCAN](https://github.com/bcb-unl/run_dbcan) for protein-level
|
|
292
|
-
CAZyme annotation.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
database path, and internal registry mirrors remain deployment policy.
|
|
306
|
+
CAZyme annotation. Managed `seqevi setup` is implemented only for dbCAN using a
|
|
307
|
+
public, digest-pinned `ghcr.io/fuqingzh/seqevi-dbcan` runtime image built from
|
|
308
|
+
locked upstream inputs. It is SeqEvi-maintained, not an upstream-official dbCAN
|
|
309
|
+
image. Callers still provide the database path; annotation databases are never
|
|
310
|
+
bundled in the wheel or runtime image, and internal registry mirrors remain
|
|
311
|
+
deployment policy.
|
|
299
312
|
|
|
300
313
|
## License
|
|
301
314
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "seqevi"
|
|
3
|
-
|
|
3
|
+
dynamic = []
|
|
4
4
|
description = "Content-addressed, reusable protein sequence annotation evidence."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Fuqing Zhang", email = "fu.qing.zhang.work@gmail.com" },
|
|
@@ -31,6 +31,7 @@ classifiers = [
|
|
|
31
31
|
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
32
32
|
]
|
|
33
33
|
license = "MIT"
|
|
34
|
+
version = "0.4.0"
|
|
34
35
|
|
|
35
36
|
[project.urls]
|
|
36
37
|
Homepage = "https://github.com/FuqingZh/seqevi"
|
|
@@ -64,11 +65,19 @@ dev = [
|
|
|
64
65
|
"pytest-timeout>=2.4,<3",
|
|
65
66
|
"pytest-xdist>=3.8,<4",
|
|
66
67
|
"ruff>=0.15,<0.16",
|
|
68
|
+
"packaging<27,>=25",
|
|
69
|
+
"twine<7,>=6.2",
|
|
67
70
|
]
|
|
68
71
|
|
|
69
72
|
[tool.pdm]
|
|
70
73
|
distribution = true
|
|
71
74
|
|
|
75
|
+
[tool.pdm.version]
|
|
76
|
+
source = "scm"
|
|
77
|
+
tag_filter = "v[0-9]*.[0-9]*.[0-9]*"
|
|
78
|
+
tag_regex = "^v(?P<version>(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*))$"
|
|
79
|
+
version_format = "scripts.version:format_version"
|
|
80
|
+
|
|
72
81
|
[tool.pdm.scripts]
|
|
73
82
|
format = "ruff format ."
|
|
74
83
|
format-check = "ruff format --check ."
|
|
@@ -123,11 +123,17 @@ class _MeasuringToolRunner(ToolRunner):
|
|
|
123
123
|
*,
|
|
124
124
|
timeout_seconds: float | None = None,
|
|
125
125
|
cancellation_signal: threading.Event | None = None,
|
|
126
|
+
output_limit_bytes: int | None = None,
|
|
126
127
|
) -> ToolRunResult:
|
|
127
128
|
result = self.delegate.run(
|
|
128
129
|
command,
|
|
129
130
|
timeout_seconds=timeout_seconds,
|
|
130
131
|
cancellation_signal=cancellation_signal or self.cancellation_signal,
|
|
132
|
+
**(
|
|
133
|
+
{"output_limit_bytes": output_limit_bytes}
|
|
134
|
+
if output_limit_bytes is not None
|
|
135
|
+
else {}
|
|
136
|
+
),
|
|
131
137
|
)
|
|
132
138
|
self.duration_seconds += result.duration_seconds
|
|
133
139
|
return result
|
|
@@ -35,6 +35,7 @@ from .progress import (
|
|
|
35
35
|
)
|
|
36
36
|
from .result import RESULT_FORMAT_VERSION, scan_annotations as _scan_annotations
|
|
37
37
|
from .store import open_evidence_store
|
|
38
|
+
from .store.oci import OciClientFiles
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
@dataclass(frozen=True, slots=True)
|
|
@@ -78,6 +79,8 @@ def annotate(
|
|
|
78
79
|
store: str | Path | None = None,
|
|
79
80
|
threads: int | None = None,
|
|
80
81
|
timeout_seconds: float | None = None,
|
|
82
|
+
oci_registry_config: str | Path | None = None,
|
|
83
|
+
oci_registry_ca_file: str | Path | None = None,
|
|
81
84
|
) -> duckdb.DuckDBPyRelation:
|
|
82
85
|
"""Annotate a protein FASTA and return its native DuckDB relation.
|
|
83
86
|
|
|
@@ -92,6 +95,9 @@ def annotate(
|
|
|
92
95
|
store: Local Store path or shared Store URL.
|
|
93
96
|
threads: Operational worker-thread override.
|
|
94
97
|
timeout_seconds: Optional external-tool timeout.
|
|
98
|
+
oci_registry_config: Optional Docker/ORAS registry config file for one
|
|
99
|
+
OCI-backed shared Store invocation. It is never persisted in a profile.
|
|
100
|
+
oci_registry_ca_file: Optional PEM trust anchor for that registry.
|
|
95
101
|
|
|
96
102
|
Returns:
|
|
97
103
|
The `main.annotations` DuckDB relation. It keeps the read-only result
|
|
@@ -127,6 +133,8 @@ def annotate(
|
|
|
127
133
|
store=store,
|
|
128
134
|
threads=threads,
|
|
129
135
|
timeout_seconds=timeout_seconds,
|
|
136
|
+
oci_registry_config=oci_registry_config,
|
|
137
|
+
oci_registry_ca_file=oci_registry_ca_file,
|
|
130
138
|
)
|
|
131
139
|
return invocation.relation
|
|
132
140
|
|
|
@@ -170,9 +178,15 @@ def _run_annotation_application(
|
|
|
170
178
|
store: str | Path | None,
|
|
171
179
|
threads: int | None,
|
|
172
180
|
timeout_seconds: float | None,
|
|
181
|
+
oci_registry_config: str | Path | None = None,
|
|
182
|
+
oci_registry_ca_file: str | Path | None = None,
|
|
173
183
|
adapter_factory: Callable[[AdapterConfiguration], AnnotationAdapter] | None = None,
|
|
174
184
|
progress_sink: ProgressSink | None = None,
|
|
175
185
|
) -> AnnotationInvocation:
|
|
186
|
+
oci_files = _resolve_oci_client_files(
|
|
187
|
+
oci_registry_config=oci_registry_config,
|
|
188
|
+
oci_registry_ca_file=oci_registry_ca_file,
|
|
189
|
+
)
|
|
176
190
|
emit_progress(
|
|
177
191
|
progress_sink,
|
|
178
192
|
ProgressEvent(
|
|
@@ -207,6 +221,7 @@ def _run_annotation_application(
|
|
|
207
221
|
store=inputs.store,
|
|
208
222
|
threads=inputs.threads,
|
|
209
223
|
timeout_seconds=inputs.timeout_seconds,
|
|
224
|
+
oci_files=oci_files,
|
|
210
225
|
)
|
|
211
226
|
emit_progress(
|
|
212
227
|
progress_sink,
|
|
@@ -243,7 +258,7 @@ def _run_annotation_application(
|
|
|
243
258
|
)
|
|
244
259
|
)
|
|
245
260
|
metadata = _result_metadata_template(configured_adapter)
|
|
246
|
-
with open_evidence_store(inputs.store) as evidence_store:
|
|
261
|
+
with open_evidence_store(inputs.store, oci_files=oci_files) as evidence_store:
|
|
247
262
|
summary = run_annotation(
|
|
248
263
|
fasta_path=fasta.expanduser().resolve(),
|
|
249
264
|
output_dir=output.expanduser().resolve(),
|
|
@@ -290,6 +305,25 @@ def _run_annotation_application(
|
|
|
290
305
|
return invocation
|
|
291
306
|
|
|
292
307
|
|
|
308
|
+
def _resolve_oci_client_files(
|
|
309
|
+
*,
|
|
310
|
+
oci_registry_config: str | Path | None,
|
|
311
|
+
oci_registry_ca_file: str | Path | None,
|
|
312
|
+
) -> OciClientFiles | None:
|
|
313
|
+
"""Resolve invocation-only OCI client files without reading credentials."""
|
|
314
|
+
|
|
315
|
+
if oci_registry_config is None and oci_registry_ca_file is None:
|
|
316
|
+
return None
|
|
317
|
+
return OciClientFiles(
|
|
318
|
+
registry_config=(
|
|
319
|
+
Path(oci_registry_config) if oci_registry_config is not None else None
|
|
320
|
+
),
|
|
321
|
+
ca_file=Path(oci_registry_ca_file)
|
|
322
|
+
if oci_registry_ca_file is not None
|
|
323
|
+
else None,
|
|
324
|
+
).validated()
|
|
325
|
+
|
|
326
|
+
|
|
293
327
|
def resolve_annotation_inputs(
|
|
294
328
|
*,
|
|
295
329
|
profile: str | None,
|