Files
cellxgene/server/cli/launch.py
Bruce Martin 2d5bc9d0c9 Performance work, plus fix #405 (#406)
* remove memoization

* update to flash 1.0.2; turn on threading

* stand-alone helper routines for array slicing

* fix issue #405

* reset diffexp state when world changes

* performance work in dimension creation; fix world slicing bug

* update tests to match new state mgmt api

* update flask

* do not make dimensions for useless annotations

* update test to match optimizations
2018-11-05 13:57:58 -08:00

100 lines
3.8 KiB
Python

import sys
import click
import logging
import webbrowser
from os.path import splitext, basename
@click.command()
@click.argument('data', metavar='<data file>', type=click.Path(exists=True, file_okay=True, dir_okay=False))
@click.option('--layout', '-l', type=click.Choice(['umap', 'tsne']), default='umap', show_default=True,
help='Method for layout.')
@click.option('--diffexp', '-d', type=click.Choice(['ttest']), default='ttest', show_default=True,
help='Method for differential expression.')
@click.option('--title', '-t', help='Title to display (if omitted will use file name).', metavar='')
@click.option('--verbose', '-v', is_flag=True, default=False, show_default=True,
help='Provide verbose output, including warnings and all server requests.')
@click.option('--debug', '-d', is_flag=True, default=False, show_default=True,
help='Run in debug mode.')
@click.option('--open', '-o', 'open_browser', is_flag=True, default=False, show_default=True,
help='Open the web browser after launch.')
@click.option('--port', '-p', help="Port to run server on.", metavar='', default=5005, show_default=True)
@click.option('--obs-names', default=None, metavar='', help='Name of annotation field to use for observations.')
@click.option('--var-names', default=None, metavar='', help='Name of annotation to use for variables.')
@click.option('--listen-all', is_flag=True, default=False, show_default=True,
help='Bind to all interfaces (this makes the server accessible beyond this computer).')
@click.option('--max-category-items', default=100, metavar='', show_default=True,
help='Limits the number of categorical annotation items displayed.')
def launch(data, layout, diffexp, title, verbose, debug, obs_names, var_names,
open_browser, port, listen_all, max_category_items):
"""Launch the cellxgene data viewer.
This web app lets you explore single-cell expression data.
Data must be in a format that cellxgene expects, read the
"getting started" guide.
Examples:
> cellxgene launch example_dataset/pbmc3k.h5ad --title pbmc3k
> cellxgene launch <your data file> --title <your title>"""
# Startup message
click.echo('[cellxgene] Starting the CLI...')
# Import Flask app
from server.app.app import app
# Argument checking
name, extension = splitext(data)
if extension != '.h5ad':
raise click.FileError(basename(data), hint='file type must be .h5ad')
if debug:
verbose = True
open_browser = False
if not verbose:
sys.tracebacklimit = 0
if not title:
file_parts = splitext(basename(data))
title = file_parts[0]
if listen_all:
host = '0.0.0.0'
else:
host = '127.0.0.1'
# Setup app
cellxgene_url = f"http://{host}:{port}"
api_base = f"{cellxgene_url}/api/"
app.config.update(
DATASET_TITLE=title,
CXG_API_BASE=api_base
)
if not verbose:
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
click.echo(f'[cellxgene] Loading data from {basename(data)}, this may take awhile...')
from server.app.scanpy_engine.scanpy_engine import ScanpyEngine
args = {'layout': layout, 'diffexp': diffexp, 'max_category_items': max_category_items,
'obs_names': obs_names, 'var_names': var_names}
app.data = ScanpyEngine(data, args)
if open_browser:
click.echo(f'[cellxgene] Launching! Opening your browser to {cellxgene_url} now.')
webbrowser.open(cellxgene_url)
else:
click.echo(f'[cellxgene] Launching! Please go to {cellxgene_url} in your browser.')
click.echo('[cellxgene] Type CTRL-C at any time to exit.')
app.run(host=host, debug=debug, port=port, threaded=True)