def _config_create(config_file, profile, ask_full=False): """Full/simplified dwave create flows.""" if ask_full: rs = Client._fetch_available_regions(DEFAULT_METADATA_API_ENDPOINT) prompts = dict( region=dict(prompt="Solver API region", choices=[r.code for r in rs]), endpoint=dict(prompt="Solver API endpoint URL (overwrites 'region')"), token=dict(prompt="Authentication token"), client=dict(prompt="Client class", choices='base qpu sw hybrid'.split()), solver=dict(prompt="Solver")) else: prompts = dict( token=dict(prompt="Authentication token")) click.echo("Using the simplified configuration flow.\n" "Try 'dwave config create --full' for more options.\n") # resolve config file path ask_to_confirm_config_path = not config_file if not config_file: config_file = get_configfile_path() if not config_file: config_file = get_default_configfile_path() config_file_exists = os.path.exists(config_file) verb = "Updating existing" if config_file_exists else "Creating new" click.echo(f"{verb} configuration file: {config_file}") if ask_full and ask_to_confirm_config_path: config_file = default_text_input("Confirm configuration file path", config_file) config_file = os.path.expanduser(config_file) config = _load_config(config_file) default_section = config.default_section # resolve profile if not profile: existing = config.sections() if default_section in config: # not included in sections existing.insert(0, default_section) if config_file_exists: click.echo(f"Available profiles: {', '.join(existing)}") default_profile = next(iter(existing)) _note = " (select existing or create new)" if config_file_exists else "" profile = default_text_input(f"Profile{_note}", default_profile) verb = "Updating existing" if profile in config else "Creating new" click.echo(f"{verb} profile: {profile}") if profile != default_section and not config.has_section(profile): config.add_section(profile) _input_config_variables(config, profile, prompts) _write_config(config, config_file) click.echo("Configuration saved.")
def test_optional_choices_text_input(self): with mock.patch("click.termui.visible_prompt_func", side_effect=[""]): self.assertEqual( default_text_input("prompt", choices='abc', optional=True), None) with mock.patch("click.termui.visible_prompt_func", side_effect=["d", "skip"]): self.assertEqual( default_text_input("prompt", choices='abc', optional=True), None) with mock.patch("click.termui.visible_prompt_func", side_effect=["e", "a"]): self.assertEqual( default_text_input("prompt", choices='abc', optional=True), 'a')
def setup(install_all, ask_full, verbose): """Setup optional Ocean packages and configuration file(s). Equivalent to running `dwave install [--all]`, followed by `dwave config create [--full]`. """ contrib = get_contrib_packages() packages = list(contrib) if not packages: install = False elif install_all: click.echo("Installing all optional non-open-source packages.\n") install = True else: # The default flow: SDK installed, so some contrib packages registered # and `dwave setup` ran without `--all` flag. click.echo("Optionally install non-open-source packages and " "configure your environment.\n") prompt = "Do you want to select non-open-source packages to install (y/n)?" val = default_text_input(prompt, default='y') install = val.lower() == 'y' click.echo() if install: for pkg in packages: _install_contrib_package(pkg, verbose=verbose, prompt=not install_all) click.echo("Creating the D-Wave configuration file.") return _config_create(config_file=None, profile=None, ask_full=ask_full)
def _input_config_variables(config: ConfigParser, profile: str, prompts: Dict[str, Dict[str, str]]) -> ConfigParser: """Update config variables in place with user-provided values.""" for var, prompt in prompts.items(): default_val = config.get(profile, var, fallback=None) prompt.setdefault('default', default_val) val = default_text_input(**prompt) if val: val = os.path.expandvars(val) if val and val != default_val: config.set(profile, var, val) return config
def _install_contrib_package(name, verbose=False, prompt=True): """pip install non-oss package `name` from dwave's pypi repo.""" contrib = get_contrib_packages() dwave_contrib_repo = "https://pypi.dwavesys.com/simple" assert name in contrib pkg = contrib[name] title = pkg['title'] # check is `name` package is already installed # right now the only way to check that is to check if all dependants from # requirements are installed # NOTE: currently we do not check if versions match! if all(_is_pip_package_installed(req) for req in pkg['requirements']): click.echo("{} already installed.\n".format(title)) return # basic pkg info click.echo(title) click.echo(pkg['description']) # license prompt license = pkg['license'] msgtpl = ("This package is available under the {name} license.\n" "The terms of the license are available online: {url}") click.echo(msgtpl.format(name=license['name'], url=license['url'])) if prompt: val = default_text_input('Install (y/n)?', default='y', optional=False) if val.lower() != 'y': click.echo('Skipping: {}.\n'.format(title)) return click.echo('Installing: {}'.format(title)) for req in pkg['requirements']: # NOTE: py35+ required res = subprocess.run([ sys.executable, "-m", "pip", "install", req, "--extra-index", dwave_contrib_repo ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if res.returncode or verbose: click.echo(res.stdout) click.echo('Successfully installed {}.\n'.format(title))
def create(config_file, profile): """Create and/or update cloud client configuration file.""" # determine the config file path if config_file: click.echo("Using configuration file: {}".format(config_file)) else: # path not given, try to detect; or use default, but allow user to override config_file = get_configfile_path() if config_file: click.echo( "Found existing configuration file: {}".format(config_file)) else: config_file = get_default_configfile_path() click.echo( "Configuration file not found; the default location is: {}". format(config_file)) config_file = default_text_input("Configuration file path", config_file) config_file = os.path.expanduser(config_file) # create config_file path config_base = os.path.dirname(config_file) if config_base and not os.path.exists(config_base): if click.confirm("Configuration file path does not exist. Create it?", abort=True): try: os.makedirs(config_base) except Exception as e: click.echo("Error creating configuration path: {}".format(e)) return 1 # try loading existing config, or use defaults try: config = load_config_from_files([config_file]) except: config = get_default_config() # determine profile if profile: click.echo("Using profile: {}".format(profile)) else: existing = config.sections() if existing: profiles = 'create new or choose from: {}'.format( ', '.join(existing)) default_profile = '' else: profiles = 'create new' default_profile = 'prod' profile = default_text_input("Profile (%s)" % profiles, default_profile, optional=False) if not config.has_section(profile): config.add_section(profile) # fill out the profile variables variables = 'endpoint token client solver proxy'.split() prompts = [ 'API endpoint URL', 'Authentication token', 'Default client class (qpu or sw)', 'Default solver' ] for var, prompt in zip(variables, prompts): default_val = config.get(profile, var, fallback=None) val = default_text_input(prompt, default_val) if val: val = os.path.expandvars(val) if val != default_val: config.set(profile, var, val) try: with open(config_file, 'w') as fp: config.write(fp) except Exception as e: click.echo("Error writing to configuration file: {}".format(e)) return 2 click.echo("Configuration saved.") return 0
def test_default_text_input(self): val = "value" with mock.patch("six.moves.input", side_effect=[val], create=True): self.assertEqual(default_text_input("prompt", val), val) with mock.patch("six.moves.input", side_effect=[val], create=True): self.assertEqual(default_text_input("prompt", val + val), val)
def _install_contrib_package(name, verbose=0, prompt=True): """pip install non-oss package `name` from dwave's pypi repo.""" contrib = get_contrib_packages() dwave_contrib_repo = "https://pypi.dwavesys.com/simple" assert name in contrib pkg = contrib[name] title = pkg['title'] # check if `name` package is already installed # right now the only way to check that is to check if all dependencies from # requirements are installed reinstall = False try: if all(_get_dist(req) for req in pkg['requirements']): click.echo("{} installed and up to date.\n".format(title)) return except pkg_resources.VersionConflict: click.echo("{} dependency version mismatch.\n".format(title)) reinstall = True except pkg_resources.DistributionNotFound: pass # dependency not installed, proceed with install action = 'Reinstall' if reinstall else 'Install' # basic pkg info click.echo(title) click.echo(pkg['description']) # license prompt license = pkg['license'] msgtpl = ("This package is available under the {name} license.\n" "The terms of the license are available online: {url}") click.echo(msgtpl.format(name=license['name'], url=license['url'])) if prompt: val = default_text_input('{} (y/n)?'.format(action), default='y', optional=False) if val.lower() != 'y': click.echo('Skipping: {}.\n'.format(title)) return click.echo('{}ing: {}'.format(action, title)) for req in pkg['requirements']: cmd = [sys.executable, "-m", "pip", "install", req, "--extra-index-url", dwave_contrib_repo] if verbose > 1: cmd.append("-{}".format('v' * (verbose - 1))) res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if res.returncode or verbose: click.echo(res.stdout) if res.returncode: click.echo('Failed to install {}.\n'.format(title)) return click.echo('Successfully installed {}.\n'.format(title))
def test_default_text_input(self): val = "value" with mock.patch("dwave.cloud.utils.input", side_effect=[val]): self.assertEqual(default_text_input("prompt", val), val) with mock.patch("dwave.cloud.utils.input", side_effect=[val]): self.assertEqual(default_text_input("prompt", val+val), val)
def test_optional_text_input(self): with mock.patch("click.termui.visible_prompt_func", side_effect=[""]): self.assertEqual(default_text_input("prompt", optional=True), None)
def test_default_text_input(self): val = "value" with mock.patch("click.termui.visible_prompt_func", side_effect=[val]): self.assertEqual(default_text_input("prompt", val), val) with mock.patch("click.termui.visible_prompt_func", side_effect=[val]): self.assertEqual(default_text_input("prompt", val + val), val)