def push(slug): """ \b Push a frozen minus80 dataset to the cloud. \b Positional Arguments: <slug> - A slug of a frozen minus80 dataset """ cloud = m80.CloudData() try: cloud.user except UserNotLoggedInError as e: click.secho("Please log in to use this feature") try: dtype,name,tag = minus80.Tools.parse_slug(slug) if tag is None: raise TagInvalidError() except (TagInvalidError, FreezableNameInvalidError): click.echo( f'Please provide a valid tag in "{slug}"' ) return 0 # Make sure that the dataset is available if not minus80.Tools.available(dtype,name): click.echo( f'"{dtype}.{name}" not in minus80 datasets! ' 'check available datasets with the list command' ) return 0 else: try: cloud.push(dtype, name, tag) except TagDoesNotExistError as e: click.echo(f'tag "{tag}" does not exist for {dtype}.{name}')
def list(name): '''List available datasets''' cloud = m80.CloudData() cloud.list( dtype='HapDab', name=name, raw=False )
def remove(name): ''' Delete a HapDab dataset from the cloud. ''' cloud = m80.CloudData() cloud.remove( 'HapDab', name, raw=False )
def pull(name,output): ''' Pull a HapDab dataset from the cloud. ''' cloud = m80.CloudData() cloud.pull( 'HapDab', name, raw=False, output=output )
def push(dtype, name, raw): ''' \b Push a minus80 dataset in the cloud. \b Positional Arguments: <dtype> - the data type of the m80 dataset or a raw file description (e.g. Cohort). <name> - the name of the m80 dataset or raw filename if --raw is set. ''' cloud = m80.CloudData() cloud.push(dtype, name, raw=raw)
def push(name): ''' \b Push a HapDab dataset to the cloud. \b Positional Arguments: <name> - the name of the m80 dataset or raw filename if --raw is set. ''' cloud = m80.CloudData() cloud.push( 'HapDab', name, raw=False )
def pull(slug): """ \b Pull a frozen minus80 dataset from the cloud. \b Positional Arguments: <slug> - The slug of the frozen minus80 dataset (e.g. Project.foo:v1) """ cloud = m80.CloudData() try: cloud.user except UserNotLoggedInError: click.secho("Please log in to use this feature") return 1 try: dtype, name, tag = FreezableAPI.parse_slug(slug) if tag is None: raise TagInvalidError() except (TagInvalidError, FreezableNameInvalidError): click.echo(f'Please provide a valid tag in "{slug}"') return 1 # Pull the files and tag from the cloud try: # run the push method in an event loop asyncio.run(cloud.pull(dtype, name, tag)) except TagExistsError: click.echo(f"The tag ({tag}) already exists from {dtype}.{name}") return 1 except CloudDatasetDoesNotExistError: click.echo(f'The dataset "{dtype}.{name}" does not exist in the cloud') return 1 except CloudTagDoesNotExistError: click.echo(f'The tag "{tag}" does not exist in the cloud') return 1 except CloudPullFailedError: click.echo(f'Failed to pull all data for tag "{tag}". ') click.echo("This could be network issues, please try again later ") click.echo( "or report error to https://github.com/LinkageIO/minus80/issues ") return 1 # Let the user know click.echo(f"{dtype}.{name}:{tag} successfully pulled")
def push(slug): """ \b Push a frozen minus80 dataset to the cloud. \b Positional Arguments: <slug> - A slug of a frozen minus80 dataset """ cloud = m80.CloudData() try: cloud.user except UserNotLoggedInError: click.secho("Please log in to use this feature") try: dtype, name, tag = FreezableAPI.parse_slug(slug) if tag is None: raise TagInvalidError() except (TagInvalidError, FreezableNameInvalidError): click.echo(f'Please provide a valid tag in "{slug}"') return 0 # Make sure that the dataset is available if not FreezableAPI.exists(dtype, name): click.echo(f'"{dtype}.{name}" not in minus80 datasets! ' "check available datasets with the ls command") return 0 else: try: # run the push method in an event loop asyncio.run(cloud.push(dtype, name, tag)) except TagDoesNotExistError: click.echo(f'tag "{tag}" does not exist for {dtype}.{name}') except TagExistsError: click.echo(f"Cannot push {dtype}.{name}:{tag} to the cloud.") click.echo("The tag already exists there.") except TagConflictError: click.echo(f"Cannot push {dtype}.{name}:{tag} to the cloud.") click.echo("The tag already exists there.") click.secho( "Warning! The contents of the local tag and the cloud tag differ " "Create a tag with a unique name and retry pushing", fg="red", )
def login(username,password,force,reset_password): """ Log into your cloud account at minus80.linkage.io """ cloud = m80.CloudData() if force: try: os.remove(cloud._token_file) except FileNotFoundError: pass try: # See if currently logged in cloud.user except UserNotLoggedInError: if username is None: username = click.prompt('Username (email)',type=str) if password is None: password = click.prompt('Password', hide_input=True, type=str) try: cloud.login(username,password) except HTTPError as e: error_code = json.loads(e.args[1])['error']['message'] if error_code == 'INVALID_EMAIL': click.secho('Error logging in. Invalid email address!.',fg='red') elif error_code == 'INVALID_PASSWORD': click.secho('Error logging in. Incorrect Password!',fg='red') else: click.secho(f'Error logging in. {error_code}',fg='red') return 0 account_info = cloud.auth.get_account_info(cloud.user['idToken']) # double check that the user is verified if account_info['users'][0]['emailVerified'] == False: # make sure they have email verified click.secho("Your email has not been verified!") if click.confirm('Do you want to resend the verification email?'): cloud.auth.send_email_verification(cloud._user['idToken']) click.secho("Please follow the link sent to your email address, then re-run this command") return 0 click.secho('Successfully logged in',bg='green')
def ls(dtype, name, tags=False): """ List available datasets """ cloud = m80.CloudData() try: cloud.user except UserNotLoggedInError: click.secho("Please log in to use this feature") sys.exit(1) except HTTPError: click.secho( "An error occurred trying to login, please re-login using " "the command:\n\t$ minus80 cloud login --force \n", fg="red", ) sys.exit(1) # Make the list call datasets = asyncio.run(cloud.list()) if len(datasets) == 0: click.echo("Nothing here yet!") for avail_dtype, avail_names in datasets.items(): click.echo(f"{avail_dtype}:") if dtype and avail_dtype != dtype: continue for avail_name in avail_names.keys(): if name and avail_name != name: continue click.echo(f" └──{avail_name}") if tags: for avail_tag, metadata in avail_names[avail_name].items(): csum = metadata["checksum"][0:10] timestamp = datetime.fromtimestamp( metadata["created"]).strftime("%I:%M%p - %b %d, %Y") click.echo(f" └──{avail_tag} {csum} ({timestamp})")
def test_bad_engine(): with pytest.raises(Exception) as e_info: m80.CloudData(engine="error")
def list(dtype, name, raw): '''List available datasets''' cloud = m80.CloudData() cloud.list(dtype=dtype, name=name, raw=raw)
def remove(dtype, name, raw): ''' Delete a minus80 dataset from the cloud. ''' cloud = m80.CloudData() cloud.remove(dtype, name, raw)
def pull(dtype, name, raw, output): ''' Pull a minus80 dataset from the cloud. ''' cloud = m80.CloudData() cloud.pull(dtype, name, raw=raw, output=output)
def login(username, password, force, reset_password): """ Log into your cloud account at minus80.linkage.io """ cloud = m80.CloudData() # check to see if we are doing a reset if reset_password == True: if username is None: username = click.prompt("Username (email)", type=str) cloud.auth.send_password_reset_email(username) click.secho("Check your email to reset your password", fg="green") sys.exit(0) elif force: try: os.remove(cloud._token_file) except FileNotFoundError: pass try: # See if currently logged in cloud.user except HTTPError as e: error_code = json.loads(e.args[1])["error"]["message"] if error_code == "TOKEN_EXPIRED": click.secho( "Current Session is EXPIRED. Use the --force option to re-login!", fg="red", ) else: click.secho( "An error occurred trying to sign in. Try again shortly or use the --force option.", fg="red", ) sys.exit(1) except UserNotLoggedInError: if username is None: if "MINUS80_USERNAME" in os.environ: username = os.environ["MINUS80_USERNAME"] else: username = click.prompt("Username (email)", type=str) if password is None: if "MINUS80_PASSWORD" in os.environ: username = os.environ["MINUS80_PASSWORD"] else: password = click.prompt("Password", hide_input=True, type=str) try: cloud.login(username, password) except HTTPError as e: error_code = json.loads(e.args[1])["error"]["message"] if error_code == "INVALID_EMAIL": click.secho("Error logging in. Invalid email address!.", fg="red") # click.secho('Sign up for an account at https://minus80.linkage.io') elif error_code == "INVALID_PASSWORD": click.secho("Error logging in. Incorrect Password!", fg="red") else: click.secho(f"Error logging in. {error_code}", fg="red") sys.exit(1) account_info = cloud.auth.get_account_info(cloud.user["idToken"]) # double check that the user is verified if account_info["users"][0]["emailVerified"] == False: # make sure they have email verified click.secho("Your email has not been verified!") if click.confirm("Do you want to resend the verification email?"): cloud.auth.send_email_verification(cloud._user["idToken"]) click.secho( "Please follow the link sent to your email address, then re-run this command" ) return 0 click.secho("Successfully logged in", bg="green")
def list(dtype, name): """List available datasets""" cloud = m80.CloudData() cloud.list(dtype=dtype, name=name)