def test_get_host(): with mock.patch('socket.gethostname', mock.Mock(return_value='test')),\ mock.patch('socket.gethostbyname', mock.Mock(return_value='127.0.0.1')): assert utils.get_host() == 'test' with mock.patch('socket.gethostbyname', mock.Mock(return_value='127.0.0.1')): assert utils.get_host('test') == 'test' with mock.patch('socket.gethostname', mock.Mock(return_value='http://test')),\ mock.patch('socket.gethostbyname', mock.Mock(side_effect=Exception)): assert utils.get_host() == 'localhost' with mock.patch('socket.gethostbyname', mock.Mock(side_effect=Exception)): with pytest.raises(Exception) as error: utils.get_host('test') assert str(error.value).startswith('Hostname (test) is not recognized')
def test_get_host(): with mock.patch("socket.gethostname", mock.Mock(return_value="test")), mock.patch( "socket.gethostbyname", mock.Mock(return_value="127.0.0.1") ): assert utils.get_host() == "test" with mock.patch("socket.gethostbyname", mock.Mock(return_value="127.0.0.1")): assert utils.get_host("test") == "test" with mock.patch( "socket.gethostname", mock.Mock(return_value="http://test") ), mock.patch("socket.gethostbyname", mock.Mock(side_effect=Exception)): assert utils.get_host() == "localhost" with mock.patch("socket.gethostbyname", mock.Mock(side_effect=Exception)): with pytest.raises(Exception) as error: utils.get_host("test") assert str(error.value).startswith("Hostname (test) is not recognized")
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 build_app(url, host=None, reaper_on=True, hide_shutdown=False, github_fork=False): """ Builds :class:`flask:flask.Flask` application encapsulating endpoints for D-Tale's front-end :return: :class:`flask:flask.Flask` application :rtype: :class:`dtale.app.DtaleFlask` """ app = DtaleFlask('dtale', reaper_on=reaper_on, static_url_path='', url=url) app.config['SECRET_KEY'] = 'Dtale' app.config['HIDE_SHUTDOWN'] = hide_shutdown app.config['GITHUB_FORK'] = github_fork app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True app.register_blueprint(dtale) compress = Compress() compress.init_app(app) _, version = retrieve_meta_info_and_version('dtale') template = dict( info={ 'title': 'D-Tale', 'version': version, 'description': 'Web Client for Visualizing Pandas Objects', 'contact': { 'name': 'Man Alpha Technology', 'email': '*****@*****.**', 'url': 'https://github.com/man-group/dtale' }, }, host=get_host(host), schemes=['http'], ) try: from flasgger import Swagger # flake8: NOQA Swagger(app, template=template) except ImportError: logger.debug('flasgger dependency not found, please install to enable feature') @app.route('/') @app.route('/dtale') @swag_from('swagger/dtale/root.yml') def root(): """ :class:`flask:flask.Flask` routes which redirect to dtale/main :return: 302 - flask.redirect('/dtale/main') """ return redirect('/dtale/main/{}'.format(head_data_id())) @app.route('/favicon.ico') def favicon(): """ :class:`flask:flask.Flask` routes which returns favicon :return: image/png """ return redirect(url_for('static', filename='images/favicon.ico')) @app.errorhandler(404) def page_not_found(e=None): """ :class:`flask:flask.Flask` routes which returns favicon :param e: exception :return: text/html with exception information """ logger.exception(e) return render_template('dtale/errors/404.html', page='', error=e, stacktrace=str(traceback.format_exc())), 404 @app.errorhandler(500) def internal_server_error(e=None): """ :class:`flask:flask.Flask` route which returns favicon :param e: exception :return: text/html with exception information """ logger.exception(e) return render_template('dtale/errors/500.html', page='', error=e, stacktrace=str(traceback.format_exc())), 500 def shutdown_server(): global ACTIVE_HOST, ACTIVE_PORT """ This function that checks if flask.request.environ['werkzeug.server.shutdown'] exists and if so, executes that function """ logger.info('Executing shutdown...') func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') func() cleanup() ACTIVE_PORT = None ACTIVE_HOST = None @app.route('/shutdown') @swag_from('swagger/dtale/shutdown.yml') def shutdown(): """ :class:`flask:flask.Flask` route for initiating server shutdown :return: text/html with server shutdown message """ app.clear_reaper() shutdown_server() return 'Server shutting down...' @app.before_request def before_request(): """ Logic executed before each :attr:`flask:flask.request` :return: text/html with server shutdown message """ app.build_reaper() @app.route('/site-map') @swag_from('swagger/dtale/site-map.yml') def site_map(): """ :class:`flask:flask.Flask` route listing all available flask endpoints :return: JSON of all flask enpoints [ [endpoint1, function path1], ..., [endpointN, function pathN] ] """ def has_no_empty_params(rule): defaults = rule.defaults or () arguments = rule.arguments or () return len(defaults) >= len(arguments) links = [] for rule in app.url_map.iter_rules(): # Filter out rules we can't navigate to in a browser # and rules that require parameters if "GET" in rule.methods and has_no_empty_params(rule): url = url_for(rule.endpoint, **(rule.defaults or {})) links.append((url, rule.endpoint)) return jsonify(links) @app.route('/version-info') @swag_from('swagger/dtale/version-info.yml') def version_info(): """ :class:`flask:flask.Flask` route for retrieving version information about D-Tale :return: text/html version information """ _, version = retrieve_meta_info_and_version('dtale') return str(version) @app.route('/health') @swag_from('swagger/dtale/health.yml') def health_check(): """ :class:`flask:flask.Flask` route for checking if D-Tale is up and running :return: text/html 'ok' """ return 'ok' return app