Beispiel #1
0
def build_startup_url_and_app_root(app_root=None):
    global ACTIVE_HOST, ACTIVE_PORT, JUPYTER_SERVER_PROXY, USE_COLAB

    if USE_COLAB:
        colab_host = use_colab(ACTIVE_PORT)
        if colab_host:
            return colab_host, None
    url = build_url(ACTIVE_PORT, ACTIVE_HOST)
    final_app_root = app_root
    if final_app_root is None and JUPYTER_SERVER_PROXY:
        final_app_root = os.environ.get("JUPYTERHUB_SERVICE_PREFIX")
        if final_app_root is None:
            final_app_root = "/user/{}".format(getpass.getuser())
        final_app_root = ("{}/proxy".format(final_app_root)
                          if not final_app_root.endswith("/proxy") else
                          final_app_root)
    if final_app_root is not None:
        if JUPYTER_SERVER_PROXY:
            final_app_root = fix_url_path("{}/{}".format(
                final_app_root, ACTIVE_PORT))
            return final_app_root, final_app_root
        else:
            return fix_url_path("{}/{}".format(url,
                                               final_app_root)), final_app_root
    return url, final_app_root
Beispiel #2
0
def instances():
    """
    Returns a dictionary of data IDs & :class:dtale.views.DtaleData objects pertaining to all the current pieces of
    data being viewed

    :return: dict
    """
    return {data_id: DtaleData(data_id, build_url(ACTIVE_PORT, ACTIVE_HOST)) for data_id in DATA}
Beispiel #3
0
def instances():
    """
    Prints all urls to the current pieces of data being viewed
    """
    print('\n'.join([
        DtaleData(data_id, build_url(ACTIVE_PORT, ACTIVE_HOST)).main_url()
        for data_id in DATA
    ]))
Beispiel #4
0
def instances():
    """
    Prints all urls to the current pieces of data being viewed
    """
    curr_data = global_state.get_data()
    if len(curr_data):
        print('\n'.join([DtaleData(data_id, build_url(ACTIVE_PORT, ACTIVE_HOST)).main_url() for data_id in curr_data]))
    else:
        print('currently no running instances...')
Beispiel #5
0
def initialize_process_props(host=None, port=None, force=False):
    """
    Helper function to initalize global state corresponding to the host & port being used for your
    :class:`flask:flask.Flask` process

    :param host: hostname to use otherwise it will default to the output of :func:`python:socket.gethostname`
    :type host: str, optional
    :param port: port to use otherwise default to the output of :meth:`dtale.app.find_free_port`
    :type port: str, optional
    :param force: boolean flag to determine whether to ignore the :meth:`dtale.app.find_free_port` function
    :type force: bool
    :return:
    """
    global ACTIVE_HOST, ACTIVE_PORT

    if force:
        active_host = get_host(ACTIVE_HOST)
        curr_base = build_url(ACTIVE_PORT, active_host)
        final_host = get_host(host)
        new_base = build_url(port, final_host)
        if curr_base != new_base:
            if is_up(new_base):
                try:
                    kill(new_base)  # kill the original process
                except BaseException:
                    raise IOError(
                        (
                            "Could not kill process at {}, possibly something else is running at port {}. Please try "
                            "another port."
                        ).format(new_base, port)
                    )
                while is_up(new_base):
                    time.sleep(0.01)
            ACTIVE_HOST = final_host
            ACTIVE_PORT = port
            return

    if ACTIVE_HOST is None:
        ACTIVE_HOST = get_host(host)

    if ACTIVE_PORT is None:
        ACTIVE_PORT = int(port or find_free_port())
Beispiel #6
0
 def _instance_msgs():
     for data_id in global_state.keys():
         data_obj = DtaleData(data_id, build_url(ACTIVE_PORT, ACTIVE_HOST))
         name = global_state.get_name(data_id)
         yield [data_id, name or "", data_obj.build_main_url(data_id=data_id)]
         if name is not None:
             yield [
                 global_state.convert_name_to_url_path(name),
                 name,
                 data_obj.build_main_url(),
             ]
Beispiel #7
0
def build_startup_url_and_app_root(app_root=None):
    url = build_url(ACTIVE_PORT, ACTIVE_HOST)
    final_app_root = app_root
    if final_app_root is None and JUPYTER_SERVER_PROXY:
        final_app_root = '/user/{}/proxy/'.format(getpass.getuser())
    if final_app_root is not None:
        if JUPYTER_SERVER_PROXY:
            final_app_root = fix_url_path('{}/{}'.format(final_app_root, ACTIVE_PORT))
            return final_app_root, final_app_root
        else:
            return fix_url_path('{}/{}'.format(url, final_app_root)), final_app_root
    return url, final_app_root
Beispiel #8
0
def get_instance(data_id):
    """
    Returns a :class:`dtale.views.DtaleData` object for the data_id passed as input, will return None if the data_id
    does not exist

    :param data_id: integer string identifier for a D-Tale process's data
    :type data_id: str
    :return: :class:`dtale.views.DtaleData`
    """
    data_id_str = str(data_id)
    if data_id_str in DATA:
        return DtaleData(data_id_str, build_url(ACTIVE_PORT, ACTIVE_HOST))
    return None
Beispiel #9
0
    def _show():
        app = build_app(reaper_on=reaper_on)
        if debug:
            app.jinja_env.auto_reload = True
            app.config['TEMPLATES_AUTO_RELOAD'] = True
        else:
            getLogger("werkzeug").setLevel(LOG_ERROR)
        url = build_url(selected_port)
        logger.info('D-Tale started at: {}'.format(url))
        if open_browser:
            webbrowser.get().open(url)

        app.run(host=host, port=selected_port, debug=debug)
Beispiel #10
0
def build_startup_url_and_app_root(app_root=None):
    if USE_COLAB:
        colab_host = use_colab(ACTIVE_PORT)
        if colab_host:
            return colab_host, None
    url = build_url(ACTIVE_PORT, ACTIVE_HOST)
    final_app_root = app_root
    if final_app_root is None and JUPYTER_SERVER_PROXY:
        final_app_root = "/user/{}/proxy/".format(getpass.getuser())
    if final_app_root is not None:
        if JUPYTER_SERVER_PROXY:
            final_app_root = fix_url_path("{}/{}".format(final_app_root, ACTIVE_PORT))
            return final_app_root, final_app_root
        else:
            return fix_url_path("{}/{}".format(url, final_app_root)), final_app_root
    return url, final_app_root
Beispiel #11
0
 def run(self, *args, **kwargs):
     """
     :param args: Optional arguments to be passed to :meth:`flask:flask.run`
     :param kwargs: Optional keyword arguments to be passed to :meth:`flask:flask.run`
     """
     port_num = kwargs.get("port")
     self.port = str(port_num or "")
     if not self.base_url:
         host = kwargs.get("host")
         initialize_process_props(host, port_num)
         app_url = build_url(self.port, host)
         self._setup_url_props(app_url)
     if kwargs.get("debug", False):
         self.reaper_on = False
     self.build_reaper()
     super(DtaleFlask, self).run(
         use_reloader=kwargs.get("debug", False), *args, **kwargs
     )
Beispiel #12
0
def test_build_url():
    assert utils.build_url(8080, "localhost") == "http://localhost:8080"
    assert utils.build_url(8080, "http://localhost") == "http://localhost:8080"
    assert utils.build_url(8080,
                           "https://localhost") == "https://localhost:8080"
Beispiel #13
0
 def _instance_msg(data_id):
     url = DtaleData(data_id, build_url(ACTIVE_PORT,
                                        ACTIVE_HOST)).main_url()
     return '{}:\t{}'.format(data_id, url)
Beispiel #14
0
def show(data=None, data_loader=None, name=None, context_vars=None, **options):
    """
    Entry point for kicking off D-Tale :class:`flask:flask.Flask` process from python process

    :param data: data which D-Tale will display
    :type data: :class:`pandas:pandas.DataFrame` or :class:`pandas:pandas.Series`
                or :class:`pandas:pandas.DatetimeIndex` or :class:`pandas:pandas.MultiIndex`, optional
    :param host: hostname of D-Tale, defaults to 0.0.0.0
    :type host: str, optional
    :param port: port number of D-Tale process, defaults to any open port on server
    :type port: str, optional
    :param name: optional label to assign a D-Tale process
    :type name: str, optional
    :param debug: will turn on :class:`flask:flask.Flask` debug functionality, defaults to False
    :type debug: bool, optional
    :param subprocess: run D-Tale as a subprocess of your current process, defaults to True
    :type subprocess: bool, optional
    :param data_loader: function to load your data
    :type data_loader: func, optional
    :param reaper_on: turn on subprocess which will terminate D-Tale after 1 hour of inactivity
    :type reaper_on: bool, optional
    :param open_browser: if true, this will try using the :mod:`python:webbrowser` package to automatically open
                         your default browser to your D-Tale process
    :type open_browser: bool, optional
    :param notebook: if true, this will try displaying an :class:`ipython:IPython.display.IFrame`
    :type notebook: bool, optional
    :param force: if true, this will force the D-Tale instance to run on the specified host/port by killing any
                  other process running at that location
    :type force: bool, optional
    :param context_vars: a dictionary of the variables that will be available for use in user-defined expressions,
                         such as filters
    :type context_vars: dict, optional
    :param ignore_duplicate: if true, this will not check if this data matches any other data previously loaded to
                             D-Tale
    :type ignore_duplicate: bool, optional
    :param app_root: Optional path to prepend to the routes of D-Tale. This is used when making use of
                     Jupyterhub server proxy
    :type app_root: str, optional
    :param allow_cell_edits: If false, this will not allow users to edit cells directly in their D-Tale grid
    :type allow_cell_edits: bool, optional
    :param inplace: If true, this will call `reset_index(inplace=True)` on the dataframe used as a way to save memory.
                    Otherwise this will create a brand new dataframe, thus doubling memory but leaving the dataframe
                    input unchanged.
    :type inplace: bool, optional
    :param drop_index: If true, this will drop any pre-existing index on the dataframe input.
    :type drop_index: bool, optional
    :param hide_shutdown: If true, this will hide the "Shutdown" buton from users
    :type hide_shutdown: bool, optional
    :param github_fork: If true, this will display a "Fork me on GitHub" ribbon in the upper right-hand corner of the
                        app
    :type github_fork: bool, optional

    :Example:

        >>> import dtale
        >>> import pandas as pd
        >>> df = pandas.DataFrame([dict(a=1,b=2,c=3)])
        >>> dtale.show(df)
        D-Tale started at: http://hostname:port

        ..link displayed in logging can be copied and pasted into any browser
    """
    global ACTIVE_HOST, ACTIVE_PORT, USE_NGROK

    try:
        final_options = dtale_config.build_show_options(options)
        logfile, log_level, verbose = map(
            final_options.get, ["logfile", "log_level", "verbose"]
        )
        setup_logging(logfile, log_level or "info", verbose)

        if USE_NGROK:
            if not PY3:
                raise Exception(
                    "In order to use ngrok you must be using Python 3 or higher!"
                )

            from flask_ngrok import _run_ngrok

            ACTIVE_HOST = _run_ngrok()
            ACTIVE_PORT = None
        else:
            initialize_process_props(
                final_options["host"], final_options["port"], final_options["force"]
            )

        app_url = build_url(ACTIVE_PORT, ACTIVE_HOST)
        startup_url, final_app_root = build_startup_url_and_app_root(
            final_options["app_root"]
        )
        instance = startup(
            startup_url,
            data=data,
            data_loader=data_loader,
            name=name,
            context_vars=context_vars,
            ignore_duplicate=final_options["ignore_duplicate"],
            allow_cell_edits=final_options["allow_cell_edits"],
            inplace=final_options["inplace"],
            drop_index=final_options["drop_index"],
            precision=final_options["precision"],
            show_columns=final_options["show_columns"],
            hide_columns=final_options["hide_columns"],
        )
        instance.started_with_open_browser = final_options["open_browser"]
        is_active = not running_with_flask_debug() and is_up(app_url)
        if is_active:

            def _start():
                if final_options["open_browser"]:
                    instance.open_browser()

        else:
            if USE_NGROK:
                thread = Timer(1, _run_ngrok)
                thread.setDaemon(True)
                thread.start()

            def _start():
                app = build_app(
                    app_url,
                    reaper_on=final_options["reaper_on"],
                    host=ACTIVE_HOST,
                    app_root=final_app_root,
                )
                if final_options["debug"] and not USE_NGROK:
                    app.jinja_env.auto_reload = True
                    app.config["TEMPLATES_AUTO_RELOAD"] = True
                else:
                    getLogger("werkzeug").setLevel(LOG_ERROR)

                if final_options["open_browser"]:
                    instance.open_browser()

                # hide banner message in production environments
                cli = sys.modules.get("flask.cli")
                if cli is not None:
                    cli.show_server_banner = lambda *x: None

                if USE_NGROK:
                    app.run(threaded=True)
                else:
                    app.run(
                        host="0.0.0.0",
                        port=ACTIVE_PORT,
                        debug=final_options["debug"],
                        threaded=True,
                    )

        if final_options["subprocess"]:
            if is_active:
                _start()
            else:
                _thread.start_new_thread(_start, ())

            if final_options["notebook"]:
                instance.notebook()
        else:
            logger.info("D-Tale started at: {}".format(app_url))
            _start()

        return instance
    except DuplicateDataError as ex:
        print(
            "It looks like this data may have already been loaded to D-Tale based on shape and column names. Here is "
            "URL of the data that seems to match it:\n\n{}\n\nIf you still want to load this data please use the "
            "following command:\n\ndtale.show(df, ignore_duplicate=True)".format(
                DtaleData(ex.data_id, build_url(ACTIVE_PORT, ACTIVE_HOST)).main_url()
            )
        )
    return None
Beispiel #15
0
def show(data=None, host=None, port=None, name=None, debug=False, subprocess=True, data_loader=None,
         reaper_on=True, open_browser=False, notebook=False, force=False, **kwargs):
    """
    Entry point for kicking off D-Tale :class:`flask:flask.Flask` process from python process

    :param data: data which D-Tale will display
    :type data: :class:`pandas:pandas.DataFrame` or :class:`pandas:pandas.Series`
                or :class:`pandas:pandas.DatetimeIndex` or :class:`pandas:pandas.MultiIndex`, optional
    :param host: hostname of D-Tale, defaults to 0.0.0.0
    :type host: str, optional
    :param port: port number of D-Tale process, defaults to any open port on server
    :type port: str, optional
    :param name: optional label to assign a D-Tale process
    :type name: str, optional
    :param debug: will turn on :class:`flask:flask.Flask` debug functionality, defaults to False
    :type debug: bool, optional
    :param subprocess: run D-Tale as a subprocess of your current process, defaults to True
    :type subprocess: bool, optional
    :param data_loader: function to load your data
    :type data_loader: func, optional
    :param reaper_on: turn on subprocess which will terminate D-Tale after 1 hour of inactivity
    :type reaper_on: bool, optional
    :param open_browser: if true, this will try using the :mod:`python:webbrowser` package to automatically open
                         your default browser to your D-Tale process
    :type open_browser: bool, optional
    :param notebook: if true, this will try displaying an :class:`ipython:IPython.display.IFrame`
    :type notebook: bool, optional
    :param force: if true, this will force the D-Tale instance to run on the specified host/port by killing any
                  other process running at that location
    :type force: bool, optional

    :Example:

        >>> import dtale
        >>> import pandas as pd
        >>> df = pandas.DataFrame([dict(a=1,b=2,c=3)])
        >>> dtale.show(df)
        D-Tale started at: http://hostname:port

        ..link displayed in logging can be copied and pasted into any browser
    """

    logfile, log_level, verbose = map(kwargs.get, ['logfile', 'log_level', 'verbose'])
    setup_logging(logfile, log_level or 'info', verbose)

    initialize_process_props(host, port, force)
    url = build_url(ACTIVE_PORT, ACTIVE_HOST)
    instance = startup(url, data=data, data_loader=data_loader, name=name)
    is_active = not running_with_flask_debug() and is_up(url)
    if is_active:
        def _start():
            if open_browser:
                instance.open_browser()
    else:
        def _start():
            app = build_app(url, reaper_on=reaper_on, host=ACTIVE_HOST)
            if debug:
                app.jinja_env.auto_reload = True
                app.config['TEMPLATES_AUTO_RELOAD'] = True
            else:
                getLogger("werkzeug").setLevel(LOG_ERROR)

            if open_browser:
                instance.open_browser()

            # hide banner message in production environments
            cli = sys.modules.get('flask.cli')
            if cli is not None:
                cli.show_server_banner = lambda *x: None

            app.run(host='0.0.0.0', port=ACTIVE_PORT, debug=debug, threaded=True)

    if subprocess:
        if is_active:
            _start()
        else:
            _thread.start_new_thread(_start, ())

        if notebook:
            instance.notebook()
    else:
        logger.info('D-Tale started at: {}'.format(url))
        _start()

    return instance
Beispiel #16
0
def test_build_url():
    assert utils.build_url(8080, 'localhost') == 'http://localhost:8080'
    assert utils.build_url(8080, 'http://localhost') == 'http://localhost:8080'
    assert utils.build_url(8080,
                           'https://localhost') == 'https://localhost:8080'
Beispiel #17
0
 def __init__(self, port):
     self._port = port
     self._url = build_url(port)
     self._notebook_handle = None
Beispiel #18
0
def show(data=None,
         host=None,
         port=None,
         name=None,
         debug=False,
         subprocess=True,
         data_loader=None,
         reaper_on=True,
         open_browser=False,
         notebook=False,
         force=False,
         context_vars=None,
         ignore_duplicate=False,
         app_root=None,
         **kwargs):
    """
    Entry point for kicking off D-Tale :class:`flask:flask.Flask` process from python process

    :param data: data which D-Tale will display
    :type data: :class:`pandas:pandas.DataFrame` or :class:`pandas:pandas.Series`
                or :class:`pandas:pandas.DatetimeIndex` or :class:`pandas:pandas.MultiIndex`, optional
    :param host: hostname of D-Tale, defaults to 0.0.0.0
    :type host: str, optional
    :param port: port number of D-Tale process, defaults to any open port on server
    :type port: str, optional
    :param name: optional label to assign a D-Tale process
    :type name: str, optional
    :param debug: will turn on :class:`flask:flask.Flask` debug functionality, defaults to False
    :type debug: bool, optional
    :param subprocess: run D-Tale as a subprocess of your current process, defaults to True
    :type subprocess: bool, optional
    :param data_loader: function to load your data
    :type data_loader: func, optional
    :param reaper_on: turn on subprocess which will terminate D-Tale after 1 hour of inactivity
    :type reaper_on: bool, optional
    :param open_browser: if true, this will try using the :mod:`python:webbrowser` package to automatically open
                         your default browser to your D-Tale process
    :type open_browser: bool, optional
    :param notebook: if true, this will try displaying an :class:`ipython:IPython.display.IFrame`
    :type notebook: bool, optional
    :param force: if true, this will force the D-Tale instance to run on the specified host/port by killing any
                  other process running at that location
    :type force: bool, optional
    :param context_vars: a dictionary of the variables that will be available for use in user-defined expressions,
                         such as filters
    :type context_vars: dict, optional
    :param ignore_duplicate: if true, this will not check if this data matches any other data previously loaded to
                             D-Tale
    :type ignore_duplicate: bool, optional

    :Example:

        >>> import dtale
        >>> import pandas as pd
        >>> df = pandas.DataFrame([dict(a=1,b=2,c=3)])
        >>> dtale.show(df)
        D-Tale started at: http://hostname:port

        ..link displayed in logging can be copied and pasted into any browser
    """
    global ACTIVE_HOST, ACTIVE_PORT, USE_NGROK, USE_COLAB, JUPYTER_SERVER_PROXY

    try:
        logfile, log_level, verbose = map(kwargs.get,
                                          ["logfile", "log_level", "verbose"])
        setup_logging(logfile, log_level or "info", verbose)

        if USE_NGROK:
            if not PY3:
                raise Exception(
                    "In order to use ngrok you must be using Python 3 or higher!"
                )

            from flask_ngrok import _run_ngrok

            ACTIVE_HOST = _run_ngrok()
            ACTIVE_PORT = None
        else:
            initialize_process_props(host, port, force)

        app_url = build_url(ACTIVE_PORT, ACTIVE_HOST)
        startup_url, final_app_root = build_startup_url_and_app_root(app_root)
        instance = startup(
            startup_url,
            data=data,
            data_loader=data_loader,
            name=name,
            context_vars=context_vars,
            ignore_duplicate=ignore_duplicate,
        )
        is_active = not running_with_flask_debug() and is_up(app_url)
        if is_active:

            def _start():
                if open_browser:
                    instance.open_browser()

        else:
            if USE_NGROK:
                thread = Timer(1, _run_ngrok)
                thread.setDaemon(True)
                thread.start()

            def _start():
                app = build_app(
                    app_url,
                    reaper_on=reaper_on,
                    host=ACTIVE_HOST,
                    app_root=final_app_root,
                )
                if debug and not USE_NGROK:
                    app.jinja_env.auto_reload = True
                    app.config["TEMPLATES_AUTO_RELOAD"] = True
                else:
                    getLogger("werkzeug").setLevel(LOG_ERROR)

                if open_browser:
                    instance.open_browser()

                # hide banner message in production environments
                cli = sys.modules.get("flask.cli")
                if cli is not None:
                    cli.show_server_banner = lambda *x: None

                if USE_NGROK:
                    app.run(threaded=True)
                else:
                    app.run(host="0.0.0.0",
                            port=ACTIVE_PORT,
                            debug=debug,
                            threaded=True)

        if subprocess:
            if is_active:
                _start()
            else:
                _thread.start_new_thread(_start, ())

            if notebook:
                instance.notebook()
        else:
            logger.info("D-Tale started at: {}".format(app_url))
            _start()

        return instance
    except DuplicateDataError as ex:
        print(
            "It looks like this data may have already been loaded to D-Tale based on shape and column names. Here is "
            "URL of the data that seems to match it:\n\n{}\n\nIf you still want to load this data please use the "
            "following command:\n\ndtale.show(df, ignore_duplicate=True)".
            format(
                DtaleData(ex.data_id, build_url(ACTIVE_PORT,
                                                ACTIVE_HOST)).main_url()))
    return None
Beispiel #19
0
from urllib.parse import urljoin

import dtale
import pandas as pd
from dtale import global_state, utils as _utils

from dtale_desktop.settings import settings

dtale.app.initialize_process_props(host=settings.HOST,
                                   port=settings.DTALE_PORT)

DTALE_HOST = dtale.app.ACTIVE_HOST

DTALE_PORT = dtale.app.ACTIVE_PORT

DTALE_INTERNAL_ROOT_URL = _utils.build_url(DTALE_PORT, DTALE_HOST)

DTALE_EXTERNAL_ROOT_URL = settings.DTALE_ROOT_URL or DTALE_INTERNAL_ROOT_URL

app = dtale.app.build_app(DTALE_INTERNAL_ROOT_URL,
                          host=DTALE_HOST,
                          reaper_on=False)

global_state.set_app_settings({"hide_shutdown": True})


def run():
    _thread.start_new_thread(
        app.run, (), dict(host=DTALE_HOST, port=DTALE_PORT, threaded=True))