def main(args): aserver_api = get_server_api(args.token, args.site) username, notebook = parse(args.handle) username = username or aserver_api.user()['login'] downloader = Downloader(aserver_api, username, notebook) packages_types = args.package_type or list(PACKAGE_TYPES.keys()) # Check valid package type for ty in packages_types: if ty not in list(PACKAGE_TYPES.keys()): raise Exception("Invalid package type '{}'".format(ty)) try: download_files = downloader.list_download_files(packages_types, output=args.output, force=args.force) for download_file, download_dist in download_files.items(): downloader.download(download_dist) logger.info("{} has been downloaded as {}".format( args.handle, download_file)) if has_environment(download_file): logger.info( "{} has an environment embedded.".format(download_file)) logger.info("Run:") logger.info(" conda env create {}".format(download_file)) logger.info("To install the environment in your system") except (errors.DestionationPathExists, errors.NotFound, errors.BinstarError, OSError) as err: logger.info(err)
def __init__(self, site=None, username=None, token=None, log_level=None): assert hasattr(binstar_utils, 'get_server_api'), "Please upgrade anaconda-client" if log_level is None: log_level = logging.INFO self._api = binstar_utils.get_server_api(site=site, token=token, log_level=log_level) self._user_info = None self._force_username = username
def _is_valid_output_hash(outputs): """Test if a set of outputs have valid hashes on the staging channel. Parameters ---------- outputs : dict A dictionary mapping each full qualified output in the conda index to a hash ("md5"), its name ("name"), and version ("version"). Returns ------- valid : dict A dict keyed on output name with True if it is valid and False otherwise. """ ac = get_server_api() valid = {o: False for o in outputs} for out_name, out in outputs.items(): try: data = ac.distribution( STAGING, out["name"], out["version"], basename=urllib.parse.quote(out_name, safe=""), ) valid[out_name] = hmac.compare_digest(data["md5"], out["md5"]) except BinstarError: pass return valid
def main(): token = os.environ.get('BINSTAR_TOKEN') description = ('Upload or check consistency of a built version of a ' 'conda recipe with binstar. Note: The existence of the ' 'BINSTAR_TOKEN environment variable determines ' 'whether the upload should actually take place.') parser = argparse.ArgumentParser(description=description) parser.add_argument('recipe_dir', help='the conda recipe directory') parser.add_argument('owner', help='the binstar owner/user') parser.add_argument('--channel', help='the binstar channel', default='main') args = parser.parse_args() recipe_dir, owner, channel = args.recipe_dir, args.owner, args.channel cli = get_server_api(token=token) meta_main = MetaData(recipe_dir) for _, meta in meta_main.get_output_metadata_set(files=None): print("Processing {}".format(meta.name())) if meta.skip(): print("No upload to take place - this configuration was skipped in build/skip.") continue exists = built_distribution_already_exists(cli, meta, owner) if token: if not exists: upload(cli, meta, owner, channel) print('Uploaded {}'.format(bldpkg_path(meta))) else: print('Distribution {} already \nexists for {}.' ''.format(bldpkg_path(meta), owner)) else: print("No BINSTAR_TOKEN present, so no upload is taking place. " "The distribution just built {} already available for {}." "".format('is' if exists else 'is not', owner))
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) spec = args.spec owner = spec.user package = spec.package if args.add_collaborator: collaborator = args.add_collaborator aserver_api.package_add_collaborator(owner, package, collaborator) args.add_collaborator elif args.list_collaborators: log.info(':Collaborators:') for collab in aserver_api.package_collaborators(owner, package): log.info(collab['login']) elif args.create: public = args.access != 'private' aserver_api.add_package(args.spec.user, args.spec.package, args.summary, public=public, license=args.license, license_url=args.license_url) log.info('Package created!')
def __init__(self, name=None, **kwargs): self.name = name self.quiet = False if get_server_api is not None: self.binstar = get_server_api() else: self.binstar = None
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) spec = args.spec channels = aserver_api.list_channels(spec.user) label_text = 'label' if (args.from_label and args.to_label) else 'channel' from_label = args.from_channel or args.from_label to_label = args.to_channel or args.to_label if from_label not in channels: raise errors.UserError( "{} {} does not exist\n\tplease choose from: {}".format( label_text.title(), from_label, ', '.join(channels) )) # TODO: add/replace from_channel => from_label and to_channel => to_label files = aserver_api.copy(spec.user, spec.package, spec.version, spec._basename, to_owner=args.to_owner, from_channel=from_label, to_channel=to_label) for binstar_file in files: print("Copied file: %(basename)s" % binstar_file) if files: log.info("Copied %i files" % len(files)) else: log.warning("Did not copy any files. Please check your inputs with\n\n\tanaconda show %s" % spec)
def main(): token = os.environ.get('BINSTAR_TOKEN') description = ('Upload or check consistency of a built version of a ' 'conda recipe with binstar. Note: The existence of the ' 'BINSTAR_TOKEN environment variable determines ' 'whether the upload should actually take place.') parser = argparse.ArgumentParser(description=description) parser.add_argument('recipe_dir', help='the conda recipe directory') parser.add_argument('owner', help='the binstar owner/user') parser.add_argument('--channel', help='the binstar channel', default='main') parser.add_argument( "-m", "--variant-config-files", action="append", help="path to conda_build_config.yaml defining your base matrix") args = parser.parse_args() recipe_dir, owner, channel = args.recipe_dir, args.owner, args.channel cli = get_server_api(token=token) metas = conda_build.api.render( recipe_dir, variant_config_files=args.variant_config_files) # Print the skipped distributions skipped_distributions = [m for m, _, _ in metas if m.skip()] for m in skipped_distributions: print("{} configuration was skipped in build/skip.".format(m.name())) # The list of built/not skipped distributions built_distributions = [(m, path) for m, _, _ in metas for path in conda_build.api.get_output_file_paths(m) if not m.skip()] # These are the ones that already exist on the owner channel's existing_distributions = [ path for m, path in built_distributions if built_distribution_already_exists(cli, m, path, owner) ] for d in existing_distributions: print('Distribution {} already exists for {}'.format(d, owner)) # These are the ones that are new to the owner channel's new_distributions = [ path for m, path in built_distributions if not built_distribution_already_exists(cli, m, path, owner) ] # This is the actual fix where we create the token file once and reuse it for all uploads if token: with get_temp_token(cli.token) as token_fn: for path in new_distributions: upload(token_fn, path, owner, channel) print('Uploaded {}'.format(path)) else: for path in new_distributions: print( "Distribution {} is new for {}, but no upload is taking place " "because the BINSTAR_TOKEN is missing.".format(path, owner))
def _writeLatestVersionFile(fname): import os from binstar_client.utils import get_server_api try: f = open(fname, 'w') except: print( 'Unable to open {} file for writing. Will not check for new HTMD versions.' .format(fname)) return api = get_server_api(log_level=0) try: package = api.package('acellera', 'htmd') except Exception as err: print("Failed at checking latest conda version. ({})".format( type(err).__name__)) return stable, dev, stabledeps, devdeps = _release_version(package) f.write('{} {}\n{} {}'.format(stable, ','.join(stabledeps), dev, ','.join(devdeps))) os.utime(fname, None) f.close()
def _writeLatestVersionFile(fname): import os try: f = open(fname, "w") except Exception: print( f"Unable to open {fname} file for writing. Will not check for new HTMD versions." ) return try: from binstar_client.utils import get_server_api api = get_server_api(log_level=0) package = api.package("acellera", "htmd") except Exception as err: print( f"Failed at checking latest conda version. ({type(err).__name__})") return stable, dev, stabledeps, devdeps = _release_version(package) f.write("{} {}\n{} {}".format(stable, ",".join(stabledeps), dev, ",".join(devdeps))) os.utime(fname, None) f.close()
def main(args): aserver_api = get_server_api(args.token, args.site) for spec in args.specs: try: if spec._basename: msg = 'Are you sure you want to remove file %s ?' % (spec,) if args.force or bool_input(msg, False): aserver_api.remove_dist(spec.user, spec.package, spec.version, spec.basename) else: logger.warning('Not removing file %s' % (spec)) elif spec._version: msg = 'Are you sure you want to remove the package release %s ? (and all files under it?)' % (spec,) if args.force or bool_input(msg, False): aserver_api.remove_release(spec.user, spec.package, spec.version) else: logger.warning('Not removing release %s' % (spec)) elif spec._package: msg = 'Are you sure you want to remove the package %s ? (and all data with it?)' % (spec,) if args.force or bool_input(msg, False): aserver_api.remove_package(spec.user, spec.package) else: logger.warning('Not removing release %s' % (spec)) else: logger.error('Invalid package specification: %s', spec) except errors.NotFound: if args.force: logger.warning('', exc_info=True) continue else: raise
def search_deps(self, dep, version, channels): key = "{}={}".format(dep, version) if key not in self.track_software.deps.keys(): aserver_api = get_server_api() package = None for channel in channels: try: package = aserver_api.package(channel, dep) logging.debug("Package {} exists in channel {}.".format(dep, channel)) except: logging.debug("Package {} does not exist in channel {}.".format(dep, channel)) if package: dep_obj = DepPackage(dep, version, package['summary'], channel ) self.track_software.deps[key] = dep_obj dep_obj.add_envs(self.environment) return dep_obj #must come from default or channels not defined in environment.yml dep_obj = DepPackage(dep, version, '', 'default' ) dep_obj.add_envs(self.environment) self.track_software.deps[key] = dep_obj return dep_obj else: dep_obj = self.track_software.deps[key] if self.environment not in dep_obj.envs: dep_obj.add_envs(self.environment) return dep_obj
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) for spec in args.specs: try: if spec._basename: msg = 'Are you sure you want to remove file %s ?' % (spec,) if args.force or bool_input(msg, False): aserver_api.remove_dist(spec.user, spec.package, spec.version, spec.basename) else: log.warn('Not removing file %s' % (spec)) elif spec._version: msg = 'Are you sure you want to remove the package release %s ? (and all files under it?)' % (spec,) if args.force or bool_input(msg, False): aserver_api.remove_release(spec.user, spec.package, spec.version) else: log.warn('Not removing release %s' % (spec)) elif spec._package: msg = 'Are you sure you want to remove the package %s ? (and all data with it?)' % (spec,) if args.force or bool_input(msg, False): aserver_api.remove_package(spec.user, spec.package) else: log.warn('Not removing release %s' % (spec)) else: log.error('Invalid package specification: %s', spec) except errors.NotFound: if args.force: log.warn('', exc_info=True) continue else: raise
def search_deps(self, dep, version, channels): key = "{}={}".format(dep, version) if key not in self.track_software.deps.keys(): aserver_api = get_server_api() packages = aserver_api.search(dep) for package in packages: if package['owner'] in channels and package['name'] == dep: dep_obj = DepPackage(dep, version, package['summary'], package['owner']) self.track_software.deps[key] = dep_obj dep_obj.add_envs(self.environment) return dep_obj #must come from default or channels not defined in environment.yml dep_obj = DepPackage(dep, version, '', 'default') dep_obj.add_envs(self.environment) self.track_software.deps[key] = dep_obj return dep_obj else: dep_obj = self.track_software.deps[key] if self.environment not in dep_obj.envs: dep_obj.add_envs(self.environment) return dep_obj
def upload_or_check(recipe_dir, owner, channel, variant): token = os.environ.get('BINSTAR_TOKEN') # Azure's tokens are filled when in PR and not empty as for the other cis # In pr they will have a value like '$(secret-name)' if token and token.startswith('$('): token = None cli = get_server_api(token=token) additional_config = {} for v in variant: variant_dir, base_name = os.path.split(v) clobber_file = os.path.join(variant_dir, 'clobber_' + base_name) if os.path.exists(clobber_file): additional_config = {'clobber_sections_file': clobber_file} break metas = conda_build.api.render(recipe_dir, variant_config_files=variant, **additional_config) # Print the skipped distributions skipped_distributions = [m for m, _, _ in metas if m.skip()] for m in skipped_distributions: print("{} configuration was skipped in build/skip.".format(m.name())) # The list of built/not skipped distributions built_distributions = [(m, path) for m, _, _ in metas for path in conda_build.api.get_output_file_paths(m) if not m.skip()] # These are the ones that already exist on the owner channel's existing_distributions = [ path for m, path in built_distributions if built_distribution_already_exists(cli, m, path, owner) ] for d in existing_distributions: print('Distribution {} already exists for {}'.format(d, owner)) # These are the ones that are new to the owner channel's new_distributions = [ path for m, path in built_distributions if not built_distribution_already_exists(cli, m, path, owner) ] # This is the actual fix where we create the token file once and reuse it for all uploads if token: with get_temp_token(cli.token) as token_fn: for path in new_distributions: upload(token_fn, path, owner, channel) print('Uploaded {}'.format(path)) return True else: for path in new_distributions: print( "Distribution {} is new for {}, but no upload is taking place " "because the BINSTAR_TOKEN is missing.".format(path, owner)) return False
def search(args): aserver_api = get_server_api(args.token, args.site, args.log_level) log.info("Run 'anaconda show <USER/PACKAGE>' to get more details:") packages = aserver_api.search(args.name, package_type=args.package_type) pprint_packages(packages, access=False) log.info("Found %i packages" % len(packages))
def search(args): aserver_api = get_server_api(args.token, args.site) packages = aserver_api.search(args.name, package_type=args.package_type, platform=args.platform) pprint_packages(packages, access=False) logger.info("Found %i packages" % len(packages)) logger.info("\nRun 'anaconda show <USER/PACKAGE>' to get installation details")
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) if args.info: data = aserver_api.authentication() log.info('Name: %s' % data['application']) log.info('Id: %s' % data['id']) if args.list: show_auths(aserver_api.authentications()) return elif args.remove: for auth_name in args.remove: aserver_api.remove_authentication(auth_name, args.organization) log.info("Removed token %s" % auth_name) return elif args.list_scopes: scopes = aserver_api.list_scopes() for key in sorted(scopes): log.info(key) log.info(' ' + scopes[key]) log.info('') log.info(SCOPE_EXAMPLES) elif args.create: try: current_user = aserver_api.user() username = current_user['login'] except: current_user = None sys.stderr.write('Username: '******'') scopes = [scope for scopes in args.scopes for scope in scopes.split()] if not scopes: log.warn("You have not specified the scope of this token with the '--scopes' argument.") log.warn("This token will grant full access to %s's account" % (args.organization or username)) log.warn("Use the --list-scopes option to see a listing of your options") for _ in range(3): try: sys.stderr.write("Please re-enter %s's " % username) password = getpass.getpass() token = aserver_api.authenticate(username, password, args.name, application_url=args.url, scopes=scopes, for_user=args.organization, max_age=args.max_age, created_with=' '.join(sys.argv), strength=args.strength, fail_if_already_exists=True) args.out.write(token) break except errors.Unauthorized: log.error('Invalid Username password combination, please try again') continue
def main(args): aserver_api = get_server_api(args.token, args.site) aserver_api.check_server() if args.user: username = args.user else: user = aserver_api.user() username = user['login'] uploaded_packages = [] uploaded_projects = [] # Flatten file list because of 'windows_glob' function files = [f for fglob in args.files for f in fglob] if args.all: files += get_convert_files(files) for filename in files: if not exists(filename): message = 'file %s does not exist' % (filename) logger.error(message) raise errors.BinstarError(message) package_type = determine_package_type(filename, args) if package_type == 'project': uploaded_projects.append(upload_project(filename, args, username)) else: if package_type == 'ipynb' and not args.mode == 'force': try: nbformat.read(open(filename), nbformat.NO_CONVERT) except Exception as error: logger.error("Invalid notebook file '%s': %s", filename, error) logger.info("Use --force to upload the file anyways") continue package_info = upload_package(filename, package_type=package_type, aserver_api=aserver_api, username=username, args=args) if package_info: uploaded_packages.append(package_info) for package, upload_info in uploaded_packages: package_url = upload_info.get( 'url', 'https://anaconda.org/%s/%s' % (username, package)) logger.info("{} located at:\n{}\n".format( verbose_package_type(package_type), package_url)) for project_name, url in uploaded_projects: logger.info("Project {} uploaded to {}.\n".format(project_name, url))
def main(args): aserver_api = get_server_api(args.token, args.site) spec = args.spec if spec._basename: dist = aserver_api.distribution(spec.user, spec.package, spec.version, spec.basename) logger.info(dist.pop('basename')) logger.info(dist.pop('description') or 'no description') logger.info('') metadata = dist.pop('attrs', {}) for key_value in dist.items(): logger.info('%-25s: %r' % key_value) logger.info('Metadata:') for key_value in metadata.items(): logger.info(' + %-25s: %r' % key_value) elif args.spec._version: logger.info('version %s' % spec.version) release = aserver_api.release(spec.user, spec.package, spec.version) for dist in release['distributions']: logger.info(' + %(basename)s' % dist) logger.info('%s' % release.get('public_attrs', {}).get('description')) elif args.spec._package: package = aserver_api.package(spec.user, spec.package) package['access'] = 'public' if package['public'] else 'private' logger.info('Name: %(name)s' % package) logger.info('Summary: %(summary)s' % package) logger.info('Access: %(access)s' % package) logger.info('Package Types: %s' % ', '.join(package.get('package_types'))) logger.info('Versions:' % package) for release in package['releases']: logger.info(' + %(version)s' % release) logger.info('') for package_type in package.get('package_types'): install_info(package, package_type) if not package['public']: logger.info('To generate a $TOKEN run:') logger.info( ' TOKEN=$(anaconda auth --create --name <TOKEN-NAME>)') elif args.spec._user: user_info = aserver_api.user(spec.user) pprint_user(user_info) pprint_packages(aserver_api.user_packages(spec.user)) if user_info['user_type'] == 'user': pprint_orgs(aserver_api.user_orgs(spec.user)) else: logger.info(args.spec)
def main(args): aserver_api = get_server_api(args.token, args.site) try: user = aserver_api.user() except errors.Unauthorized as err: logger.debug(err) logger.info('Anonymous User') return 1 pprint_user(user)
def main(args): aserver_api = get_server_api(args.token, args.site) spec = args.spec if spec._basename: dist = aserver_api.distribution(spec.user, spec.package, spec.version, spec.basename) logger.info(dist.pop('basename')) logger.info(dist.pop('description') or 'no description') logger.info('') metadata = dist.pop('attrs', {}) for key_value in dist.items(): logger.info('%-25s: %r' % key_value) logger.info('Metadata:') for key_value in metadata.items(): logger.info(' + %-25s: %r' % key_value) elif args.spec._version: logger.info('version %s' % spec.version) release = aserver_api.release(spec.user, spec.package, spec.version) for dist in release['distributions']: logger.info(' + %(basename)s' % dist) logger.info('%s' % release.get('public_attrs', {}).get('description')) elif args.spec._package: package = aserver_api.package(spec.user, spec.package) package['access'] = 'public' if package['public'] else 'private' logger.info('Name: %(name)s' % package) logger.info('Summary: %(summary)s' % package) logger.info('Access: %(access)s' % package) logger.info('Package Types: %s' % ', '.join(package.get('package_types'))) logger.info('Versions:' % package) for release in package['releases']: logger.info(' + %(version)s' % release) logger.info('') for package_type in package.get('package_types'): install_info(package, package_type) if not package['public']: logger.info('To generate a $TOKEN run:') logger.info(' TOKEN=$(anaconda auth --create --name <TOKEN-NAME>)') elif args.spec._user: user_info = aserver_api.user(spec.user) pprint_user(user_info) pprint_packages(aserver_api.user_packages(spec.user)) if user_info['user_type'] == 'user': pprint_orgs(aserver_api.user_orgs(spec.user)) else: logger.info(args.spec)
def upload(args): aserver_api = get_server_api(args.token, args.site, args.log_level) uploader = Uploader(aserver_api, args.notebook, user=args.user, summary=args.summary, version=args.version, thumbnail=args.thumbnail, name=args.name) try: upload_info = uploader.upload(force=args.force) log.info("{} has been uploaded.".format(args.notebook)) log.info("You can visit your notebook at {}".format(notebook_url(upload_info))) except (errors.BinstarError, IOError) as e: log.error(str(e))
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) spec = args.spec if spec._basename: dist = aserver_api.distribution(spec.user, spec.package, spec.version, spec.basename) log.info(dist.pop("basename")) log.info(dist.pop("description") or "no description") log.info("") metadata = dist.pop("attrs", {}) for key_value in dist.items(): log.info("%-25s: %r" % key_value) log.info("Metadata:") for key_value in metadata.items(): log.info(" + %-25s: %r" % key_value) elif args.spec._version: log.info("version %s" % spec.version) release = aserver_api.release(spec.user, spec.package, spec.version) for dist in release["distributions"]: log.info(" + %(basename)s" % dist) log.info("%s" % release.get("public_attrs", {}).get("description")) elif args.spec._package: package = aserver_api.package(spec.user, spec.package) package["access"] = "public" if package["public"] else "private" log.info("Name: %(name)s" % package) log.info("Summary: %(summary)s" % package) log.info("Access: %(access)s" % package) log.info("Package Types: %s" % ", ".join(package.get("package_types"))) log.info("Versions:" % package) for release in package["releases"]: log.info(" + %(version)s" % release) log.info("") for package_type in package.get("package_types"): install_info(package, package_type) if not package["public"]: log.info("To generate a $TOKEN run:") log.info(" TOKEN=$(anaconda auth --create --name <TOKEN-NAME>)") elif args.spec._user: user_info = aserver_api.user(spec.user) pprint_user(user_info) pprint_packages(aserver_api.user_packages(spec.user)) if user_info["user_type"] == "user": pprint_orgs(aserver_api.user_orgs(spec.user)) else: log.info(args.spec)
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) if args.action == 'add': result = aserver_api.add_group(args.spec['org'], args.spec['group_name'], args.perms) pprint(result) elif args.action == 'show': if args.spec['group_name']: result = aserver_api.group(args.spec['org'], args.spec['group_name']) pprint(result) else: result = aserver_api.groups(args.spec['org']) pprint(result) elif args.action == 'members': if not args.spec['group_name']: raise ArgumentError('must specify group_name in spec') result = aserver_api.group_members(args.spec['org'], args.spec['group_name']) user_list(result, args.verbose) elif args.action == 'add_member': if not args.spec['group_name']: raise ArgumentError('must specify group_name in spec') if not args.spec['member']: raise ArgumentError('must specify group_name in spec') aserver_api.add_group_member(args.spec['org'], args.spec['group_name'], args.spec['member']) elif args.action == 'remove_member': if not args.spec['group_name']: raise ArgumentError('must specify group_name in spec') if not args.spec['member']: raise ArgumentError('must specify group_name in spec') aserver_api.remove_group_member(args.spec['org'], args.spec['group_name'], args.spec['member']) elif args.action == 'packages': if not args.spec['group_name']: raise ArgumentError('must specify group_name in spec') result = aserver_api.group_packages(args.spec['org'], args.spec['group_name']) package_list(result, args.verbose) elif args.action == 'add_package': if not args.spec['group_name']: raise ArgumentError('must specify group_name in spec') if not args.spec['member']: raise ArgumentError('must specify group_name in spec') aserver_api.add_group_package(args.spec['org'], args.spec['group_name'], args.spec['member']) elif args.action == 'remove_package': if not args.spec['group_name']: raise ArgumentError('must specify group_name in spec') if not args.spec['member']: raise ArgumentError('must specify group_name in spec') aserver_api.remove_group_package(args.spec['org'], args.spec['group_name'], args.spec['member']) else: raise NotImplementedError(args.action)
def upload(args): aserver_api = get_server_api(args.token, args.site) uploader = Uploader(aserver_api, args.notebook, user=args.user, summary=args.summary, version=args.version, thumbnail=args.thumbnail, name=args.name) try: upload_info = uploader.upload(force=args.force) logger.warning("`anaconda notebook` is going to be deprecated") logger.warning("use `anaconda upload` instead.") logger.info("{} has been uploaded.".format(args.notebook)) logger.info("You can visit your notebook at {}".format(notebook_url(upload_info))) except (errors.BinstarError, IOError) as e: logger.error(str(e))
def sync(from_channel, to_channel, package, token, exact_version=None, from_label='main', to_label='main'): """ Sync all versions of a package from a conda channel to another conda channel. """ print("Syncing {0} from {1} to {2}".format(package, from_channel, to_channel)) # Get an API object to interact with anaconda.org api = get_server_api(token=token) # Find out which versions are available from origin package_orig = api.package(from_channel, package) versions_orig = [(x['version'], x['basename']) for x in package_orig['files'] if from_label in x['labels']] # Find out which versions are available from destination try: package_dest = api.package(to_channel, package) versions_dest = [(x['version'], x['basename']) for x in package_dest['files'] if to_label in x['labels']] except NotFound: versions_dest = [] # Find which ones need to be synced versions_sync = set(versions_orig) - set(versions_dest) # Copy over for version, basename in versions_sync: if exact_version is not None and version != exact_version: continue print(' -> copying {0} from {1} [{2}] to {3} [{4}]...'.format( basename, from_channel, from_label, to_channel, to_label)) api.copy(from_channel, package, version, basename=basename, to_owner=to_channel, from_label=from_label, to_label=to_label)
def __init__(self, name, content): self.aserver_api = get_server_api() self.name = parameterize(name) self.content = content self.summary = self.metadata.get("summary", "Jupyter Notebook") self.username = self.metadata.get("organization", None) if self.metadata.get("attach-environment", None): self.env_name = self.metadata.get("environment", None) if self.env_name is None: self.env_name = self.default_env() else: self.env_name = None if self.username is None: self.username = self.aserver_api.user()['login']
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) username, notebook = parse(args.handle) username = username or aserver_api.user()['login'] downloader = Downloader(aserver_api, username, notebook) try: download_info = downloader(output=args.output, force=args.force) log.info("{} has been downloaded as {}.".format(args.handle, download_info[0])) if has_environment(download_info[0]): log.info("{} has an environment embedded.".format(download_info[0])) log.info("Run:") log.info(" conda env create {}".format(download_info[0])) log.info("To install the environment in your system") except (errors.DestionationPathExists, errors.NotFound, errors.BinstarError, OSError) as err: log.info(err.msg)
def main(args): aserver_api = get_server_api(args.token, args.site) if aserver_api.token: # TODO: named 'application' because I was using the github model # Change it to name once we release the latest version of binstar server try: aserver_api.remove_authentication() except errors.Unauthorized as err: logger.debug("The token that you are trying to remove may not be valid" "{}".format(err)) remove_token(args) logger.info("logout successful") else: logger.info("You are not logged in")
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) if aserver_api.token: # TODO: named 'application' because I was using the github model # Change it to name once we release the latest version of binstar server try: aserver_api.remove_authentication() except errors.Unauthorized as err: log.debug("The token that you are trying to remove may not be valid" "{}".format(err)) remove_token(args) log.info("logout successful") else: log.info("You are not logged in")
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) spec = args.spec action = args.action verbose = args.log_level == logging.DEBUG if action == 'add': aserver_api.add_group(spec.org, spec.group_name, args.perms) print('Created the group %s' % (spec, )) elif action == 'show': if spec._group_name: result = aserver_api.group(spec.org, spec.group_name) pprint(result) else: result = aserver_api.groups(spec.org) pprint(result) elif action == 'members': result = aserver_api.group_members(spec.org, spec.group_name) user_list(result, verbose) elif action == 'add_member': aserver_api.add_group_member(spec.org, spec.group_name, spec.member) print( 'Added the user "{spec.member}" to the group "{spec.org}/{spec.group_name}"' .format(spec=spec)) elif action == 'remove_member': aserver_api.remove_group_member(spec.org, spec.group_name, spec.member) print( 'Removed the user "{spec.member}" from the group "{spec.org}/{spec.group_name}"' .format(spec=spec)) elif action == 'packages': result = aserver_api.group_packages(spec.org, spec.group_name) package_list(result, verbose) elif action == 'add_package': aserver_api.add_group_package(spec.org, spec.group_name, spec.member) print( 'Added the package "{spec.member}" to the group "{spec.org}/{spec.group_name}"' .format(spec=spec)) elif action == 'remove_package': aserver_api.remove_group_package(spec.org, spec.group_name, spec.member) print( 'Removed the package "{spec.member}" from the group "{spec.org}/{spec.group_name}"' .format(spec=spec)) else: raise NotImplementedError(args.action)
def main(args): aserver_api = get_server_api(args.token, args.site) spec = args.spec channels = aserver_api.list_channels(spec.user) label_text = 'label' if (args.from_label and args.to_label) else 'channel' from_label = args.from_label.lower() to_label = args.to_label.lower() if from_label not in channels: raise errors.UserError( "{} {} does not exist\n\tplease choose from: {}".format( label_text.title(), from_label, ', '.join(channels) )) if from_label == to_label: raise errors.UserError('--from-label and --to-label must be different') # Add files to to_label try: aserver_api.add_channel( to_label, spec.user, package=spec.package, version=spec._version, filename=spec._basename, ) except Exception: pass # Remove files from from_label try: aserver_api.remove_channel( from_label, spec.user, package=spec.package, version=spec._version, filename=spec._basename, ) except Exception: pass
def upload(args): aserver_api = get_server_api(args.token, args.site, args.log_level) uploader = Uploader(aserver_api, args.notebook, user=args.user, summary=args.summary, version=args.version, thumbnail=args.thumbnail, name=args.name) try: upload_info = uploader.upload(force=args.force) log.info("{} has been uploaded.".format(args.notebook)) log.info("You can visit your notebook at {}".format( notebook_url(upload_info))) except (errors.BinstarError, IOError) as e: log.error(str(e))
def download(args): aserver_api = get_server_api(args.token, args.site, args.log_level) username, notebook = parse(args.handle) username = username or aserver_api.user()['login'] downloader = Downloader(aserver_api, username, notebook) try: download_info = downloader(output=args.output, force=args.force) log.info("{} has been downloaded as {}.".format( args.handle, download_info[0])) if has_environment(download_info[0]): log.info("{} has an environment embedded.".format( download_info[0])) log.info("Run:") log.info(" conda env create {}".format(download_info[0])) log.info("To install the environment in your system") except (errors.DestionationPathExists, errors.NotFound, OSError) as err: log.info(err.msg)
def _release_version(user, package): import requests from binstar_client.utils import get_server_api api = get_server_api() package = api.package(user, package) versionlist = package['versions'] laststable = None lastdev = None for ver in versionlist[::-1]: # Iterate in reverse due to sorting of conda versions if _is_stable(ver): laststable = ver else: lastdev = ver if laststable and lastdev: break return laststable, lastdev
def main(args, name, deprecated=False): aserver_api = get_server_api(args.token, args.site, args.log_level) if args.organization: owner = args.organization else: current_user = aserver_api.user() owner = current_user['login'] if deprecated: log.warn('channel command is deprecated in favor of label') if args.copy: aserver_api.copy_channel(args.copy[0], owner, args.copy[1]) log.info("Copied {} {} to {}".format(name, *tuple(args.copy))) elif args.remove: aserver_api.remove_channel(args.remove, owner) log.info("Removed {} {}".format(name, args.remove)) elif args.list: log.info('{}s'.format(name.title())) for channel, info in aserver_api.list_channels(owner).items(): if isinstance(info, int): # OLD API log.info((' + %s ' % channel)) else: log.info((' + %s ' % channel) + ('[locked]' if info['is_locked'] else '')) elif args.show: info = aserver_api.show_channel(args.show, owner) log.info('{} {} {}'.format( name.title(), args.show, ('[locked]' if info['is_locked'] else '') )) for f in info['files']: log.info(' + %(full_name)s' % f) elif args.lock: aserver_api.lock_channel(args.lock, owner) log.info("{} {} is now locked".format(name.title(), args.lock)) elif args.unlock: aserver_api.unlock_channel(args.unlock, owner) log.info("{} {} is now unlocked".format(name.title(), args.unlock)) else: raise NotImplementedError()
def check_for_omitted_packages(): """ Return a list of any affiliated packages not listed in requirements """ pkg_list = requests.get(AFFILIATED_PACKAGES_LIST).json() with open(REQUIREMENTS, 'rt') as f: reqs_list = yaml.safe_load(f) packge_list_names = set( [p['pypi_name'].lower() for p in pkg_list['packages']]) requirements_names = set([r['name'].lower() for r in reqs_list]) # Construct list of packages in the registry that are not in the astropy # conda-forge channel. missing = packge_list_names - requirements_names api = get_server_api() add_to_requirements = [] make_recipe = [] # Check whether missing packages are already on conda-forge for package in sorted(missing): try: api.package('conda-forge', package) except NotFound: on_conda_forge = False else: on_conda_forge = True if on_conda_forge: add_to_requirements.append(package) else: make_recipe.append(package) if add_to_requirements: print("\n\nCopy/paste this into requirements.yml:\n\n") print("\n\n".join( [f"- name: {package}" for package in add_to_requirements])) if make_recipe: print("\n\nMake a new conda recipe on conda-forge for each of these:") print("\n".join(make_recipe)) print("\n\n")
def upload(args): aserver_api = get_server_api(args.token, args.site) uploader = Uploader(aserver_api, args.notebook, user=args.user, summary=args.summary, version=args.version, thumbnail=args.thumbnail, name=args.name) try: upload_info = uploader.upload(force=args.force) logger.warning("`anaconda notebook` is going to be deprecated") logger.warning("use `anaconda upload` instead.") logger.info("{} has been uploaded.".format(args.notebook)) logger.info("You can visit your notebook at {}".format( notebook_url(upload_info))) except (errors.BinstarError, IOError) as e: logger.error(str(e))
def _release_version(user, package): import requests from binstar_client.utils import get_server_api api = get_server_api() package = api.package(user, package) versionlist = package['versions'] laststable = None lastdev = None for ver in versionlist[:: -1]: # Iterate in reverse due to sorting of conda versions if _is_stable(ver): laststable = ver else: lastdev = ver if laststable and lastdev: break return laststable, lastdev
def _writeLatestVersionFile(fname): import os from binstar_client.utils import get_server_api try: f = open(fname, 'w') except: print('Unable to open {} file for writing. Will not check for new HTMD versions.'.format(fname)) return api = get_server_api(log_level=0) try: package = api.package('acellera', 'htmd') except Exception as err: print("Failed at checking latest conda version. ({})".format(type(err).__name__)) return stable, dev, stabledeps, devdeps = _release_version(package) f.write('{} {}\n{} {}'.format(stable, ','.join(stabledeps), dev, ','.join(devdeps))) os.utime(fname, None) f.close()
def main(args): aserver_api = get_server_api(args.token, args.site) spec = args.spec action = args.action verbose = args.log_level == logging.DEBUG if action == 'add': aserver_api.add_group(spec.org, spec.group_name, args.perms) logger.info('Created the group %s', spec) elif action == 'show': if spec._group_name: result = aserver_api.group(spec.org, spec.group_name) else: result = aserver_api.groups(spec.org) logger.info(pformat(result)) elif action == 'members': result = aserver_api.group_members(spec.org, spec.group_name) logger.info(user_list(result, verbose)) elif action == 'add_member': aserver_api.add_group_member(spec.org, spec.group_name, spec.member) logger.info('Added the user "%s" to the group "%s/%s"', spec.member, spec.org, spec.group_name) elif action == 'remove_member': aserver_api.remove_group_member(spec.org, spec.group_name, spec.member) logger.info('Removed the user "%s" from the group "%s/%s"', spec.member, spec.org, spec.group_name) elif action == 'packages': result = aserver_api.group_packages(spec.org, spec.group_name) logger.info(package_list(result, verbose)) elif action == 'add_package': aserver_api.add_group_package(spec.org, spec.group_name, spec.member) logger.info('Added the package "%s" to the group "%s/%s"', spec.member, spec.org, spec.group_name) elif action == 'remove_package': aserver_api.remove_group_package(spec.org, spec.group_name, spec.member) logger.info('Removed the package "%s" to the group "%s/%s"', spec.member, spec.org, spec.group_name) else: raise NotImplementedError(args.action)
def main(args): aserver_api = get_server_api(args.token, args.site) spec = args.spec owner = spec.user package = spec.package if args.add_collaborator: collaborator = args.add_collaborator aserver_api.package_add_collaborator(owner, package, collaborator) args.add_collaborator elif args.list_collaborators: logger.info(':Collaborators:') for collab in aserver_api.package_collaborators(owner, package): logger.info(collab['login']) elif args.create: public = args.access != 'private' aserver_api.add_package(args.spec.user, args.spec.package, args.summary, public=public, license=args.license, license_url=args.license_url) logger.info('Package created!')
def main(args): aserver_api = get_server_api(args.token, args.site) username, notebook = parse(args.handle) username = username or aserver_api.user()['login'] downloader = Downloader(aserver_api, username, notebook) packages_types = args.package_type or list(PACKAGE_TYPES.keys()) # Check valid package type for ty in packages_types: if ty not in list(PACKAGE_TYPES.keys()): raise Exception("Invalid package type '{}'".format(ty)) try: download_files = downloader.list_download_files(packages_types, output=args.output, force=args.force) for download_file, download_dist in download_files.items(): downloader.download(download_dist) logger.info("{} has been downloaded as {}".format(args.handle, download_file)) if has_environment(download_file): logger.info("{} has an environment embedded.".format(download_file)) logger.info("Run:") logger.info(" conda env create {}".format(download_file)) logger.info("To install the environment in your system") except (errors.DestionationPathExists, errors.NotFound, errors.BinstarError, OSError) as err: logger.info(err)
def binstar(self): if self._binstar is None: self._binstar = get_server_api() return self._binstar
def __init__(self): self._user = None self.aserver_api = get_server_api()
def interactive_get_token(args, fail_if_already_exists=True): bs = get_server_api(args.token, args.site, args.log_level) config = get_config(remote_site=args.site) token = None # This function could be called from a totally different CLI, so we don't # know if the attribute hostname exists. hostname = getattr(args, 'hostname', platform.node()) site = args.site or config.get('default_site') url = config.get('url', 'https://api.anaconda.org') auth_name = 'binstar_client:' if site and site != 'binstar': # For testing with binstar alpha site auth_name += '%s:' % site auth_name += '%s@%s' % (getpass.getuser(), hostname) auth_type = bs.authentication_type() if auth_type == 'kerberos': token = try_replace_token( bs.krb_authenticate, application=auth_name, application_url=url, created_with=' '.join(sys.argv), fail_if_already_exists=fail_if_already_exists, hostname=hostname, ) if token is None: raise errors.BinstarError( 'Unable to authenticate via Kerberos. Try refreshing your ' 'authentication using `kinit`') else: if getattr(args, 'login_username', None): username = args.login_username else: username = input('Username: '******'login_password', None) for _ in range(3): try: sys.stderr.write("%s's " % username) if password is None: password = getpass.getpass(stream=sys.stderr) token = try_replace_token( bs.authenticate, username=username, password=password, application=auth_name, application_url=url, created_with=' '.join(sys.argv), fail_if_already_exists=fail_if_already_exists, hostname=hostname, ) break except errors.Unauthorized: log.error('Invalid Username password combination, please try again') password = None continue if token is None: parsed_url = urlparse(url) if parsed_url.netloc.startswith('api.anaconda.org'): netloc = 'anaconda.org' else: netloc = parsed_url.netloc hostparts = (parsed_url.scheme, netloc) msg = ('Sorry. Please try again ' + \ '(go to %s://%s/account/forgot_password ' % hostparts + \ 'to reset your password)') raise errors.BinstarError(msg) return token
def main(args): config = get_config(site=args.site) aserver_api = get_server_api(token=args.token, site=args.site, config=config) aserver_api.check_server() validate_username = True if args.user: username = args.user elif 'upload_user' in config: username = config['upload_user'] else: validate_username = False user = aserver_api.user() username = user['login'] logger.info('Using "%s" as upload username', username) if validate_username: try: aserver_api.user(username) except errors.NotFound: message = 'User "{}" does not exist'.format(username) logger.error(message) raise errors.BinstarError(message) uploaded_packages = [] uploaded_projects = [] # Flatten file list because of 'windows_glob' function files = [f for fglob in args.files for f in fglob] if args.all: files += get_convert_files(files) for filename in files: if not exists(filename): message = 'File "{}" does not exist'.format(filename) logger.error(message) raise errors.BinstarError(message) else: logger.info("Processing '%s'", filename) package_type = determine_package_type(filename, args) if package_type == 'project': uploaded_projects.append(upload_project(filename, args, username)) else: if package_type == 'ipynb' and not args.mode == 'force': try: nbformat.read(open(filename), nbformat.NO_CONVERT) except Exception as error: logger.error("Invalid notebook file '%s': %s", filename, error) logger.info("Use --force to upload the file anyways") continue package_info = upload_package( filename, package_type=package_type, aserver_api=aserver_api, username=username, args=args) if package_info is not None and len(package_info) == 2: _package, _upload_info = package_info if _upload_info: uploaded_packages.append(package_info) for package, upload_info in uploaded_packages: package_url = upload_info.get('url', 'https://anaconda.org/%s/%s' % (username, package)) logger.info("{} located at:\n{}\n".format(verbose_package_type(package_type), package_url)) for project_name, url in uploaded_projects: logger.info("Project {} uploaded to {}.\n".format(project_name, url))
#!/usr/bin/env python3 # (c) 2015-2017 Acellera Ltd http://www.acellera.com # All Rights Reserved # Distributed under HTMD Software License Agreement # No redistribution in whole or part # import os from subprocess import call from binstar_client.utils import get_server_api api = get_server_api() os.chdir('/tmp') # Add packages to sync in this list here packages = [ ['omnia', 'fftw3f'], ['omnia', 'openmm'], ['omnia', 'parmed'], ['omnia', 'ambermini'], ['omnia', 'bhmm'], ['omnia', 'funcsigs'], ['omnia', 'mdtraj'], ['conda-forge', 'msmtools'], ['openbabel', 'openbabel'], ['omnia', 'pint'], ['conda-forge', 'progress_reporter'], ['conda-forge', 'pyemma'],
def main(args): aserver_api = get_server_api(args.token, args.site, args.log_level) if args.user: username = args.user else: user = aserver_api.user() username = user['login'] uploaded_packages = [] # Flatten file list because of 'windows_glob' function files = [f for fglob in args.files for f in fglob] for filename in files: if not exists(filename): raise errors.BinstarError('file %s does not exist' % (filename)) package_type = determine_package_type(filename, args) log.info('extracting package attributes for upload ...') sys.stdout.flush() try: package_attrs, release_attrs, file_attrs = get_attrs(package_type, filename, parser_args=args) except Exception: if args.show_traceback: raise raise errors.BinstarError('Trouble reading metadata from %r. Is this a valid %s package' % (filename, package_type)) if args.build_id: file_attrs['attrs']['binstar_build'] = args.build_id log.info('done') package_name = get_package_name(args, package_attrs, filename, package_type) version = get_version(args, release_attrs, package_type) add_package(aserver_api, args, username, package_name, package_attrs, package_type) add_release(aserver_api, args, username, package_name, version, release_attrs) binstar_package_type = file_attrs.pop('binstar_package_type', package_type) with open(filename, 'rb') as fd: log.info('\nUploading file %s/%s/%s/%s ... ' % (username, package_name, version, file_attrs['basename'])) sys.stdout.flush() if remove_existing_file(aserver_api, args, username, package_name, version, file_attrs): continue try: upload_info = aserver_api.upload(username, package_name, version, file_attrs['basename'], fd, binstar_package_type, args.description, dependencies=file_attrs.get('dependencies'), attrs=file_attrs['attrs'], channels=args.labels, callback=upload_print_callback(args)) except errors.Conflict: full_name = '%s/%s/%s/%s' % (username, package_name, version, file_attrs['basename']) log.info('Distribution already exists. Please use the -i/--interactive or --force options or `anaconda remove %s`' % full_name) raise except requests_ext.OpenSslError: requests_ext.warn_openssl() if args.show_traceback != 'never': raise else: raise errors.BinstarError('Could not upload package') uploaded_packages.append([package_name, upload_info]) log.info("\n\nUpload(s) Complete\n") for package, upload_info in uploaded_packages: package_url = upload_info.get('url', 'https://anaconda.org/%s/%s' % (username, package)) log.info("Package located at:\n%s\n" % package_url)
def interactive_get_token(args, fail_if_already_exists=True): bs = get_server_api(args.token, args.site, args.log_level) config = get_config(remote_site=args.site) url = config.get('url', 'https://api.anaconda.org') parsed_url = urlparse(url) token = None hostname = getattr(args, 'hostname', platform.node()) if getattr(args, 'login_username', None): username = args.login_username else: username = input('Username: '******'binstar_client:' site = args.site or config.get('default_site') if site and site != 'binstar': # For testing with binstar alpha site auth_name += '%s:' % site auth_name += '%s@%s' % (getpass.getuser(), hostname) password = getattr(args, 'login_password', None) for _ in range(3): try: sys.stderr.write("%s's " % username) if password is None: password = getpass.getpass(stream=sys.stderr) token = bs.authenticate(username, password, auth_name, url, created_with=' '.join(sys.argv), fail_if_already_exists=fail_if_already_exists, hostname=hostname) break except errors.Unauthorized: log.error('Invalid Username password combination, please try again') password = None continue except errors.BinstarError as err: if fail_if_already_exists is True and err.args[1] == 400: log.warn('It appears you are already logged in from host %s' % socket.gethostname()) log.warn('Logging in again will remove the previous token. ' ' (This could cause troubles with virtual machines with the same hostname)') log.warn('Otherwise you can login again and specify a ' 'different hostname with "--hostname"') if bool_input("Would you like to continue"): fail_if_already_exists = False continue else: raise if token is None: if parsed_url.netloc.startswith('api.anaconda.org'): netloc = 'anaconda.org' else: netloc = parsed_url.netloc hostparts = (parsed_url.scheme, netloc) msg = ('Sorry. Please try again ' + \ '(go to %s://%s/account/forgot_password ' % hostparts + \ 'to reset your password)') raise errors.BinstarError(msg) return token