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
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}
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 ]))
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...')
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())
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(), ]
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
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
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)
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
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 )
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"
def _instance_msg(data_id): url = DtaleData(data_id, build_url(ACTIVE_PORT, ACTIVE_HOST)).main_url() return '{}:\t{}'.format(data_id, url)
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
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
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'
def __init__(self, port): self._port = port self._url = build_url(port) self._notebook_handle = None
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
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))