From 9944efbd0f1b94b60e7a6b4056a47166a347abc6 Mon Sep 17 00:00:00 2001 From: Jorge Orpinel Date: Wed, 11 Mar 2020 13:45:29 -0500 Subject: [PATCH] api: docstring updates (2) (#3426) * api: update to latest definitions to match iterative/dvc.org/pull/908 * Update dvc/api.py * metrics show: update -h output to match docs per https://github.com/iterative/dvc.org/pull/1014/commits/2c3452119545987f77b764e4aa6fc94d051092a7 * api: update docstrings to match iterative/dvc.org/pull/908 * api: refactor DVC repo check in get_url, and document it * dvc: cosmetic edits as I explored exceptions that api functions may raise * api: copy default info to read() docstring from open() per https://github.com/iterative/dvc/pull/3426#pullrequestreview-366949501 * api: improve open() docstring for clarity and add example per https://github.com/iterative/dvc/pull/3426#pullrequestreview-366956856 * api: remove unnecessary info from get_url docstring per https://github.com/iterative/dvc/pull/3426#discussion_r386203064 * api: produces->generated in open() docstring * api: simplify open docstring per https://github.com/iterative/dvc/pull/3426#discussion_r388218147 Co-authored-by: Ruslan Kuprieiev --- dvc/api.py | 44 ++++++++++++++++++++++++++++---------------- dvc/config.py | 7 +++---- dvc/scm/__init__.py | 4 ++-- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/dvc/api.py b/dvc/api.py index d1312baaf..98763d16a 100644 --- a/dvc/api.py +++ b/dvc/api.py @@ -7,31 +7,44 @@ from dvc.external_repo import external_repo class UrlNotDvcRepoError(DvcException): - """Thrown if given URL is not a DVC repository. - - Args: - url (str): URL to the repository - """ + """Thrown if the given URL is not a DVC repository.""" def __init__(self, url): super().__init__("'{}' is not a DVC repository.".format(url)) def get_url(path, repo=None, rev=None, remote=None): - """Returns URL to the storage location of a data artifact tracked - by DVC, specified by its path in a repo. + """ + Returns the URL to the storage location of a data file or directory tracked + in a DVC repo. For Git repos, HEAD is used unless a rev argument is + supplied. The default remote is tried unless a remote argument is supplied. - NOTE: There's no guarantee that the file actually exists in that location. + Raises UrlNotDvcRepoError if repo is not a DVC project. + + NOTE: This function does not check for the actual existence of the file or + directory in the remote storage. """ with _make_repo(repo, rev=rev) as _repo: - _require_dvc(_repo) + if not isinstance(_repo, Repo): + raise UrlNotDvcRepoError(_repo.url) out = _repo.find_out_by_relpath(path) remote_obj = _repo.cloud.get_remote(remote) return str(remote_obj.checksum_to_path_info(out.checksum)) def open(path, repo=None, rev=None, remote=None, mode="r", encoding=None): - """Context manager to open a tracked file as a file object.""" + """ + Open file in the supplied path tracked in a repo (both DVC projects and + plain Git repos are supported). For Git repos, HEAD is used unless a rev + argument is supplied. The default remote is tried unless a remote argument + is supplied. It may only be used as a context manager: + + with dvc.api.open( + 'path/to/file', + repo='https://example.com/url/to/repo' + ) as fd: + # ... Handle file object fd + """ args = (path,) kwargs = { "repo": repo, @@ -63,7 +76,11 @@ def _open(path, repo=None, rev=None, remote=None, mode="r", encoding=None): def read(path, repo=None, rev=None, remote=None, mode="r", encoding=None): - """Returns the contents of a tracked file.""" + """ + Returns the contents of a tracked file (by DVC or Git). For Git repos, HEAD + is used unless a rev argument is supplied. The default remote is tried + unless a remote argument is supplied. + """ with open( path, repo=repo, rev=rev, remote=remote, mode=mode, encoding=encoding ) as fd: @@ -81,8 +98,3 @@ def _make_repo(repo_url=None, rev=None): pass # fallthrough to external_repo with external_repo(url=repo_url, rev=rev) as repo: yield repo - - -def _require_dvc(repo): - if not isinstance(repo, Repo): - raise UrlNotDvcRepoError(repo.url) diff --git a/dvc/config.py b/dvc/config.py index 096bcf6f5..0907c66f3 100644 --- a/dvc/config.py +++ b/dvc/config.py @@ -205,9 +205,8 @@ class Config(dict): validate (bool): optional flag to tell dvc if it should validate the config or just load it as is. 'True' by default. - Raises: - ConfigError: thrown when config has an invalid format. + ConfigError: thrown if config has an invalid format. """ APPNAME = "dvc" @@ -276,7 +275,7 @@ class Config(dict): """Loads config from all the config files. Raises: - dvc.config.ConfigError: thrown if config has invalid format. + ConfigError: thrown if config has an invalid format. """ conf = {} for level in self.LEVELS: @@ -336,7 +335,7 @@ class Config(dict): @contextmanager def edit(self, level="repo"): if level in {"repo", "local"} and self.dvc_dir is None: - raise ConfigError("Not inside a dvc repo") + raise ConfigError("Not inside a DVC repo") conf = self.load_one(level) yield conf diff --git a/dvc/scm/__init__.py b/dvc/scm/__init__.py index 62f106314..15a75796f 100644 --- a/dvc/scm/__init__.py +++ b/dvc/scm/__init__.py @@ -4,8 +4,8 @@ from dvc.scm.base import Base from dvc.scm.git import Git -# just a sugar to point that this is an actual implementation for a dvc -# project under no SCM control +# Syntactic sugar to signal that this is an actual implementation for a DVC +# project under no SCM control. class NoSCM(Base): pass