Third Party App Style Guide
This document provides guidelines for app and applet development. While we outline best practices in this guide, we recommend using the following industry-standard style guides, to ensure that code is clean and maintainable:
Bash - Google Shellchecker Shell-format
As always with any style guide if you have a reason or a different convention is followed in the code you are extending then it's okay, even recommended, to deviate from the style guide.
dxapp.json
The dxapp.json
JSON file establishes the convention that users of the DNAnexus platform use to create app(let)s on the platform. When defining applications for wide use, this style guide sets standards for user-friendly UI, CLI, and runtime app(let) definitions.
Name
Applet names should be all lowercase with words separated by underscores.
Summary
An app summary must be concise. It should fit on one line and not terminate in a period. The current app(let) is the assumed subject of the summary.
Good
Bad
The subject "This app" is unnecessary. The sentence is too verbose in its explanation; it should rely on the subject being assumed.
App Execution Environment
Make sure the app runs in Python3 App Execution Environment by setting runSpec
accordingly. For example, to run an app in Ubuntu 20.04 Python3 environment specify:
and a Bash app in Ubuntu 20.04 Python3 environment:
Licenses
Include licenses of the dependency software and packages installed in the upstreamProjects
property of the dxapp.json
. If there are additional hidden layers of dependencies from the ones you explicitly installed, it is the package author's responsibility to list the appropriate licenses.
The following keys are required to ensure compliance with open-source licenses: name
, repoUrl
, version
, license
, and licenseUrl
, while author
is optional but good to have.
Take note of the following:
license
: Follow spdx standards for license abbrivation.licenseUrl
When the software is maintained on GitHub:
Find the
LICENSE
orCOPYING
file link from the software version's tag/commitUse "permalink" for the static hyperlink pointing to the particular version applied. Press "y" at the browser for permanent link: getting-permanent-links-to-files
When the software is not maintained on GitHub:
Find the license document from the software's website and provide URL pointing to the license document.
author
First use authors from the relevant paper for the tool
Second use AUTHORS.md file (usually an org name or person's name) if present at the software's repository
Third if no options, then provide no author
Citations
Cite the publications that are associated with the software being used. Use a DOI name to refer to the paper.
Categories (Apps)
Categories are great for filtering applets from the CLI using dx find
. While an app can have many categories, a subset will show up in the web UI. You can assign any category to an app(let) but remember, Categories searchable in the UI are defined by DNAnexus. If you want to add/remove a category from the web UI, contact support@dnanexus.com.
Help
Optional arguments should start with "(Optional)".
Specifying Inputs and Outputs (I/O Spec)
Treat the I/O spec of an app(let) like the docstring of a well-documented function; it should be descriptive and provide good understanding without looking under the hood.
Input Variable Ordering
For inputs use the group
field to dictate how options will be shown. Groups will be shown in order of first appearance in the input specification with the unnamed group always appearing first. Strive to sensibly group inputs.
Output Files
When possible, output index files (for example BAMs + BAIs and VCFs + TBIs) along with the primary file.
When outputting a reference index file from an app(let) script retain the reference name in the generated index. For example:
referencename.fa.gz
-> indexed by HISAT2 index -> referencename.hisat2-index.tar.gz
output filename
Suggestions
For file type inputs you can recommend projects containing inputs or specific input files for users. For reference genomes and indexes suggest the "DNAnexus Reference Genomes" project.
Name Specification
App(let) I/O name
fields should follow the pattern:
noun[index]_[adjective]_filetype
For BAM files:
For FASTQ files:
For VCF files:
For reference files:
Scripts
General Guidelines
Local Variable Naming
Efforts should be made to download files as their filename on the platform, not as a constant. Any errors that occur due to the input will contain filenames familiar to users. For example:
Good (src/code.sh
):
Bad (src/code.sh
):
Good (src/code.py
):
Bad (src/code.py
):
Bash Specifics
Variables used in bash should always be enclosed in brackets and quotes to prevent globbing or word splitting unless intended. This is especially important when constructing file names and other values:
Good (src/code.sh
):
Bad (src/code.sh
):
References
References should have filenames which are descriptive of what is in them. This includes references which have been indexed for specific uses. We have multiple ways of how references are handled.
Script Section Commenting
Functions
Function/Method Naming
descriptive_lowercase_function_name_separated_by_underscores()
Functions, like variables, should be all lowercase, with name parts separated by underscores. Names should describe the task being performed in the function body.
Good (src/code.sh
):
Good (src/code.py
):
Descriptions (Doc Strings)
Function Descriptions
In general, try to keep functions simple and easy to understand. Comments should be used for: long functions, complex algorithms, or a series of difficult to read shell commands. Descriptions should be included as a block comment in bash or a docstring in Python (for Python follow PEP 257). When needed, include an overview of function Arguments, Returns, and Exceptions (Raises) in the docstring/comment.
Good (src/code.sh
):
Good (src/code.py
):
Supplementary Information
Building Commands
In App(let)s commands that are executed (via subprocess in Python) are constructed in different ways based on user input. Incorrect command construction can lead to unexpected failures and results due to word splitting and globbing. In Python use string.format() to build commands and remember to escape special characters and in Bash use arrays to construct commands.
Good (src/code.sh
):
Use arrays and correct quoting to build commands
Good (src/code.py
):
Last updated