def update(component, version, name, description, tags, private): """Update component hub. Uses /docs/core/cli/#caching Example: \b $ polyaxon hub update foobar --description="Image Classification with DL using TensorFlow" \b $ polyaxon hub update mike1/foobar --description="Image Classification with DL using TensorFlow" \b $ polyaxon hub update --tags="foo, bar" """ owner, component_hub, component_version, is_version = get_info( component, version) full_entity = ("{}/{}:{}".format(owner, component_hub, component_version) if is_version else "{}/{}".format(owner, component_hub)) update_dict = {} if name: update_dict["name"] = name if description: update_dict["description"] = description tags = validate_tags(tags) if tags: update_dict["tags"] = tags if private is not None: update_dict["is_public"] = not private if not update_dict: Printer.print_warning( "No argument was provided to update the component {}.".format( "version" if is_version else "hub")) sys.exit(1) try: polyaxon_client = PolyaxonClient() if is_version: response = polyaxon_client.component_hub_v1.patch_component_version( owner, component_hub, component_version, body=update_dict) Printer.print_success("Component version updated.") get_component_version_details(response) else: response = polyaxon_client.component_hub_v1.patch_component_hub( owner, component_hub, body=update_dict) Printer.print_success("Component updated.") get_entity_details(response, "Component hub") except (ApiException, HTTPError) as e: handle_cli_error( e, message="Could not update component {} `{}`.".format( "version" if is_version else "hub", full_entity), ) sys.exit(1)
def upload(): # pylint:disable=assign-to-new-keyword """Upload code of the current directory while respecting the .polyaxonignore file. > **Note**: Please note that this command has been temporarily disabled. """ Printer.print_warning( "Please note that this command has been temporarily disabled.")
def show(): """Show the current cli, client, and user configs.""" _config = ClientConfigManager.get_config_or_default() Printer.print_header("Client config:") dict_tabulate(_config.to_dict()) _config = CliConfigManager.get_config_or_default() if _config: Printer.print_header("CLI config:") if _config.current_version: click.echo("Version {}".format(_config.current_version)) else: Printer.print_warning("This cli is not configured.") if _config.installation: config_installation = dict_to_tabulate( _config.installation, humanize_values=True, exclude_attrs=["hmac", "auth", "host"], ) dict_tabulate(config_installation) else: Printer.print_warning( "This cli is not connected to a Polyaxon Host.") _config = UserConfigManager.get_config_or_default() if _config: Printer.print_header("User config:") config_user = dict_to_tabulate( _config.to_dict(), humanize_values=True, exclude_attrs=["theme"], ) dict_tabulate(config_user)
def set_client_config(): global CLIENT_CONFIG try: CLIENT_CONFIG = ClientConfigManager.get_config_from_env() except (TypeError, ValidationError): ClientConfigManager.purge() Printer.print_warning("Your client Configuration was purged!") CLIENT_CONFIG = ClientConfigManager.get_config_from_env()
def set_auth_config(): from polyaxon.managers.auth import AuthConfigManager global AUTH_CONFIG try: AUTH_CONFIG = AuthConfigManager.get_config_from_env() except (TypeError, ValidationError): AuthConfigManager.purge() Printer.print_warning("Your auth Configuration was purged!")
def project(ctx, _project): # pylint:disable=redefined-outer-name """Commands for projects.""" if _project: Printer.print_warning( "Passing arguments to command groups is deprecated and will be removed in v1.2! " "Please use arguments on the sub-command directly: " "`polyaxon project SUB_COMMAND --help`") if ctx.invoked_subcommand not in ["create", "ls"]: ctx.obj = ctx.obj or {} ctx.obj["project"] = _project
def set_cli_config(): from polyaxon.managers.cli import CliConfigManager global CLI_CONFIG try: CLI_CONFIG = CliConfigManager.get_config_or_default() except (TypeError, ValidationError): CliConfigManager.purge() Printer.print_warning("Your CLI Configuration was purged!")
def ops(ctx, project, uid): """Commands for ops/runs.""" ctx.obj = ctx.obj or {} if project or uid: Printer.print_warning( "Passing arguments to command groups is deprecated and will be removed in v2! " "Please use arguments on the sub-command directly: `polyaxon ops SUB_COMMAND --help`" ) ctx.obj["project"] = project if ctx.invoked_subcommand not in ["ls"]: ctx.obj["run_uuid"] = uid
def run( ctx, name: str, owner: str, project_name: str, description: str, tags: List[str], op_spec: V1Operation, upload: Callable, log: bool, can_upload: bool, ): if not settings.CLIENT_CONFIG.set_polypod: Printer.print_warning("Polypod not configured!") return def create_run(): click.echo("Creating a run.") try: compiled_operation = OperationSpecification.compile_operation( op_spec) run_name = compiled_operation.name or name resource = compiler.make( owner_name=owner, project_name=project_name, project_uuid=project_name, run_uuid=run_name, run_name=name, run_path=run_name, compiled_operation=compiled_operation, params=op_spec.params, ) Spawner(namespace=settings.AGENT_CONFIG.namespace).create( run_uuid=run_name, run_kind=compiled_operation.get_run_kind(), resource=resource, ) # cache.cache(config_manager=RunManager, response=response) run_job_uid = get_resource_name(run_name) Printer.print_success( "A new run `{}` was created".format(run_job_uid)) except (PolyaxonCompilerError, PolyaxonK8SError, PolypodException) as e: handle_cli_error(e, message="Could not create a run.") sys.exit(1) create_run() logs_cmd = run_logs # Check if we need to invoke logs if log and logs_cmd: ctx.obj = {"project": "{}/{}".format(owner, project_name)} ctx.invoke(logs_cmd)
def service(ctx, yes, external, url): """Open the operation service in browser. N.B. The operation must have a run kind service, otherwise it will raise an error. You can open the service embedded in Polyaxon UI or using the real service URL, please use the `--external` flag. """ owner, project_name, run_uuid = get_project_run_or_local( ctx.obj.get("project"), ctx.obj.get("run_uuid"), is_cli=True, ) client = RunClient(owner=owner, project=project_name, run_uuid=run_uuid) client.refresh_data() if client.run_data.kind != V1RunKind.SERVICE: Printer.print_warning("Command expected a operations of " "kind `service` received kind: {}!".format( client.run_data.kind)) sys.exit(1) dashboard_url = settings.CLIENT_CONFIG.host Printer.print_header("Waiting for running condition ...") client.wait_for_condition(statuses=[V1Statuses.RUNNING], print_status=True) client.refresh_data() namespace = client.run_data.settings.namespace run_url = "{}/{}/{}/runs/{}/service".format(dashboard_url, owner, project_name, run_uuid) service_endpoint = SERVICES_V1 if client.run_data.meta_info.get("rewrite_path", False): service_endpoint = REWRITE_SERVICES_V1 external_run_url = "{}/{}/{}/{}/{}/runs/{}/".format( dashboard_url, service_endpoint, namespace, owner, project_name, run_uuid) if url: Printer.print_header( "The service will be available at: {}".format(run_url)) Printer.print_header( "You can also view it in an external link at: {}".format( external_run_url)) sys.exit(0) if not yes: click.confirm( "Dashboard page will now open in your browser. Continue?", abort=True, default=True, ) if external: click.launch(external_run_url) sys.exit(0) click.launch(run_url)
def update(ctx, name, description, private): """Update project. Uses [Caching](/references/polyaxon-cli/#caching) Example: \b ```bash $ polyaxon update foobar --description="Image Classification with DL using TensorFlow" ``` \b ```bash $ polyaxon update mike1/foobar --description="Image Classification with DL using TensorFlow" ``` \b ```bash $ polyaxon update --tags="foo, bar" ``` """ owner, project_name = get_project_or_local(ctx.obj.get("project")) update_dict = {} if name: update_dict["name"] = name if description: update_dict["description"] = description if private is not None: update_dict["is_public"] = not private if not update_dict: Printer.print_warning( "No argument was provided to update the project.") sys.exit(1) try: polyaxon_client = PolyaxonClient() response = polyaxon_client.projects_v1.patch_project( owner, project_name, update_dict) except (ApiException, HTTPError) as e: handle_cli_error( e, message="Could not update project `{}`.".format(project_name)) sys.exit(1) Printer.print_success("Project updated.") get_project_details(response)
def update(ctx, _project, name, description, tags, private): """Update project. Uses /docs/core/cli/#caching Example: \b $ polyaxon project update foobar --description="Image Classification with DL using TensorFlow" \b $ polyaxon project update mike1/foobar --description="Image Classification with DL using TensorFlow" \b $ polyaxon update --tags="foo, bar" """ owner, project_name = get_project_or_local(_project or ctx.obj.get("project"), is_cli=True) update_dict = {} if name: update_dict["name"] = name if description: update_dict["description"] = description tags = validate_tags(tags) if tags: update_dict["tags"] = tags if private is not None: update_dict["is_public"] = not private if not update_dict: Printer.print_warning( "No argument was provided to update the project.") sys.exit(1) try: polyaxon_client = ProjectClient(owner=owner) response = polyaxon_client.update(update_dict) except (ApiException, HTTPError) as e: handle_cli_error( e, message="Could not update project `{}`.".format(project_name)) sys.exit(1) Printer.print_success("Project updated.") get_entity_details(response, "Project")
def update(ctx, name, description, tags): """Update run. Uses [Caching](/references/polyaxon-cli/#caching) Examples: \b ```bash $ polyaxon runs --uid=8aac02e3a62a4f0aaa257c59da5eab80 update --description="new description for my runs" ``` \b ```bash $ polyaxon runs --project=cats-vs-dogs -id 8aac02e3a62a4f0aaa257c59da5eab80 update --tags="foo, bar" --name="unique-name" ``` """ owner, project_name, run_uuid = get_project_run_or_local( ctx.obj.get("project"), ctx.obj.get("run_uuid"), is_cli=True) update_dict = {} if name: update_dict["name"] = name if description: update_dict["description"] = description tags = validate_tags(tags) if tags: update_dict["tags"] = tags if not update_dict: Printer.print_warning("No argument was provided to update the run.") sys.exit(0) try: polyaxon_client = RunClient(owner=owner, project=project_name, run_uuid=run_uuid) response = polyaxon_client.update(update_dict) except (ApiException, HTTPError) as e: handle_cli_error(e, message="Could not update run `{}`.".format(run_uuid)) sys.exit(1) Printer.print_success("Run updated.") get_run_details(response)
def get_component_version_details(response): content = response.content response = dict_to_tabulate(response.to_dict(), humanize_values=True, exclude_attrs=["content"]) Printer.print_header("Component info:") dict_tabulate(response) if content: specification = get_specification(data=content) get_specification_details(specification) else: Printer.print_warning( "This component version does not have any polyaxonfile content!")
def code(ctx): """Download code for run. Uses [Caching](/references/polyaxon-cli/#caching) Examples: \b ```bash $ polyaxon runs -uid=8aac02e3a62a4f0aaa257c59da5eab80 code ``` """ owner, project_name, run_uuid = get_project_run_or_local( ctx.obj.get("project"), ctx.obj.get("run_uuid")) try: polyaxon_client = PolyaxonClient() code_ref = polyaxon_client.runs_v1.get_run_code_refs( owner, project_name, run_uuid) commit = None if code_ref: commit = code_ref.commit Printer.print_header( "Run has code ref: `{}`, downloading ...".format(commit)) else: Printer.print_warning( "Run has no code ref, downloading latest code...") PolyaxonClient().project.download_repo(owner, project_name, commit=commit) except (ApiException, HTTPError) as e: handle_cli_error( e, message="Could not download outputs for run `{}`.".format( run_uuid)) sys.exit(1) Printer.print_success("Files downloaded.")
def run( ctx, project, polyaxonfile, python_module, url, hub, name, tags, description, log, upload, upload_from, upload_to, watch, local, params, presets, queue, nocache, cache, eager, git_preset, git_revision, ignore_template, ): """Run polyaxonfile specification. Examples: \b $ polyaxon run -f file -f file_override ... Run and set description and tags for this run \b $ polyaxon run -f file --description="Description of the current run" --tags="foo, bar, moo" Run and set a unique name for this run \b polyaxon run --name=foo Run for a specific project \b $ polyaxon run -p project1 -f file.yaml Run with updated params \b $ polyaxon run -p project1 -f file.yaml -P param1=234.2 -P param2=relu If a python file contains a component main, you can run that component \b $ polyaxon run -pm path/to/my-component.py If a python file contains more than one component, you can specify the component to run \b $ polyaxon run -pm path/to/my-component.py:componentA Uploading from everything in the current folder to the default uploads path \b $ polyaxon run ... -u Uploading from everything in the current folder to a custom path, e.g. code \b $ polyaxon run ... -u-to code Uploading from everything from a sub-folder, e.g. ./code to the a custom path, e.g. new-code \b $ polyaxon run ... -u-from ./code -u-to new-code """ if cache and nocache: Printer.print_error( "You can't use `--cache` and `--nocache` at the same.", sys_exit=True ) if (upload_to or upload_from) and not upload: upload = True if upload and eager: Printer.print_error( "You can't use `--upload` and `--eager` at the same.", sys_exit=True ) git_init = None if git_preset or git_revision: # Check that the current path was initialized if not GitConfigManager.is_initialized(): Printer.print_error( "You can't use `--git-preset [--git-revision]`, " "the current path is not initialized with a valid git connection or a git url, " "please run `polyaxon init [--git-connection] [--git-url]` " "to set a valid git configuration.", sys_exit=True, ) git_init = GitConfigManager.get_config() if git_init.git is None: GitConfigManager.purge(visibility=GitConfigManager.VISIBILITY_LOCAL) Printer.print_error( "Polyaxon could not start a new run with the `[--git-preset] or [--git-revision]`. " "The current path is initialized with " "an invalid git connection or an invalid git url.\n" "please run `polyaxon init [--git-connection] [--git-url]` " "to properly initialize the current path.", sys_exit=True, ) if git_revision: git_init.git.revision = git_revision elif code_reference.is_git_initialized(path="."): if code_reference.is_dirty(path="."): Printer.print_warning( "Polyaxon detected uncommitted changes in the current git repo!" ) commit_hash = code_reference.get_commit() git_init.git.revision = commit_hash else: Printer.print_warning( "Polyaxon could not find a valid git repo, " "and will not add the current commit to the git initializer." ) presets = validate_tags(presets) op_spec = check_polyaxonfile( polyaxonfile=polyaxonfile, python_module=python_module, url=url, hub=hub, params=params, presets=presets, queue=queue, cache=cache, nocache=nocache, verbose=False, eager=eager, git_init=git_init, ignore_template=ignore_template, ) if ignore_template: op_spec.disable_template() if op_spec.is_template(): click.echo("Please customize the specification or disable the template.") sys.exit(1) owner, project_name = get_project_or_local(project, is_cli=True) tags = validate_tags(tags) if local: try: compiled_operation = OperationSpecification.compile_operation(op_spec) compiled_operation = ( CompiledOperationSpecification.apply_operation_contexts( compiled_operation ) ) except (PolyaxonSchemaError, ValidationError): Printer.print_error( "Could not run this polyaxonfile locally, " "a context is required to resolve it dependencies." ) sys.exit(1) docker_run( ctx=ctx, name=name, owner=owner, project_name=project_name, description=description, tags=tags, compiled_operation=compiled_operation, log=log, ) elif settings.CLIENT_CONFIG.no_api: k8s_run( ctx=ctx, name=name, owner=owner, project_name=project_name, description=description, tags=tags, op_spec=op_spec, log=log, ) else: platform_run( ctx=ctx, name=name, owner=owner, project_name=project_name, description=description, tags=tags, op_spec=op_spec, log=log, upload=upload, upload_to=upload_to, upload_from=upload_from, watch=watch, eager=eager, )
def check_polyaxonfile( polyaxonfile: str = None, python_module: str = None, url: str = None, hub: str = None, params: Dict = None, presets: List[str] = None, queue: str = None, nocache: bool = None, cache: bool = None, verbose: bool = True, is_cli: bool = True, to_op: bool = True, validate_params: bool = True, eager: bool = False, git_init: V1Init = None, ignore_template: bool = False, ): if sum([1 for i in [python_module, url, hub] if i]) > 1: message = ("You can only use one and only one option: " "hub, url, or a python module.".format(hub)) if is_cli: Printer.print_error(message, sys_exit=True) else: raise PolyaxonfileError(message) if not any([polyaxonfile, python_module, url, hub]): polyaxonfile = check_default_path(path=".") if not any([polyaxonfile, python_module, url, hub]): message = ( "Something went wrong, `check_polyaxonfile` was called without a polyaxonfile, " "a hub component reference, a url or a python module.") if is_cli: Printer.print_error(message, sys_exit=True) else: raise PolyaxonfileError(message) if hub and not to_op: message = "Something went wrong, calling hub component `{}` without operation.".format( hub) if is_cli: Printer.print_error(message, sys_exit=True) else: raise PolyaxonfileError(message) polyaxonfile = to_list(polyaxonfile, check_none=True) parsed_params = None if params: parsed_params = parse_params(params, is_cli=is_cli) if not any([os.path.isfile(f) for f in polyaxonfile]) and not any([python_module, url, hub]): message = "Please pass a valid polyaxonfile, a python module, a url, or a component name" if is_cli: Printer.print_error(message, sys_exit=True) else: raise PolyaxonfileError(message) try: path_context = None if python_module: path_context = python_module plx_file = (ConfigSpec.get_from(python_module, config_type=".py").read().to_dict( include_kind=True, include_version=True)) elif url: plx_file = ConfigSpec.get_from(url, "url").read() elif hub: plx_file = ConfigSpec.get_from(hub, "hub").read() else: path_context = polyaxonfile.pop(0) plx_file = ConfigSpec.read_from(path_context) plx_file = get_specification(data=plx_file) if plx_file.kind == kinds.OPERATION: plx_file = collect_references(plx_file, path_context) plx_component = plx_file.component else: plx_component = plx_file if plx_component.is_dag_run: collect_dag_components(plx_component.run, path_context) if to_op or hub: plx_file = get_op_specification( hub=hub, config=plx_file, params=parsed_params, presets=presets, queue=queue, nocache=nocache, cache=cache, validate_params=validate_params, preset_files=polyaxonfile, git_init=git_init, ) if verbose and is_cli: Printer.print_success("Polyaxonfile valid") if ignore_template: plx_file.disable_template() if plx_file.is_template(): template_message = "This polyaxonfile was marked as template by the owner:" if plx_file.template.description: template_message += "\ntemplate description: {}".format( plx_file.template.description) if plx_file.template.fields: template_message += "\ntemplate fields that need changes: {}".format( plx_file.template.fields) Printer.print_warning(template_message) if eager: is_supported_in_eager_mode(spec=plx_file) return plx_file except Exception as e: message = "Polyaxonfile is not valid." if is_cli: handle_cli_error(e, message=message, sys_exit=True) else: raise PolyaxonfileError(message) from e
def init(project, git_connection, git_url, polyaxonfile, polyaxonignore): """Initialize a new local project and cache directory. Note: Make sure to add the local cache `.polyaxon` to your `.gitignore` and `.dockerignore` files. """ if not any( [project, git_connection, git_url, polyaxonfile, polyaxonignore]): Printer.print_warning( "`polyaxon init` did not receive any valid option.", command_help="polyaxon init", ) if project: owner, project_name = get_project_or_local(project, is_cli=True) try: polyaxon_client = ProjectClient(owner=owner, project=project_name) polyaxon_client.refresh_data() except (ApiException, HTTPError) as e: Printer.print_error( "Make sure you have a project with this name `{}`".format( project)) handle_cli_error( e, message="You can a create new project with this command: " "polyaxon project create " "--name={} [--description=...] [--tags=...]".format( project_name), ) sys.exit(1) init_project = False if ProjectConfigManager.is_initialized(): local_project = get_local_project() click.echo( "Warning! This project is already initialized with the following project:" ) with indentation.indent(4): indentation.puts("Owner: {}".format(local_project.owner)) indentation.puts("Project: {}".format(local_project.name)) if click.confirm("Would you like to override this current config?", default=False): init_project = True else: init_project = True if init_project: ProjectConfigManager.purge( visibility=ProjectConfigManager.VISIBILITY_LOCAL) config = polyaxon_client.client.sanitize_for_serialization( polyaxon_client.project_data) ProjectConfigManager.set_config( config, init=True, visibility=ProjectConfigManager.VISIBILITY_LOCAL) Printer.print_success("Project was initialized") Printer.print_header( "Make sure to add the local cache `.polyaxon` " "to your `.gitignore` and `.dockerignore` files.") else: Printer.print_header("Project config was not changed.") if git_connection or git_url: init_git = False if GitConfigManager.is_initialized(): click.echo("Warning! A {} file was found.".format( GitConfigManager.CONFIG_FILE_NAME)) if click.confirm("Would you like to override it?", default=False): init_git = True else: init_git = True if init_git: GitConfigManager.purge( visibility=GitConfigManager.VISIBILITY_LOCAL) config = GitConfigManager.CONFIG( connection=git_connection, git=V1GitType(url=git_url) if git_url else None, ) GitConfigManager.set_config(config=config, init=True) Printer.print_success("New {} file was created.".format( GitConfigManager.CONFIG_FILE_NAME)) else: Printer.print_header("{} file was not changed.".format( GitConfigManager.CONFIG_FILE_NAME)) if polyaxonfile: create_polyaxonfile() if polyaxonignore: init_ignore = False if IgnoreConfigManager.is_initialized(): click.echo("Warning! A {} file was found.".format( IgnoreConfigManager.CONFIG_FILE_NAME)) if click.confirm("Would you like to override it?", default=False): init_ignore = True else: init_ignore = True if init_ignore: IgnoreConfigManager.init_config() Printer.print_success("New {} file was created.".format( IgnoreConfigManager.CONFIG_FILE_NAME)) else: Printer.print_header("{} file was not changed.".format( IgnoreConfigManager.CONFIG_FILE_NAME))
def service(ctx, yes, external, url): """Open the operation service in browser. N.B. The operation must have a run kind service, otherwise it will raise an error. You can open the service embedded in Polyaxon UI or using the real service URL, please use the `--external` flag. """ owner, project_name, run_uuid = get_project_run_or_local( ctx.obj.get("project"), ctx.obj.get("run_uuid"), is_cli=True, ) client = RunClient(owner=owner, project=project_name, run_uuid=run_uuid) client.refresh_data() if client.run_data.kind != V1RunKind.SERVICE: Printer.print_warning( "Command expected an operation of " "kind `service` received kind: `{}`!".format(client.run_data.kind) ) sys.exit(1) Printer.print_header("Waiting for running condition ...") client.wait_for_condition( statuses={V1Statuses.RUNNING} | LifeCycle.DONE_VALUES, print_status=True ) client.refresh_data() if LifeCycle.is_done(client.run_data.status): Printer.print_header("The operations reached a done statuses.") latest_status = Printer.add_status_color( {"status": client.run_data.status}, status_key="status" ) click.echo("{}\n".format(latest_status["status"])) run_url = get_dashboard_url( subpath="{}/{}/runs/{}/service".format(owner, project_name, run_uuid) ) namespace = client.run_data.settings.namespace service_endpoint = SERVICES_V1 if client.run_data.meta_info.get("rewrite_path", False): service_endpoint = REWRITE_SERVICES_V1 external_run_url = get_dashboard_url( base=service_endpoint, subpath="{}/{}/{}/runs/{}/".format(namespace, owner, project_name, run_uuid), ) if url: Printer.print_header("The service will be available at: {}".format(run_url)) Printer.print_header( "You can also view it in an external link at: {}".format(external_run_url) ) sys.exit(0) if not yes: click.confirm( "Dashboard page will now open in your browser. Continue?", abort=True, default=True, ) if external: click.launch(external_run_url) sys.exit(0) click.launch(run_url)
def ls(ctx, project, io, to_csv, query, sort, limit, offset, columns, offline, offline_path): """List runs for this project. Uses /docs/core/cli/#caching Examples: Get all runs: \b Get all runs with with status {created or running}, and creation date between 2018-01-01 and 2018-01-02, and params activation equal to sigmoid and metric loss less or equal to 0.2 \b $ polyaxon ops ls \ -q "status:created|running, started_at:2018-01-01..2018-01-02, \ params.activation:sigmoid, metrics.loss:<=0.2" Get all runs sorted by update date: \b $ polyaxon ops ls -s "-updated_at" Get all runs of kind job: \b $ polyaxon ops ls -q "kind: job" Get all runs of kind service: \b $ polyaxon ops ls -q "kind: service" """ if offline: offline_path = offline_path or container_contexts.CONTEXT_OFFLINE_ROOT offline_path_format = "{}/{{}}/run_data.json".format(offline_path) if not os.path.exists(offline_path) or not os.path.isdir(offline_path): Printer.print_error( f"Could not list offline runs, the path `{offline_path}` " f"does not exist or is not a directory.") sys.exit(1) results = [] for uid in os.listdir(offline_path): run_path = offline_path_format.format(uid) if os.path.exists(run_path): results.append(RunConfigManager.read_from_path(run_path)) else: Printer.print_warning( f"Skipping run {uid}, offline data not found.") else: owner, project_name = get_project_or_local(project or ctx.obj.get("project"), is_cli=True) try: polyaxon_client = RunClient(owner=owner, project=project_name) response = polyaxon_client.list(limit=limit, offset=offset, query=query, sort=sort) except (ApiException, HTTPError) as e: handle_cli_error( e, message="Could not get runs for project `{}`.".format( project_name)) sys.exit(1) meta = get_meta_response(response) if meta: Printer.print_header("Runs for project `{}/{}`.".format( owner, project_name)) Printer.print_header("Navigation:") dict_tabulate(meta) else: Printer.print_header("No runs found for project `{}/{}`.".format( owner, project_name)) results = response.results objects = [Printer.add_status_color(o.to_dict()) for o in results] columns = validate_tags(columns) if io: objects, prefixed_columns = flatten_keys( objects=objects, columns=["inputs", "outputs"], columns_prefix={ "inputs": "in", "outputs": "out" }, ) if columns: columns = {prefixed_columns.get(col, col) for col in columns} if to_csv: objects = list_dicts_to_csv( objects, include_attrs=columns, exclude_attrs=DEFAULT_EXCLUDE, ) else: objects = list_dicts_to_tabulate( objects, include_attrs=columns, exclude_attrs=DEFAULT_EXCLUDE, humanize_values=True, upper_keys=True, ) else: if to_csv: objects = list_dicts_to_csv( objects, include_attrs=columns, exclude_attrs=DEFAULT_EXCLUDE + ["inputs", "outputs"], ) else: objects = list_dicts_to_tabulate( objects, include_attrs=columns, exclude_attrs=DEFAULT_EXCLUDE + ["inputs", "outputs"], humanize_values=True, upper_keys=True, ) if objects: if to_csv: filename = "./results.csv" write_csv(objects, filename=filename) Printer.print_success("CSV file generated: `{}`".format(filename)) else: Printer.print_header("Runs:") objects.pop("project_name", None) dict_tabulate(objects, is_list_dict=True)
def run( ctx, project, polyaxonfile, python_module, url, hub, name, tags, description, log, watch, local, params, presets, queue, nocache, eager, git_preset, git_revision, ignore_template, ): """Run polyaxonfile specification. Examples: \b $ polyaxon run -f file -f file_override ... Run and set description and tags for this run \b $ polyaxon run -f file --description="Description of the current run" --tags="foo, bar, moo" Run and set a unique name for this run \b polyaxon run --name=foo Run for a specific project \b $ polyaxon run -p project1 -f file.yaml Run with updated params \b $ polyaxon run -p project1 -f file.yaml -P param1=234.2 -P param2=relu If a python file contains a component main, you can run that component \b polyaxon run -pm path/to/my-component.py If a python file contains more than one component, you can specify the component to run \b polyaxon run -pm path/to/my-component.py:componentA """ git_init = None if git_preset: # Check that the current path was initialized if not GitConfigManager.is_initialized(): Printer.print_error( "You can't use --git-init, " "the current path is not initialized with a valid git connection or a git url, " "please run `polyaxon init [--git-connection] [--git-url]` " "to set a valid git configuration.") sys.exit(1) git_init = GitConfigManager.get_config() if git_revision: git_init.git.revision = git_revision elif code_reference.is_git_initialized(path="."): if code_reference.is_dirty(path="."): Printer.print_warning( "Polyaxon detected uncommitted changes in the current git repo!" ) commit_hash = code_reference.get_commit() git_init.git.revision = commit_hash else: Printer.print_warning( "Polyaxon could not find a valid git repo, " "and will not add the current commit to the git initializer.") presets = validate_tags(presets) op_spec = check_polyaxonfile( polyaxonfile=polyaxonfile, python_module=python_module, url=url, hub=hub, params=params, presets=presets, queue=queue, nocache=nocache, verbose=False, eager=eager, git_init=git_init, ignore_template=ignore_template, ) if ignore_template: op_spec.disable_template() if op_spec.is_template(): click.echo( "Please customize the specification or disable the template.") sys.exit(1) owner, project_name = get_project_or_local(project, is_cli=True) tags = validate_tags(tags) if local: try: compiled_operation = OperationSpecification.compile_operation( op_spec) compiled_operation = CompiledOperationSpecification.apply_operation_contexts( compiled_operation) except (PolyaxonSchemaError, ValidationError): Printer.print_error( "Could not run this polyaxonfile locally, " "a context is required to resolve it dependencies.") sys.exit(1) docker_run( ctx=ctx, name=name, owner=owner, project_name=project_name, description=description, tags=tags, compiled_operation=compiled_operation, log=log, ) elif settings.CLIENT_CONFIG.no_api: k8s_run( ctx=ctx, name=name, owner=owner, project_name=project_name, description=description, tags=tags, op_spec=op_spec, log=log, ) else: platform_run( ctx=ctx, name=name, owner=owner, project_name=project_name, description=description, tags=tags, op_spec=op_spec, log=log, watch=watch, eager=eager, )
def config(_list): # pylint:disable=redefined-builtin """Set and get the global configurations.""" if _list: Printer.print_warning( "`polyaxon config -l` is deprecated, please use `polyaxon config show`!" )
def cli(context, verbose, offline): """Polyaxon - Cloud Native Machine Learning Automation & Experimentation tool. This CLI provides tools to: - Parse, Validate, and Check Polyaxonfiles. - Interact with Polyaxon server. - Run and Monitor experiments and jobs. This CLI tool comes with a caching mechanism: - You can initialize a project with: polyaxon init -p [project name] - Otherwise Polyaxon will use the default global path for the cache. You can check the version of your CLI by running: - polyaxon version To can check the version of the CLI and the server, and check the compatibility matrix: - polyaxon version --check To Enable debug mode, you can use the `-v` flag: - polyaxon -v ... To configure your host: - polyaxon config set --host=... To check your current config: - polyaxon config show Common commands: - polyaxon project get - polyaxon run [-f] [-l] - polyaxon ops ls - polyaxon ops logs - polyaxon ops get - polyaxon config set ... Admin deployment commands: - polyaxon admin deploy [-f] [--check] - polyaxon admin upgrade [-f] [--check] - polyaxon admin teardown [-f] For more information, please visit https://polyaxon.com/docs/core/cli/ Check the help available for each command listed below by appending `-h`. """ settings.set_cli_config() configure_logger(verbose) if settings.CLIENT_CONFIG.no_op: Printer.print_warning( "POLYAXON_NO_OP is set to `true`, some commands will not function correctly." ) context.obj = context.obj or {} if not settings.CLIENT_CONFIG.client_header: settings.CLIENT_CONFIG.set_cli_header() context.obj["offline"] = offline if offline: os.environ["POLYAXON_IS_OFFLINE"] = "true" settings.CLIENT_CONFIG.is_offline = True non_check_cmds = [ "completion", "config", "version", "login", "logout", "deploy", "admin", "teardown", "docker", "initializer", "sidecar", "proxy", "notify", "upgrade", "port-forward", ] if not settings.CLI_CONFIG.installation: pass if (not (context.invoked_subcommand in non_check_cmds or offline or settings.CLIENT_CONFIG.no_api or settings.CLIENT_CONFIG.is_ops or DOCS_GEN) and not settings.CLI_CONFIG.installation): cli_config = set_versions_config(is_cli=False) settings.CLI_CONFIG = cli_config check_cli_version(cli_config, is_cli=False)