Writing your own apps#
The app infrastructure is provided by the scinexus package. See the scinexus documentation for full details on define_app, app types, handling NotCompleted, and citations.
Below are cogent3-specific examples showing how to write apps that work with cogent3 data types.
Available cogent3 types#
You can use existing type hints if your function takes or returns cogent3 types.
from cogent3.app.typing import defined_types
defined_types()
| type hint | includes |
|---|---|
| UnionType | UnionType |
| AlignedSeqsType | Alignment |
| UnalignedSeqsType | SequenceCollection |
| SeqsCollectionType | Alignment, SequenceCollection |
| SeqType | ByteSequence, DnaSequence, ProteinSequence, ProteinWithStopSequence, RnaSequence, Sequence |
| PairwiseDistanceType | DistanceMatrix |
| TabularType | DictArray, DistanceMatrix, Table |
| TreeType | PhyloNode |
| BootstrapResultType | bootstrap_result |
| HypothesisResultType | hypothesis_result |
| ModelCollectionResultType | model_collection_result |
| ModelResultType | model_result |
| TabularResultType | tabular_result |
| GenericResultType | generic_result |
| ResultType | bootstrap_result, generic_result, hypothesis_result, model_result, tabular_result |
| SerialisableType | SerialisableType |
| IdentifierType | DataMemberABC, Path, str |
Note
You don’t have to use cogent3 types. You can also use standard Python types.
Defining a cogent3 app from a function#
We write a function that takes a cogent3 alignment and returns the first n positions.
from scinexus.composable import define_app
from cogent3.app.typing import AlignedSeqsType
@define_app
def n_positions(val: AlignedSeqsType, n=2) -> AlignedSeqsType:
return val[:n]
The critical elements are:
The
define_appdecorator is used.Type hints are specified for the function’s first argument and its return type.
Using the custom app
We create an app instance for a specific value of n.
first4 = n_positions(n=4)
first4
n_positions(n=4)
The instance’s repr() indicates the wrapped function and the argument values. You use first4() like all composable apps, e.g.
from cogent3 import make_aligned_seqs
aln = make_aligned_seqs(
dict(a="GCAAGCGTTTAT", b="GCTTTTGTCAAT"), moltype="dna"
)
result = first4(aln)
result
| 0 | |
| a | GCAA |
| b | ..TT |
2 x 4 dna alignment
Defining a cogent3 app from a class#
from scinexus.composable import define_app
from cogent3.app.typing import AlignedSeqsType
@define_app
class n_positions:
def __init__(self, n=2):
self.n = n
def main(self, val: AlignedSeqsType) -> AlignedSeqsType:
return val[:self.n]
The critical elements are:
The
define_appdecorator is used.The class has a
main()method.Type hints are specified for the
main()method’s first argument and its return type.
Using the custom app
This is identical to what we did above.
first4 = n_positions(n=4)
# we use the alignment defined above
result = first4(aln)
result
| 0 | |
| a | GCAA |
| b | ..TT |
2 x 4 dna alignment
App naming conventions#
Use words in lower case separated by underscores (e.g. lower_case) to name your apps. Apps are callable, just like functions, and the PEP8 guidelines specify this naming style.
If you will make your app available on the Python package index, we recommend prefixing each app with your package name. For example, the piqtree2 library distributes apps with names such as piqtree_phylo.
See scinexus documentation for how to add a citation to your app.
How to get the citations for the apps you use#
Correctly attributing the authors of algorithms and software is a requirement of good scientific practice. The .citations property on an app instance returns its citations as a tuple.
app = some_app()
app.citations
(Software(
author=['Doe, J', 'Smith, A'],
title='My Sequence Filter',
year=2025,
version='0.1.0',
url='https://example.com/my-filter',
),)
You can get the BibTeX string directly via the .bib property.
print(app.bib)
@software{Doe.2025,
author = {Doe, J and Smith, A},
title = {My Sequence Filter},
year = {2025},
version = {0.1.0},
url = {https://example.com/my-filter},
}
Citations in a composed pipeline
When apps are composed into a pipeline, .citations collects unique citations from all apps in the chain.
from cogent3 import get_app
loader = get_app("load_aligned", moltype="dna", format_name="fasta")
pipeline = loader + some_app()
pipeline.citations
(Software(
author=['Doe, J', 'Smith, A'],
title='My Sequence Filter',
year=2025,
version='0.1.0',
url='https://example.com/my-filter',
),
Software(
key='cogent3',
author=['Huttley, Gavin', 'Caley, Katherine', 'Fotovat, Nabi', 'Ma, Stephen Ka-Wah', 'Koh, Moses', 'Morris, Richard', 'McArthur, Robert', 'McDonald, Daniel', 'Jaya, Fred', 'Maxwell, Peter', 'Martini, James', 'La, Thomas', 'Lang, Yapeng'],
title='{cogent3}: making sense of sequence',
year=2025,
doi='10.5281/zenodo.16519079',
url='https://cogent3.org',
))
The .bib property gives the combined BibTeX for the whole pipeline.
print(pipeline.bib)
@software{Doe.2025,
author = {Doe, J and Smith, A},
title = {My Sequence Filter},
year = {2025},
version = {0.1.0},
url = {https://example.com/my-filter},
}
@software{cogent3,
author = {Huttley, Gavin and Caley, Katherine and Fotovat, Nabi and Ma, Stephen Ka-Wah and Koh, Moses and Morris, Richard and McArthur, Robert and McDonald, Daniel and Jaya, Fred and Maxwell, Peter and Martini, James and La, Thomas and Lang, Yapeng},
title = {{cogent3}: making sense of sequence},
year = {2025},
doi = {10.5281/zenodo.16519079},
url = {https://cogent3.org},
}
Note
When a composed pipeline is run via apply_to(), citations are
automatically saved in the output data store. See data store citations
for how to inspect and export them.