def list_tasks(args: Namespace) -> None: api_path = RemoteTaskNewAPIs[args._command] api_full_path = "api/v1/{}".format(api_path) table_header = RemoteTaskListTableHeaders[args._command] if args.all: params = {} # type: Dict[str, Any] else: params = {"users": [authentication.must_cli_auth().get_session_user()]} res = api.get(args.master, api_full_path, params=params).json()[api_path] if args.quiet: for command in res: print(command["id"]) return for item in res: if item["state"].startswith("STATE_"): item["state"] = item["state"][6:] if getattr(args, "json", None): print(json.dumps(res, indent=4)) return values = render.select_values(res, table_header) render.tabulate_or_csv(table_header, values, getattr(args, "csv", False))
def list_project_experiments(args: Namespace) -> None: sess = setup_session(args) (w, p) = project_by_name(sess, args.workspace_name, args.project_name) kwargs: Dict[str, Any] = { "id": p.id, "orderBy": bindings.v1OrderBy[f"ORDER_BY_{args.order_by.upper()}"], "sortBy": bindings. v1GetExperimentsRequestSortBy[f"SORT_BY_{args.sort_by.upper()}"], } if not args.all: kwargs["users"] = [authentication.must_cli_auth().get_session_user()] kwargs["archived"] = "false" all_experiments: List[bindings.v1Experiment] = [] internal_offset = args.offset if ("offset" in args and args.offset) else 0 limit = args.limit if "limit" in args else 200 while True: experiments = bindings.get_GetProjectExperiments( sess, limit=limit, offset=internal_offset, **kwargs).experiments all_experiments += experiments internal_offset += len(experiments) if ("offset" in args and args.offset) or len(experiments) < limit: break if args.json: print(json.dumps([e.to_json() for e in all_experiments], indent=2)) else: render_experiments(args, all_experiments)
def change_password(parsed_args: Namespace) -> None: if parsed_args.target_user: username = parsed_args.target_user elif parsed_args.user: username = parsed_args.user else: username = authentication.must_cli_auth().get_session_user() if not username: # The default user should have been set by now by autologin. print( colored("Please log in as an admin or user to change passwords", "red")) return password = getpass.getpass("New password for user '{}': ".format(username)) check_password = getpass.getpass("Confirm password: "******"Passwords do not match", "red")) return # Hash the password to avoid sending it in cleartext. password = api.salt_and_hash(password) update_user(username, parsed_args.master, password=password) # If the target user's password isn't being changed by another user, reauthenticate after # password change so that the user doesn't have to do so manually. if parsed_args.target_user is None: token_store = authentication.TokenStore(parsed_args.master) token = authentication.do_login(parsed_args.master, username, password) token_store.set_token(username, token) token_store.set_active(username)
def ws(host: str, path: str) -> WebSocket: """ Connect to a web socket at the remote API. """ websocket = lomond.WebSocket(maybe_upgrade_ws_scheme(make_url(host, path))) token = authentication.must_cli_auth().get_session_token() websocket.add_header("Authorization".encode(), "Bearer {}".format(token).encode()) return WebSocket(websocket)
def delete_workspace(args: Namespace) -> None: sess = setup_session(args) w = workspace_by_name(sess, args.workspace_name) if w.numExperiments > 0: raise errors.ForbiddenException( authentication.must_cli_auth().get_session_user(), "Workspaces with associated experiments currently cannot be deleted. " "Use archive to hide workspaces.", ) if args.yes or render.yes_or_no( 'Deleting workspace "' + args.workspace_name + '" will result \n' "in the unrecoverable deletion of all associated projects. For a \n" "recoverable alternative, see the 'archive' command. Do you still \n" "wish to proceed?"): bindings.delete_DeleteWorkspace(sess, id=w.id) print(f"Successfully deleted workspace {args.workspace_name}.") else: print("Aborting workspace deletion.")
def list_experiments(args: Namespace) -> None: kwargs = { "limit": args.limit, "offset": args.offset, } if not args.all: kwargs["archived"] = "false" kwargs["users"] = [authentication.must_cli_auth().get_session_user()] all_experiments: List[bindings.v1Experiment] = limit_offset_paginator( bindings.get_GetExperiments, "experiments", setup_session(args), **kwargs) def format_experiment(e: Any) -> List[Any]: result = [ e.id, e.username, e.name, e.forkedFrom, e.state.value.replace("STATE_", ""), render.format_percent(e.progress), render.format_time(e.startTime), render.format_time(e.endTime), e.resourcePool, ] if args.all: result.append(e.archived) return result headers = [ "ID", "Owner", "Name", "Parent ID", "State", "Progress", "Start Time", "End Time", "Resource Pool", ] if args.all: headers.append("Archived") values = [format_experiment(e) for e in all_experiments] render.tabulate_or_csv(headers, values, args.csv)
def delete_project(args: Namespace) -> None: sess = setup_session(args) (w, p) = project_by_name(sess, args.workspace_name, args.project_name) if p.numExperiments > 0: raise errors.ForbiddenException( authentication.must_cli_auth().get_session_user(), "Projects with associated experiments currently cannot be deleted. " "Use archive to hide projects.", ) if args.yes or render.yes_or_no( 'Deleting project "' + args.project_name + '" will result in the \n' "unrecoverable deletion of this project and notes. For a recoverable \n" "alternative, see the 'archive' command. Do you still \n" "wish to proceed?"): bindings.delete_DeleteProject(sess, id=p.id) print(f"Successfully deleted project {args.project_name}.") else: print("Aborting project deletion.")
def list(args: Namespace) -> None: api_path = RemoteTaskNewAPIs[args._command] api_full_path = "api/v1/{}".format(api_path) table_header = RemoteTaskListTableHeaders[args._command] if args.all: params = {} # type: Dict[str, Any] else: params = {"users": [authentication.must_cli_auth().get_session_user()]} res = api.get(args.master, api_full_path, params=params).json()[api_path] if args.quiet: for command in res: print(command["id"]) return for item in res: if item["state"].startswith("STATE_"): item["state"] = item["state"][6:] render.render_table(res, table_header)
def list_experiments(args: Namespace) -> None: params = {} if args.all: params["filter"] = "all" else: params["user"] = authentication.must_cli_auth().get_session_user() r = api.get(args.master, "experiments", params=params) def format_experiment(e: Any) -> List[Any]: result = [ e["id"], e["owner"]["username"], e["config"]["name"], e["state"], render.format_percent(e["progress"]), render.format_time(e["start_time"]), render.format_time(e["end_time"]), e["config"]["resources"].get("resource_pool"), ] if args.all: result.append(e["archived"]) return result headers = [ "ID", "Owner", "Name", "State", "Progress", "Start Time", "End Time", "Resource Pool", ] if args.all: headers.append("Archived") values = [format_experiment(e) for e in r.json()] render.tabulate_or_csv(headers, values, args.csv)