Пример #1
0
def launch(data, verbose, debug, open_browser, port, host, layout, obs_names,
           var_names, max_category_items, diffexp_lfc_cutoff, title, scripts):
    """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>"""

    e_args = parse_engine_args(layout, obs_names, var_names,
                               max_category_items, diffexp_lfc_cutoff)
    # Startup message
    click.echo("[cellxgene] Starting the CLI...")

    # 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
    else:
        warnings.formatwarning = custom_format_warning

    if not verbose:
        sys.tracebacklimit = 0

    if scripts:
        click.echo(r"""
    / / /\ \ \__ _ _ __ _ __ (_)_ __   __ _
    \ \/  \/ / _` | '__| '_ \| | '_ \ / _` |
     \  /\  / (_| | |  | | | | | | | | (_| |
      \/  \/ \__,_|_|  |_| |_|_|_| |_|\__, |
                                      |___/
    The --scripts flag is intended for developers to include google analytics etc. You could be opening yourself to a
    security risk by including the --scripts flag. Make sure you trust the scripts that you are including.
            """)
        scripts_pretty = ", ".join(scripts)
        click.confirm(
            f"Are you sure you want to inject these scripts: {scripts_pretty}?",
            abort=True)

    if not title:
        file_parts = splitext(basename(data))
        title = file_parts[0]

    if port:
        if debug:
            raise click.ClickException(
                "--port and --debug may not be used together (try --verbose for error logging)."
            )
        if not is_port_available(host, int(port)):
            raise click.ClickException(
                f"The port selected {port} is in use, please specify an open port using the --port flag."
            )
    else:
        port = find_available_port(host)

    # Setup app
    cellxgene_url = f"http://{host}:{port}"

    # Import Flask app
    server = Server()

    server.create_app()
    server.app.config.update(SCRIPTS=scripts)

    if not verbose:
        log = logging.getLogger("werkzeug")
        log.setLevel(logging.ERROR)

    file_size = getsize(data)

    # if a big file, let the user know it may take a while to load.
    if file_size > BIG_FILE_SIZE_THRESHOLD:
        click.echo(
            f"[cellxgene] Loading data from {basename(data)}, this may take awhile..."
        )
    else:
        click.echo(f"[cellxgene] Loading data from {basename(data)}.")

    # Fix for anaconda python. matplotlib typically expects python to be installed as a framework TKAgg is usually
    # available and fixes this issue. See https://matplotlib.org/faq/virtualenv_faq.html
    import matplotlib as mpl

    mpl.use("TkAgg")
    from server.app.scanpy_engine.scanpy_engine import ScanpyEngine

    try:
        server.attach_data(ScanpyEngine(data, e_args), title=title)
    except ScanpyFileError as e:
        raise click.ClickException(f"{e}")

    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.")

    if not verbose:
        f = open(devnull, "w")
        sys.stdout = f

    try:
        server.app.run(host=host,
                       debug=debug,
                       port=port,
                       threaded=True,
                       use_debugger=False)
    except OSError as e:
        if e.errno == errno.EADDRINUSE:
            raise click.ClickException(
                "Port is in use, please specify an open port using the --port flag."
            ) from e
        raise
Пример #2
0
def launch(data, verbose, debug, open_browser, port, host, embedding,
           obs_names, var_names, max_category_items, diffexp_lfc_cutoff, title,
           scripts, about, experimental_label_file, backed, disable_diffexp):
    """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>

    > cellxgene launch <url>"""

    e_args = parse_engine_args(embedding, obs_names, var_names,
                               max_category_items, diffexp_lfc_cutoff,
                               experimental_label_file, backed,
                               disable_diffexp)
    try:
        data_locator = DataLocator(data)
    except RuntimeError as re:
        raise click.ClickException(
            f"Unable to access data at {data}.  {str(re)}")

    # Startup message
    click.echo("[cellxgene] Starting the CLI...")

    # Argument checking
    if data_locator.islocal():
        # if data locator is local, apply file system conventions and other "cheap"
        # validation checks.  If a URI, defer until we actually fetch the data and
        # try to read it.  Many of these tests don't make sense for URIs (eg, extension-
        # based typing).
        if not data_locator.exists():
            raise click.FileError(data, hint="file does not exist")
        if not data_locator.isfile():
            raise click.FileError(data, hint="data is not a file")
        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
    else:
        warnings.formatwarning = custom_format_warning

    if not verbose:
        sys.tracebacklimit = 0

    if scripts:
        click.echo(r"""
    / / /\ \ \__ _ _ __ _ __ (_)_ __   __ _
    \ \/  \/ / _` | '__| '_ \| | '_ \ / _` |
     \  /\  / (_| | |  | | | | | | | | (_| |
      \/  \/ \__,_|_|  |_| |_|_|_| |_|\__, |
                                      |___/
    The --scripts flag is intended for developers to include google analytics etc. You could be opening yourself to a
    security risk by including the --scripts flag. Make sure you trust the scripts that you are including.
            """)
        scripts_pretty = ", ".join(scripts)
        click.confirm(
            f"Are you sure you want to inject these scripts: {scripts_pretty}?",
            abort=True)

    if not title:
        file_parts = splitext(basename(data))
        title = file_parts[0]

    if port:
        if debug:
            raise click.ClickException(
                "--port and --debug may not be used together (try --verbose for error logging)."
            )
        if not is_port_available(host, int(port)):
            raise click.ClickException(
                f"The port selected {port} is in use, please specify an open port using the --port flag."
            )
    else:
        port = find_available_port(host)

    if experimental_label_file:
        lf_name, lf_ext = splitext(experimental_label_file)
        if lf_ext and lf_ext != ".csv":
            raise click.FileError(basename(experimental_label_file),
                                  hint="label file type must be .csv")

    if about:

        def url_check(url):
            try:
                result = urlparse(url)
                if all([result.scheme, result.netloc]):
                    return True
                else:
                    return False
            except ValueError:
                return False

        if not url_check(about):
            raise click.ClickException(
                "Must provide an absolute URL for --about. (Example format: http://example.com)"
            )

    # Setup app
    cellxgene_url = f"http://{host}:{port}"

    # Import Flask app
    server = Server()

    server.create_app()
    server.app.config.update(SCRIPTS=scripts)

    if not verbose:
        log = logging.getLogger("werkzeug")
        log.setLevel(logging.ERROR)

    file_size = data_locator.size() if data_locator.islocal() else 0

    # if a big file, let the user know it may take a while to load.
    if file_size > BIG_FILE_SIZE_THRESHOLD:
        click.echo(
            f"[cellxgene] Loading data from {basename(data)}, this may take a while..."
        )
    else:
        click.echo(f"[cellxgene] Loading data from {basename(data)}.")

    from server.app.scanpy_engine.scanpy_engine import ScanpyEngine

    try:
        server.attach_data(ScanpyEngine(data_locator, e_args),
                           title=title,
                           about=about)
    except ScanpyFileError as e:
        raise click.ClickException(f"{e}")

    if not disable_diffexp and server.app.data.config['diffexp_may_be_slow']:
        click.echo(f"[cellxgene] CAUTION: due to the size of your dataset, "
                   f"running differential expression may take longer or fail.")

    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.")

    if not verbose:
        f = open(devnull, "w")
        sys.stdout = f

    try:
        server.app.run(host=host,
                       debug=debug,
                       port=port,
                       threaded=False if debug else True,
                       use_debugger=False)
    except OSError as e:
        if e.errno == errno.EADDRINUSE:
            raise click.ClickException(
                "Port is in use, please specify an open port using the --port flag."
            ) from e
        raise
Пример #3
0
from server.gui.browser import CefWidget, CefApplication
from server.gui.workers import Worker, SiteReadyWorker
from server.gui.utils import WINDOWS, LINUX, MAC, FileLoadSignals, Emitter, WorkerSignals, FileChanged
from server.utils.utils import find_available_port

if WINDOWS or LINUX:
    dirname = dirname(PySide2.__file__)
    plugin_path = join(dirname, 'plugins', 'platforms')
    environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path

# Configuration
# TODO remember this or calculate it?
WIDTH = 1300
HEIGHT = 800
MAX_CONTENT_WIDTH = 700
GUI_PORT = find_available_port("localhost")
BROWSER_INDEX = 0
LOAD_INDEX = 1


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__(None)
        self.cef_widget = None
        self.data_widget = None
        self.stacked_layout = None
        self.parent_conn, self.child_conn = None, None
        self.load_emitter = None
        self.emitter_thread = None
        self.worker = None
        self.url = f"http://localhost:{GUI_PORT}/"