fix(lapis): restore insertion and mutation format in response - #1798
fix(lapis): restore insertion and mutation format in response#1798fengelniederhammer wants to merge 8 commits into
insertion and mutation format in response#1798Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
insertion and mutation format in response
There was a problem hiding this comment.
Pull request overview
This PR restores the public LAPIS API contract for mutation and insertion fields after SILO stopped returning those assembled strings, by assembling them within LAPIS from the remaining SILO-provided components.
Changes:
- Assemble
mutationvalues inSiloQueryModelfrommutationFrom/position/mutationTo(andsequenceNamewhere applicable) while keeping field-selection behavior intact. - Assemble
insertionvalues inSiloQueryModelfromsequenceName/position/insertedSymbols, restoring the legacy formatting for single- vs multi-segmented genomes. - Update Arrow row converters and tests to reflect SILO’s updated payloads (no longer containing pre-assembled
mutation/insertion), and switch CI to useSILO_TAG: latestagain.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloQueryModel.kt | Reassembles mutation/insertion strings in LAPIS responses; adjusts requested SILO fields accordingly. |
| lapis/src/main/kotlin/org/genspectrum/lapis/request/MutationProportionsRequest.kt | Adds helpers for field-selection logic used when deciding what to return. |
| lapis/src/main/kotlin/org/genspectrum/lapis/response/SiloResponse.kt | Updates internal data models to match SILO output (drops assembled fields). |
| lapis/src/main/kotlin/org/genspectrum/lapis/silo/ArrowRowConverter.kt | Stops reading removed SILO columns (mutation, insertion) from Arrow rows. |
| lapis/src/main/kotlin/org/genspectrum/lapis/response/LapisResponse.kt | Fixes capitalization in a JavaScript wording comment. |
| lapis/src/test/kotlin/org/genspectrum/lapis/controller/Helpers.kt | Updates mutation test helper to provide mutationFrom/mutationTo instead of mutation. |
| lapis/src/test/kotlin/org/genspectrum/lapis/model/SiloQueryModelTest.kt | Updates/extends tests to validate assembled mutation/insertion response formatting. |
| lapis/src/test/kotlin/org/genspectrum/lapis/silo/SiloClientTest.kt | Updates SILO client Arrow test fixtures to remove now-missing SILO columns. |
| .github/workflows/lapis.yml | Switches SILO docker tag back to latest in CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
.github/workflows/lapis.yml:8
- Using a floating Docker tag (
SILO_TAG: latest) in CI makes test runs non-reproducible and can cause sudden breakages when SILO publishes a new image. Consider pinning to a specific SILO version (or image digest) that this PR is verified against, and bump it intentionally when needed.
env:
DOCKER_IMAGE_NAME: ghcr.io/genspectrum/lapis
SILO_TAG: latest
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 35 changed files in this pull request and generated no new comments.
Suppressed comments (4)
lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloQueryModel.kt:86
assembleMutationbuilds the assembled amino-acid mutation string from nullable fields (sequenceName,mutationFrom,position,mutationTo). If any of those columns are missing in the SILO response, the assembledmutationwill contain "null" segments. It’s safer to require these fields when assembling the string (or otherwise explicitly handle missing values).
val assembleMutation = { data: MutationData ->
"${data.sequenceName}:${data.mutationFrom}${data.position}${data.mutationTo}"
}
lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloQueryModel.kt:61
assembleMutationconcatenates nullable fields (mutationFrom,position,mutationTo, and (for multi-segmented)sequenceName). If SILO omits any of these columns (e.g., due to afieldsprojection), Kotlin string interpolation will produce strings containing "null" (likenull123null), silently breaking the API contract. Consider failing fast when any required component is missing so incorrect assembled mutations can’t leak into responses.
This issue also appears on line 84 of the same file.
val assembleMutation = { data: MutationData ->
val core = "${data.mutationFrom}${data.position}${data.mutationTo}"
if (referenceGenomeSchema.isSingleSegmented()) core else "${data.sequenceName}:$core"
}
lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloQueryModel.kt:31
import kotlin.collections.emptyListis redundant (the function is in Kotlin’s default imports) and will typically be flagged by ktlint/IDE inspections as an unused/redundant import. Removing it avoids unnecessary lint noise.
import kotlin.collections.emptyList
lapis/src/main/kotlin/org/genspectrum/lapis/request/MutationProportionsRequest.kt:32
ifRequested’s KDoc implies conditional evaluation (“Returns value only if field was requested”), but thevalueargument is evaluated eagerly at the call site. That means potentially expensive/unsafe computations (e.g., assemblingmutation) still happen even when the field is not requested. Consider switching this to a lambda form (e.g.,ifRequested(field) { ... }) and updating call sites accordingly.
fun shouldResponseContainField(field: MutationsField) = fields.isEmpty() || fields.contains(field)
/** Returns [value] only if [field] was requested (or all fields were requested), otherwise `null`. */
fun <T> ifRequested(
field: MutationsField,
value: T,
): T? = if (shouldResponseContainField(field)) value else null
resolves #1797
Summary
SILO dropped the assembled
insertionandmutationfields from its responses. This restores them by assembling them in LAPIS, keeping the API contract unchanged.PR Checklist
- [ ] All necessary documentation has been adapted.- [ ] All necessary changes are explained in thellms.txt.