Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b279fb2
Basic GDrive remote support
maxhora Sep 29, 2019
3f5b22f
Support upload progress bar with Tqdm
maxhora Oct 2, 2019
33ac722
Fix found issues
maxhora Oct 3, 2019
f1ad91c
More fixes
maxhora Oct 3, 2019
e2890f1
Remove unneccessary condition
maxhora Oct 3, 2019
f452538
Enclose dependencies imports inside property
maxhora Oct 6, 2019
949afc6
Use cached property for gdrive object access
maxhora Oct 6, 2019
5ec22c8
Fix tests; Add default token usage warning
maxhora Oct 9, 2019
488ffa3
Adjust test_data_cloud gdrive run condition
maxhora Oct 11, 2019
5250475
Move remote access out from init
maxhora Oct 11, 2019
df8e9f7
Incorporate ratelimit decorator to call GDrive API
maxhora Oct 11, 2019
dec8c28
Missed setup dep
maxhora Oct 11, 2019
43078eb
Refactor drive ListFile query
maxhora Oct 11, 2019
456cfe1
Fix deps
maxhora Oct 11, 2019
0357a5a
Refactor get_path_id
maxhora Oct 12, 2019
ae6ab5f
Fix climate issues
maxhora Oct 12, 2019
91b4da9
Create PyDrive instance on init of Remote
maxhora Oct 14, 2019
b6f87e7
Increase API rate limit to its maximum - 10 calls per second
maxhora Oct 14, 2019
0b08ab3
Fix code review findings
maxhora Oct 15, 2019
934be73
Wrap GDrive API calls into single function with backoff on exception
maxhora Oct 20, 2019
03951fc
Support pagination of GDrive API response; Fix code climate issues
maxhora Oct 23, 2019
22d7fd7
Add missed dep to setup
maxhora Oct 23, 2019
917f5c0
Fix tests
maxhora Oct 23, 2019
1abb735
Support multiple directories with similar titles
maxhora Oct 26, 2019
e1ed0b1
Raise exception on missed gdrive settings file path in config
maxhora Oct 26, 2019
b71f0b2
Fix tests
maxhora Oct 26, 2019
8589dec
Fix DeepSource findings
maxhora Oct 26, 2019
28e208c
Fix code review findings
maxhora Nov 2, 2019
0afd64c
Fix more code review findings
maxhora Nov 3, 2019
f397ca8
GDrive settings via DVC config
maxhora Nov 11, 2019
901adbf
Move credentials file erasing to earlier stage just after auth is com…
maxhora Nov 11, 2019
db8e7ed
Restyled by reorder-python-imports
restyled-commits Nov 11, 2019
1b4149c
Restyled by yapf
restyled-commits Nov 11, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 60 additions & 59 deletions dvc/config.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
"""DVC config objects."""

from __future__ import unicode_literals

from dvc.utils.compat import str, open

import os
import re
import copy
import errno
import configobj
import logging
import os
import re

from schema import Schema, Optional, And, Use, Regex, SchemaError
from dvc.exceptions import DvcException, NotDvcRepoError
import configobj
from schema import And
from schema import Optional
from schema import Regex
from schema import Schema
from schema import SchemaError
from schema import Use

from dvc.exceptions import DvcException
from dvc.exceptions import NotDvcRepoError
from dvc.utils.compat import open
from dvc.utils.compat import str

logger = logging.getLogger(__name__)

Expand All @@ -26,19 +32,16 @@ class ConfigError(DvcException):
"""

def __init__(self, msg, cause=None):
super(ConfigError, self).__init__(
"config file error: {}".format(msg), cause=cause
)
super(ConfigError, self).__init__("config file error: {}".format(msg),
cause=cause)


class NoRemoteError(ConfigError):
def __init__(self, command, cause=None):
msg = (
"no remote specified. Setup default remote with\n"
" dvc config core.remote <name>\n"
"or use:\n"
" dvc {} -r <name>\n".format(command)
)
msg = ("no remote specified. Setup default remote with\n"
" dvc config core.remote <name>\n"
"or use:\n"
" dvc {} -r <name>\n".format(command))

super(NoRemoteError, self).__init__(msg, cause=cause)

Expand Down Expand Up @@ -147,6 +150,8 @@ class Config(object): # pylint: disable=too-many-instance-attributes
CONFIG = "config"
CONFIG_LOCAL = "config.local"

CREDENTIALPATH = "credentialpath"

LEVEL_LOCAL = 0
LEVEL_REPO = 1
LEVEL_GLOBAL = 2
Expand All @@ -157,8 +162,7 @@ class Config(object): # pylint: disable=too-many-instance-attributes
SECTION_CORE = "core"
SECTION_CORE_LOGLEVEL = "loglevel"
SECTION_CORE_LOGLEVEL_SCHEMA = And(
Use(str.lower), Choices("info", "debug", "warning", "error")
)
Use(str.lower), Choices("info", "debug", "warning", "error"))
SECTION_CORE_REMOTE = "remote"
SECTION_CORE_INTERACTIVE_SCHEMA = BOOL_SCHEMA
SECTION_CORE_INTERACTIVE = "interactive"
Expand Down Expand Up @@ -197,25 +201,22 @@ class Config(object): # pylint: disable=too-many-instance-attributes
}

SECTION_CORE_SCHEMA = {
Optional(SECTION_CORE_LOGLEVEL): And(
str, Use(str.lower), SECTION_CORE_LOGLEVEL_SCHEMA
),
Optional(SECTION_CORE_REMOTE, default=""): And(str, Use(str.lower)),
Optional(
SECTION_CORE_INTERACTIVE, default=False
): SECTION_CORE_INTERACTIVE_SCHEMA,
Optional(
SECTION_CORE_ANALYTICS, default=True
): SECTION_CORE_ANALYTICS_SCHEMA,
Optional(
SECTION_CORE_CHECKSUM_JOBS, default=None
): SECTION_CORE_CHECKSUM_JOBS_SCHEMA,
Optional(SECTION_CORE_LOGLEVEL):
And(str, Use(str.lower), SECTION_CORE_LOGLEVEL_SCHEMA),
Optional(SECTION_CORE_REMOTE, default=""):
And(str, Use(str.lower)),
Optional(SECTION_CORE_INTERACTIVE, default=False):
SECTION_CORE_INTERACTIVE_SCHEMA,
Optional(SECTION_CORE_ANALYTICS, default=True):
SECTION_CORE_ANALYTICS_SCHEMA,
Optional(SECTION_CORE_CHECKSUM_JOBS, default=None):
SECTION_CORE_CHECKSUM_JOBS_SCHEMA,
}

# backward compatibility
SECTION_AWS = "aws"
SECTION_AWS_STORAGEPATH = "storagepath"
SECTION_AWS_CREDENTIALPATH = "credentialpath"
SECTION_AWS_CREDENTIALPATH = CREDENTIALPATH
SECTION_AWS_ENDPOINT_URL = "endpointurl"
SECTION_AWS_LIST_OBJECTS = "listobjects"
SECTION_AWS_REGION = "region"
Expand All @@ -238,7 +239,7 @@ class Config(object): # pylint: disable=too-many-instance-attributes
# backward compatibility
SECTION_GCP = "gcp"
SECTION_GCP_STORAGEPATH = SECTION_AWS_STORAGEPATH
SECTION_GCP_CREDENTIALPATH = SECTION_AWS_CREDENTIALPATH
SECTION_GCP_CREDENTIALPATH = CREDENTIALPATH
SECTION_GCP_PROJECTNAME = "projectname"
SECTION_GCP_SCHEMA = {
SECTION_GCP_STORAGEPATH: str,
Expand All @@ -255,6 +256,10 @@ class Config(object): # pylint: disable=too-many-instance-attributes
SECTION_OSS_ACCESS_KEY_ID = "oss_key_id"
SECTION_OSS_ACCESS_KEY_SECRET = "oss_key_secret"
SECTION_OSS_ENDPOINT = "oss_endpoint"
# GDrive options
SECTION_GDRIVE_CLIENT_ID = "gdrive_client_id"
SECTION_GDRIVE_CLIENT_SECRET = "gdrive_client_secret"
SECTION_GDRIVE_USER_CREDENTIALS_FILE = "gdrive_user_credentials_file"

SECTION_REMOTE_REGEX = r'^\s*remote\s*"(?P<name>.*)"\s*$'
SECTION_REMOTE_FMT = 'remote "{}"'
Expand All @@ -271,7 +276,7 @@ class Config(object): # pylint: disable=too-many-instance-attributes
SECTION_REMOTE_URL: str,
Optional(SECTION_AWS_REGION): str,
Optional(SECTION_AWS_PROFILE): str,
Optional(SECTION_AWS_CREDENTIALPATH): str,
Optional(CREDENTIALPATH): str,
Optional(SECTION_AWS_ENDPOINT_URL): str,
Optional(SECTION_AWS_LIST_OBJECTS, default=False): BOOL_SCHEMA,
Optional(SECTION_AWS_USE_SSL, default=True): BOOL_SCHEMA,
Expand All @@ -291,6 +296,9 @@ class Config(object): # pylint: disable=too-many-instance-attributes
Optional(SECTION_OSS_ACCESS_KEY_ID): str,
Optional(SECTION_OSS_ACCESS_KEY_SECRET): str,
Optional(SECTION_OSS_ENDPOINT): str,
Optional(SECTION_GDRIVE_CLIENT_ID): str,
Optional(SECTION_GDRIVE_CLIENT_SECRET): str,
Optional(SECTION_GDRIVE_USER_CREDENTIALS_FILE): str,
Optional(PRIVATE_CWD): str,
Optional(SECTION_REMOTE_NO_TRAVERSE, default=True): BOOL_SCHEMA,
}
Expand Down Expand Up @@ -339,9 +347,8 @@ def get_global_config_dir():
"""
from appdirs import user_config_dir

return user_config_dir(
appname=Config.APPNAME, appauthor=Config.APPAUTHOR
)
return user_config_dir(appname=Config.APPNAME,
appauthor=Config.APPAUTHOR)

@staticmethod
def get_system_config_dir():
Expand All @@ -352,9 +359,8 @@ def get_system_config_dir():
"""
from appdirs import site_config_dir

return site_config_dir(
appname=Config.APPNAME, appauthor=Config.APPAUTHOR
)
return site_config_dir(appname=Config.APPNAME,
appauthor=Config.APPAUTHOR)

@staticmethod
def init(dvc_dir):
Expand Down Expand Up @@ -397,13 +403,11 @@ def _resolve_paths(self, config):
return ret

def _load_configs(self):
system_config_file = os.path.join(
self.get_system_config_dir(), self.CONFIG
)
system_config_file = os.path.join(self.get_system_config_dir(),
self.CONFIG)

global_config_file = os.path.join(
self.get_global_config_dir(), self.CONFIG
)
global_config_file = os.path.join(self.get_global_config_dir(),
self.CONFIG)

self._system_config = configobj.ConfigObj(system_config_file)
self._global_config = configobj.ConfigObj(global_config_file)
Expand Down Expand Up @@ -437,10 +441,10 @@ def load(self):

self.config = configobj.ConfigObj()
for c in [
self._system_config,
self._global_config,
self._repo_config,
self._local_config,
self._system_config,
self._global_config,
self._repo_config,
self._local_config,
]:
c = self._resolve_paths(c)
c = self._lower(c)
Expand Down Expand Up @@ -516,9 +520,8 @@ def unset(self, section, opt=None, level=None, force=False):
if opt not in config[section].keys():
if force:
return
raise ConfigError(
"option '{}.{}' doesn't exist".format(section, opt)
)
raise ConfigError("option '{}.{}' doesn't exist".format(
section, opt))
del config[section][opt]

if not config[section]:
Expand Down Expand Up @@ -551,8 +554,7 @@ def set(self, section, opt, value, level=None, force=True):
elif not force:
raise ConfigError(
"Section '{}' already exists. Use `-f|--force` to overwrite "
"section with new value.".format(section)
)
"section with new value.".format(section))

config[section][opt] = value
self.save(config)
Expand All @@ -574,9 +576,8 @@ def get(self, section, opt=None, level=None):
raise ConfigError("section '{}' doesn't exist".format(section))

if opt not in config[section].keys():
raise ConfigError(
"option '{}.{}' doesn't exist".format(section, opt)
)
raise ConfigError("option '{}.{}' doesn't exist".format(
section, opt))

return config[section][opt]

Expand Down
12 changes: 6 additions & 6 deletions dvc/remote/__init__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
from __future__ import unicode_literals

from .config import RemoteConfig
from dvc.remote.azure import RemoteAZURE
from dvc.remote.gdrive import RemoteGDrive
from dvc.remote.gs import RemoteGS
from dvc.remote.hdfs import RemoteHDFS
from dvc.remote.local import RemoteLOCAL
from dvc.remote.s3 import RemoteS3
from dvc.remote.ssh import RemoteSSH
from dvc.remote.http import RemoteHTTP
from dvc.remote.https import RemoteHTTPS
from dvc.remote.local import RemoteLOCAL
from dvc.remote.oss import RemoteOSS

from .config import RemoteConfig

from dvc.remote.s3 import RemoteS3
from dvc.remote.ssh import RemoteSSH

REMOTES = [
RemoteAZURE,
RemoteGDrive,
RemoteGS,
RemoteHDFS,
RemoteHTTP,
Expand Down
Loading