Skip to content

Commit

Permalink
feat(lapis): omit sequences with null values in unaligned fasta dow…
Browse files Browse the repository at this point in the history
…nloads

closes #912
  • Loading branch information
fengelniederhammer authored and JonasKellerer committed Aug 26, 2024
1 parent d50014a commit f1931a6
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const val ALIGNED_MULTI_SEGMENTED_NUCLEOTIDE_SEQUENCE_ENDPOINT_DESCRIPTION =
Only sequences matching the specified sequence filters are considered."""
const val UNALIGNED_MULTI_SEGMENTED_NUCLEOTIDE_SEQUENCE_ENDPOINT_DESCRIPTION =
"""Returns a string of fasta formatted unaligned nucleotide sequences of the requested segment.
Only sequences matching the specified sequence filters are considered."""
Only sequences matching the specified sequence filters are considered.
Sequences that don't have an unaligned sequence for this segment are omitted."""

const val AGGREGATED_GROUP_BY_FIELDS_DESCRIPTION =
"""The fields to stratify by. If empty, only the overall count is returned"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.node.JsonNodeType
import com.fasterxml.jackson.databind.node.NullNode
import io.swagger.v3.oas.annotations.media.Schema
import jakarta.servlet.http.HttpServletResponse
Expand Down Expand Up @@ -103,7 +104,7 @@ data class InsertionData(

data class SequenceData(
val sequenceKey: String,
val sequence: String,
val sequence: String?,
) {
fun writeAsString() = ">$sequenceKey\n$sequence"
}
Expand All @@ -116,10 +117,9 @@ fun Stream<SequenceData>.writeFastaTo(
if (response.contentType == null) {
response.contentType = MediaType(TEXT_X_FASTA, Charset.defaultCharset()).toString()
}
response.outputStream.writer().use {
for (sequenceData in this) {
it.appendLine(sequenceData.writeAsString())
}
response.outputStream.writer().use { stream ->
this.filter { it.sequence != null }
.forEach { stream.appendLine(it.writeAsString()) }
}
}

Expand All @@ -135,8 +135,19 @@ class SequenceDataDeserializer(val databaseConfig: DatabaseConfig) : JsonDeseria
): SequenceData {
val node = p.readValueAsTree<JsonNode>()
val sequenceKey = node.get(databaseConfig.schema.primaryKey).asText()
val sequence =
node.fields().asSequence().first { it.key != databaseConfig.schema.primaryKey }.value.asText()
return SequenceData(sequenceKey, sequence)

val value = node.fields().asSequence().first { it.key != databaseConfig.schema.primaryKey }.value
val sequence = when (value.nodeType) {
JsonNodeType.NULL -> null
JsonNodeType.STRING -> value.asText()
else -> throw RuntimeException(
"Error deserializing sequence data: got unexpected value $value of type ${value.nodeType}",
)
}

return SequenceData(
sequenceKey = sequenceKey,
sequence = sequence,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,11 @@ class LapisControllerTest(
SequenceType.ALIGNED,
"geneName",
)
} returns Stream.of(SequenceData("key1", "the sequence"), SequenceData("key2", "the other sequence"))
} returns Stream.of(
SequenceData("key1", "the sequence"),
SequenceData("key2", "the other sequence"),
SequenceData("key3", null),
)

mockMvc.perform(request("$ALIGNED_AMINO_ACID_SEQUENCES_ROUTE/geneName"))
.andExpect(status().isOk)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import java.util.stream.Stream
class MultiSegmentedSequenceControllerTest(
@Autowired val mockMvc: MockMvc,
) {
val returnedValue: Stream<SequenceData> = Stream.of(SequenceData("sequenceKey", "theSequence"))
val returnedValue: Stream<SequenceData> = Stream.of(
SequenceData("sequenceKey", "theSequence"),
SequenceData("sequenceKeyWithNullValue", null),
)

val expectedFasta = """
>sequenceKey
theSequence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ import java.util.stream.Stream
class SingleSegmentedSequenceControllerTest(
@Autowired val mockMvc: MockMvc,
) {
val returnedValue: Stream<SequenceData> = Stream.of(SequenceData("sequenceKey", "theSequence"))
val returnedValue: Stream<SequenceData> = Stream.of(
SequenceData("sequenceKey", "theSequence"),
SequenceData("sequenceKeyWithNullValue", null),
)

val expectedFasta = """
>sequenceKey
theSequence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class SiloClientTest(
"""
{"primaryKey": "key1","someSequenceName": "ABCD"}
{"primaryKey": "key2","someSequenceName": "DEFG"}
{"primaryKey": "key3","someSequenceName": null}
""",
),
)
Expand All @@ -159,12 +160,13 @@ class SiloClientTest(
)
val result = underTest.sendQuery(query).toList()

assertThat(result, hasSize(2))
assertThat(result, hasSize(3))
assertThat(
result,
containsInAnyOrder(
SequenceData("key1", "ABCD"),
SequenceData("key2", "DEFG"),
SequenceData(sequenceKey = "key1", sequence = "ABCD"),
SequenceData(sequenceKey = "key2", sequence = "DEFG"),
SequenceData(sequenceKey = "key3", sequence = null),
),
)
}
Expand Down

0 comments on commit f1931a6

Please sign in to comment.