mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-07 15:18:12 +08:00
Improve CLI help (#1025)
* launch option changes * more CLI help improvements * change plot help * additional changes requested * change metavars for options and subcommand
This commit is contained in:
+11
-2
@@ -4,8 +4,17 @@ from .launch import launch
|
|||||||
from .prepare import prepare
|
from .prepare import prepare
|
||||||
|
|
||||||
|
|
||||||
@click.group(name="cellxgene", context_settings=dict(max_content_width=85))
|
@click.group(name="cellxgene",
|
||||||
@click.version_option(version="0.12.0", prog_name="cellxgene", message="[%(prog)s] Version %(version)s")
|
subcommand_metavar="COMMAND <args>",
|
||||||
|
options_metavar="<options>",
|
||||||
|
context_settings=dict(max_content_width=85,
|
||||||
|
help_option_names=['-h', '--help']))
|
||||||
|
@click.help_option("--help", "-h", help="Show this message and exit.")
|
||||||
|
@click.version_option(
|
||||||
|
version="0.12.0",
|
||||||
|
prog_name="cellxgene",
|
||||||
|
message="[%(prog)s] Version %(version)s",
|
||||||
|
help="Show the software version and exit.")
|
||||||
def cli():
|
def cli():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
+70
-34
@@ -13,7 +13,7 @@ import click
|
|||||||
from server.app.app import Server
|
from server.app.app import Server
|
||||||
from server.app.util.errors import ScanpyFileError
|
from server.app.util.errors import ScanpyFileError
|
||||||
from server.app.util.utils import custom_format_warning
|
from server.app.util.utils import custom_format_warning
|
||||||
from server.utils.utils import find_available_port, is_port_available
|
from server.utils.utils import find_available_port, is_port_available, sort_options
|
||||||
from server.app.util.data_locator import DataLocator
|
from server.app.util.data_locator import DataLocator
|
||||||
|
|
||||||
# anything bigger than this will generate a special message
|
# anything bigger than this will generate a special message
|
||||||
@@ -25,55 +25,70 @@ def common_args(func):
|
|||||||
Decorator to contain CLI args that will be common to both CLI and GUI: title and engine args.
|
Decorator to contain CLI args that will be common to both CLI and GUI: title and engine args.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@click.option("--title", "-t", help="Title to display (if omitted will use file name).")
|
@click.option(
|
||||||
@click.option("--about",
|
"--title",
|
||||||
help="A URL to more information about the dataset."
|
"-t",
|
||||||
"(This must be an absolute URL including HTTP(S) protocol)")
|
metavar="<text>",
|
||||||
|
help="Title to display. If omitted will use file name.")
|
||||||
|
@click.option(
|
||||||
|
"--about",
|
||||||
|
metavar="<URL>",
|
||||||
|
help="URL providing more information about the dataset "
|
||||||
|
"(hint: must be a fully specified absolute URL).")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--embedding",
|
"--embedding",
|
||||||
"-e",
|
"-e",
|
||||||
default=[],
|
default=[],
|
||||||
multiple=True,
|
multiple=True,
|
||||||
show_default=False,
|
show_default=False,
|
||||||
|
metavar="<text>",
|
||||||
help="Embedding name, eg, 'umap'. Repeat option for multiple embeddings. Defaults to all."
|
help="Embedding name, eg, 'umap'. Repeat option for multiple embeddings. Defaults to all."
|
||||||
)
|
)
|
||||||
@click.option("--obs-names", default=None, metavar="", help="Name of annotation field to use for observations.")
|
@click.option(
|
||||||
@click.option("--var-names", default=None, metavar="", help="Name of annotation to use for variables.")
|
"--obs-names",
|
||||||
|
"-obs",
|
||||||
|
default=None,
|
||||||
|
metavar="<text>",
|
||||||
|
help="Name of annotation field to use for observations. If not specified cellxgene will use the the obs index.")
|
||||||
|
@click.option(
|
||||||
|
"--var-names",
|
||||||
|
"-var",
|
||||||
|
default=None,
|
||||||
|
metavar="<text>",
|
||||||
|
help="Name of annotation to use for variables. If not specified cellxgene will use the the var index.")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--max-category-items",
|
"--max-category-items",
|
||||||
default=1000,
|
default=1000,
|
||||||
metavar="",
|
metavar="<integer>",
|
||||||
show_default=True,
|
show_default=True,
|
||||||
help="Categories with more distinct values than this will not be displayed.",
|
help="Will not display categories with more distinct values than specified.",)
|
||||||
)
|
|
||||||
@click.option(
|
@click.option(
|
||||||
"--diffexp-lfc-cutoff",
|
"--diffexp-lfc-cutoff",
|
||||||
|
"-de",
|
||||||
default=0.01,
|
default=0.01,
|
||||||
show_default=True,
|
show_default=True,
|
||||||
help="Relative expression cutoff used when selecting top N differentially expressed genes",
|
metavar="<float>",
|
||||||
)
|
help="Minimum log fold change threshold for differential expression.",)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--experimental-label-file",
|
"--experimental-label-file",
|
||||||
default=None,
|
default=None,
|
||||||
show_default=True,
|
show_default=True,
|
||||||
multiple=False,
|
multiple=False,
|
||||||
metavar="<user labels CSV file>",
|
metavar="<path>",
|
||||||
help="CSV file containing user annotations; will be overwritten. Created if does not exist.",
|
help="CSV file containing user annotations; will be overwritten. Created if does not exist.",)
|
||||||
)
|
|
||||||
@click.option(
|
@click.option(
|
||||||
"--backed",
|
"--backed",
|
||||||
|
"-b",
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
default=False,
|
default=False,
|
||||||
show_default=False,
|
show_default=False,
|
||||||
help="Load data in file-backed mode, which may save memory, but result in slower overall performance."
|
help="Load data in file-backed mode. This may save memory, but may result in slower overall performance.")
|
||||||
)
|
|
||||||
@click.option(
|
@click.option(
|
||||||
"--disable-diffexp",
|
"--disable-diffexp",
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
default=False,
|
default=False,
|
||||||
show_default=False,
|
show_default=False,
|
||||||
help="Disable on-demand differential expression."
|
help="Disable on-demand differential expression.")
|
||||||
)
|
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
@@ -96,17 +111,26 @@ def parse_engine_args(embedding, obs_names, var_names, max_category_items,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@sort_options
|
||||||
@click.argument("data", nargs=1, metavar="<data file>", required=True)
|
@click.command(short_help="Launch the cellxgene data viewer. "
|
||||||
|
"Run `cellxgene launch --help` for more information.",
|
||||||
|
options_metavar="<options>",)
|
||||||
|
@click.argument("data", nargs=1, metavar="<path to data file>", required=True)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--verbose",
|
"--verbose",
|
||||||
"-v",
|
"-v",
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
default=False,
|
default=False,
|
||||||
show_default=True,
|
show_default=True,
|
||||||
help="Provide verbose output, including warnings and all server requests.",
|
help="Provide verbose output, including warnings and all server requests.",)
|
||||||
)
|
@click.option(
|
||||||
@click.option("--debug", is_flag=True, default=False, show_default=True, help="Run in debug mode.")
|
"--debug",
|
||||||
|
"-d",
|
||||||
|
is_flag=True,
|
||||||
|
default=False,
|
||||||
|
show_default=True,
|
||||||
|
help="Run in debug mode. This is helpful for cellxgene developers, "
|
||||||
|
"or when you want more information about an error condition.",)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--open",
|
"--open",
|
||||||
"-o",
|
"-o",
|
||||||
@@ -114,18 +138,29 @@ def parse_engine_args(embedding, obs_names, var_names, max_category_items,
|
|||||||
is_flag=True,
|
is_flag=True,
|
||||||
default=False,
|
default=False,
|
||||||
show_default=True,
|
show_default=True,
|
||||||
help="Open the web browser after launch.",
|
help="Open web browser after launch.",)
|
||||||
)
|
@click.option(
|
||||||
@click.option("--port", "-p", help="Port to run server on, if not specified cellxgene will find an available port.",
|
"--port",
|
||||||
metavar="", show_default=True)
|
"-p",
|
||||||
@click.option("--host", default="127.0.0.1", help="Host IP address")
|
metavar="<port>",
|
||||||
|
show_default=True,
|
||||||
|
help="Port to run server on. If not specified cellxgene will find an available port.",)
|
||||||
|
@click.option(
|
||||||
|
"--host",
|
||||||
|
metavar="<IP address>",
|
||||||
|
default="127.0.0.1",
|
||||||
|
show_default=False,
|
||||||
|
help="Host IP address. By default cellxgene will use localhost (e.g. 127.0.0.1).")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--scripts",
|
"--scripts",
|
||||||
|
"-s",
|
||||||
default=[],
|
default=[],
|
||||||
multiple=True,
|
multiple=True,
|
||||||
help="Additional script files to include in html page",
|
metavar="<text>",
|
||||||
show_default=True,
|
help="Additional script files to include in HTML page. If not specified, "
|
||||||
)
|
"no additional script files will be included.",
|
||||||
|
show_default=False,)
|
||||||
|
@click.help_option("--help", "-h", help="Show this message and exit.")
|
||||||
@common_args
|
@common_args
|
||||||
def launch(
|
def launch(
|
||||||
data,
|
data,
|
||||||
@@ -148,8 +183,9 @@ def launch(
|
|||||||
):
|
):
|
||||||
"""Launch the cellxgene data viewer.
|
"""Launch the cellxgene data viewer.
|
||||||
This web app lets you explore single-cell expression data.
|
This web app lets you explore single-cell expression data.
|
||||||
Data must be in a format that cellxgene expects, read the
|
Data must be in a format that cellxgene expects.
|
||||||
"getting started" guide.
|
Read the "getting started" guide to learn more:
|
||||||
|
https://chanzuckerberg.github.io/cellxgene/getting-started.html
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
|||||||
+33
-20
@@ -4,16 +4,21 @@ import click
|
|||||||
from numpy import ndarray, unique
|
from numpy import ndarray, unique
|
||||||
from scipy.sparse.csc import csc_matrix
|
from scipy.sparse.csc import csc_matrix
|
||||||
|
|
||||||
|
from server.utils.utils import sort_options
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.argument("data", nargs=1, metavar="<dataset: file or path to data>", required=True)
|
@sort_options
|
||||||
|
@click.command(short_help="Preprocess data for use with cellxgene. "
|
||||||
|
"Run `cellxgene prepare --help` for more information.",
|
||||||
|
options_metavar="<options>",)
|
||||||
|
@click.argument("data", nargs=1, metavar="<path to data file>", required=True)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--embedding",
|
"--embedding",
|
||||||
"-e",
|
"-e",
|
||||||
default=["umap", "tsne"],
|
default=["umap", "tsne"],
|
||||||
multiple=True,
|
multiple=True,
|
||||||
type=click.Choice(["umap", "tsne"]),
|
type=click.Choice(["umap", "tsne"]),
|
||||||
help="Embedding algorithm",
|
help="Embedding algorithm(s). Repeat option for multiple embeddings.",
|
||||||
show_default=True,
|
show_default=True,
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
@@ -25,21 +30,29 @@ from scipy.sparse.csc import csc_matrix
|
|||||||
show_default=True,
|
show_default=True,
|
||||||
)
|
)
|
||||||
@click.option("--output", "-o", default="", help="Save a new file to filename.", metavar="<filename>")
|
@click.option("--output", "-o", default="", help="Save a new file to filename.", metavar="<filename>")
|
||||||
@click.option("--plotting", "-p", default=False, is_flag=True, help="Whether to generate plots.", show_default=True)
|
@click.option("--plotting", "-p", default=False, is_flag=True, help="Generate plots.", show_default=True)
|
||||||
@click.option("--sparse", default=False, is_flag=True, help="Whether to force sparsity.", show_default=True)
|
@click.option("--sparse", default=False, is_flag=True, help="Force sparsity.", show_default=True)
|
||||||
@click.option("--overwrite", default=False, is_flag=True, help="Allow file overwriting.", show_default=True)
|
@click.option("--overwrite", default=False, is_flag=True, help="Allow file overwriting.", show_default=True)
|
||||||
@click.option("--set-obs-names", default="", help="Named field to set as index for obs.", metavar="<name>")
|
@click.option("--set-obs-names", default="", help="Named field to set as index for obs.", metavar="<name>")
|
||||||
@click.option("--set-var-names", default="", help="Named field to set as index for var.", metavar="<name>")
|
@click.option("--set-var-names", default="", help="Named field to set as index for var.", metavar="<name>")
|
||||||
|
@click.option("--skip-qc", default=False, is_flag=True,
|
||||||
|
help="Do not run quality control metrics. By default cellxgene runs them "
|
||||||
|
"(saved to adata.obs and adata.var; see scanpy.pp.calculate_qc_metrics for details).")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--run-qc/--skip-qc", default=True, is_flag=True,
|
"--make-obs-names-unique",
|
||||||
help="Whether to calculate QC metrics (saved to adata.obs and adata.var). \
|
default=True,
|
||||||
See scanpy.pp.calculate_qc_metrics for details.", show_default=True)
|
is_flag=True,
|
||||||
@click.option(
|
help="Ensure obs index is unique.",
|
||||||
"--make-obs-names-unique", default=True, is_flag=True, help="Ensure obs index is unique.", show_default=True
|
show_default=True
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--make-var-names-unique", default=True, is_flag=True, help="Ensure var index is unique.", show_default=True
|
"--make-var-names-unique",
|
||||||
|
default=True,
|
||||||
|
is_flag=True,
|
||||||
|
help="Ensure var index is unique.",
|
||||||
|
show_default=True
|
||||||
)
|
)
|
||||||
|
@click.help_option("--help", "-h", help="Show this message and exit.")
|
||||||
def prepare(
|
def prepare(
|
||||||
data,
|
data,
|
||||||
embedding,
|
embedding,
|
||||||
@@ -50,18 +63,18 @@ def prepare(
|
|||||||
overwrite,
|
overwrite,
|
||||||
set_obs_names,
|
set_obs_names,
|
||||||
set_var_names,
|
set_var_names,
|
||||||
run_qc,
|
skip_qc,
|
||||||
make_obs_names_unique,
|
make_obs_names_unique,
|
||||||
make_var_names_unique,
|
make_var_names_unique,
|
||||||
):
|
):
|
||||||
"""Preprocesses data for use with cellxgene.
|
"""
|
||||||
|
Preprocess data for use with cellxgene.
|
||||||
This tool runs a series of scanpy routines for preparing a dataset
|
This tool runs a series of scanpy routines for preparing a dataset for use
|
||||||
for use with cellxgene. It loads data from different formats
|
with cellxgene. It loads data from different formats
|
||||||
(h5ad, loom, or a 10x directory), runs dimensionality reduction,
|
(h5ad, loom, or a 10x directory), runs dimensionality reduction,
|
||||||
computes nearest neighbors, computes an embedding, performs clustering,
|
computes nearest neighbors, computes an embedding, performs clustering,
|
||||||
and saves the results. Includes additional options for naming
|
and saves the results. Includes additional options for naming annotations,
|
||||||
annotations, ensuring sparsity, and plotting results."""
|
ensuring sparsity, and plotting results."""
|
||||||
|
|
||||||
# collect slow imports here to make CLI startup more responsive
|
# collect slow imports here to make CLI startup more responsive
|
||||||
click.echo("[cellxgene] Starting CLI...")
|
click.echo("[cellxgene] Starting CLI...")
|
||||||
@@ -129,7 +142,7 @@ def prepare(
|
|||||||
return adata
|
return adata
|
||||||
|
|
||||||
def calculate_qc_metrics(adata):
|
def calculate_qc_metrics(adata):
|
||||||
if run_qc:
|
if not skip_qc:
|
||||||
sc.pp.calculate_qc_metrics(adata, inplace=True)
|
sc.pp.calculate_qc_metrics(adata, inplace=True)
|
||||||
return adata
|
return adata
|
||||||
|
|
||||||
@@ -179,7 +192,7 @@ def prepare(
|
|||||||
sc.pl.tsne(adata, color="louvain", palette=palette, save="_louvain")
|
sc.pl.tsne(adata, color="louvain", palette=palette, save="_louvain")
|
||||||
|
|
||||||
def show_step(item):
|
def show_step(item):
|
||||||
if run_qc:
|
if not skip_qc:
|
||||||
qc_name = "Calculating QC metrics"
|
qc_name = "Calculating QC metrics"
|
||||||
else:
|
else:
|
||||||
qc_name = "Skipping QC"
|
qc_name = "Skipping QC"
|
||||||
|
|||||||
@@ -24,3 +24,12 @@ def is_port_available(host, port):
|
|||||||
except socket.error:
|
except socket.error:
|
||||||
pass
|
pass
|
||||||
return is_available
|
return is_available
|
||||||
|
|
||||||
|
|
||||||
|
def sort_options(command):
|
||||||
|
"""
|
||||||
|
Helper for the click options - will sort options in a command, and can
|
||||||
|
be used as a decorator.
|
||||||
|
"""
|
||||||
|
command.params.sort(key=lambda p: p.name)
|
||||||
|
return command
|
||||||
|
|||||||
Reference in New Issue
Block a user