Skip to content

Commit 7a186ee

Browse files
authored
Merge pull request #48 from rekcurd/feature/gcs-support
Merged
2 parents 32c95bb + de17e69 commit 7a186ee

7 files changed

Lines changed: 82 additions & 6 deletions

File tree

rekcurd/data_servers/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .local_handler import LocalHandler
1313
from .ceph_handler import CephHandler
1414
from .aws_s3_handler import AwsS3Handler
15+
from .gcs_handler import GcsHandler
1516

1617

1718
class DataServer(object):
@@ -27,6 +28,8 @@ def __init__(self, config: RekcurdConfig):
2728
self._api_handler = CephHandler(config)
2829
elif config.MODEL_MODE_ENUM == ModelModeEnum.AWS_S3:
2930
self._api_handler = AwsS3Handler(config)
31+
elif config.MODEL_MODE_ENUM == ModelModeEnum.GCS:
32+
self._api_handler = GcsHandler(config)
3033
else:
3134
raise ValueError("Invalid ModelModeEnum value.")
3235

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# coding: utf-8
2+
3+
4+
import boto3
5+
6+
from .data_handler import DataHandler
7+
from rekcurd.utils import RekcurdConfig
8+
9+
10+
class GcsHandler(DataHandler):
11+
"""GcsHandler
12+
"""
13+
def __init__(self, config: RekcurdConfig):
14+
super(GcsHandler, self).__init__(config)
15+
self._resource = boto3.resource(
16+
's3',
17+
region_name="auto",
18+
endpoint_url="https://storage.googleapis.com",
19+
aws_access_key_id=config.GCS_ACCESS_KEY,
20+
aws_secret_access_key=config.GCS_SECRET_KEY,
21+
)
22+
self._bucket = config.GCS_BUCKET_NAME
23+
24+
def download(self, remote_filepath: str, local_filepath: str) -> None:
25+
self._resource.Bucket(self._bucket).download_file(remote_filepath, local_filepath)
26+
27+
def upload(self, remote_filepath: str, local_filepath: str) -> None:
28+
self._resource.Bucket(self._bucket).upload_file(local_filepath, remote_filepath)

rekcurd/template/settings.yml-tpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ model:
2828
access_key: xxxxx # AWS access key.
2929
secret_key: xxxxx # AWS secret key.
3030
bucket: xxxxx # AWS bucket name.
31-
gcs: # :TODO: GCS parameters.
31+
gcs: # GCS access parameters. Required for "gcs" mode. To generate keys, see "https://cloud.google.com/storage/docs/migrating#keys"
3232
filepath: model/default.model # ML model file. Default "model/default.model"
33+
access_key: xxxxx # GCS access key.
34+
secret_key: xxxxx # GCS secret key.
35+
bucket: xxxxx # GCS bucket name.

rekcurd/utils/rekcurd_config.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ class RekcurdConfig:
5656
AWS_ACCESS_KEY: str = None
5757
AWS_SECRET_KEY: str = None
5858
AWS_BUCKET_NAME: str = None
59-
# TODO: GCS
59+
GCS_ACCESS_KEY: str = None
60+
GCS_SECRET_KEY: str = None
61+
GCS_BUCKET_NAME: str = None
6062

6163
def __init__(self, config_file: str = None):
6264
self.KUBERNETES_MODE = os.getenv("REKCURD_KUBERNETES_MODE")
@@ -74,6 +76,7 @@ def set_configurations(
7476
ceph_port: int = None, ceph_is_secure: bool = None,
7577
ceph_bucket_name: str = None, aws_access_key: str = None,
7678
aws_secret_key: str = None, aws_bucket_name: str = None,
79+
gcs_access_key: str = None, gcs_secret_key: str = None, gcs_bucket_name: str = None,
7780
**options):
7881
self.DEBUG_MODE = debug_mode if debug_mode is not None else self.DEBUG_MODE
7982
self.APPLICATION_NAME = application_name or self.APPLICATION_NAME
@@ -92,7 +95,9 @@ def set_configurations(
9295
self.AWS_ACCESS_KEY = aws_access_key or self.AWS_ACCESS_KEY
9396
self.AWS_SECRET_KEY = aws_secret_key or self.AWS_SECRET_KEY
9497
self.AWS_BUCKET_NAME = aws_bucket_name or self.AWS_BUCKET_NAME
95-
# TODO: GCS
98+
self.GCS_ACCESS_KEY = gcs_access_key or self.GCS_ACCESS_KEY
99+
self.GCS_SECRET_KEY = gcs_secret_key or self.GCS_SECRET_KEY
100+
self.GCS_BUCKET_NAME = gcs_bucket_name or self.GCS_BUCKET_NAME
96101

97102
def __load_from_file(self, config_file: str):
98103
if config_file is not None:
@@ -128,8 +133,13 @@ def __load_from_file(self, config_file: str):
128133
self.AWS_ACCESS_KEY = config_model_mode.get("access_key")
129134
self.AWS_SECRET_KEY = config_model_mode.get("secret_key")
130135
self.AWS_BUCKET_NAME = config_model_mode.get("bucket")
136+
elif self.MODEL_MODE_ENUM == ModelModeEnum.GCS:
137+
config_model_mode = config_model.get(model_mode, dict())
138+
self.MODEL_FILE_PATH = config_model_mode.get("filepath", "model/default.model")
139+
self.GCS_ACCESS_KEY = config_model_mode.get("access_key")
140+
self.GCS_SECRET_KEY = config_model_mode.get("secret_key")
141+
self.GCS_BUCKET_NAME = config_model_mode.get("bucket")
131142
else:
132-
# TODO: GCS
133143
raise ValueError("'{}' is not supported as ModelModeEnum".format(model_mode))
134144

135145
def __load_from_env(self):
@@ -151,4 +161,6 @@ def __load_from_env(self):
151161
self.AWS_ACCESS_KEY = os.getenv("REKCURD_AWS_ACCESS_KEY")
152162
self.AWS_SECRET_KEY = os.getenv("REKCURD_AWS_SECRET_KEY")
153163
self.AWS_BUCKET_NAME = os.getenv("REKCURD_AWS_BUCKET_NAME")
154-
# TODO: GCS
164+
self.GCS_ACCESS_KEY = os.getenv("REKCURD_GCS_ACCESS_KEY")
165+
self.GCS_SECRET_KEY = os.getenv("REKCURD_GCS_SECRET_KEY")
166+
self.GCS_BUCKET_NAME = os.getenv("REKCURD_GCS_BUCKET_NAME")

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ grpcio>=1.13.0 # Apache-2.0
44
grpcio-tools>=1.13.0 # Apache-2.0
55
PyYAML>=3.12 # MIT
66
boto>=2.49.0 # MIT
7-
boto3>=1.9.0 # Apache-2.0
7+
boto3>=1.9.38 # Apache-2.0

test/data_servers/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def inner_method(*args, **kwargs):
1616
new=Mock(return_value=None)) as _, \
1717
patch('rekcurd.data_servers.AwsS3Handler.upload',
1818
new=Mock(return_value=None)) as _, \
19+
patch('rekcurd.data_servers.GcsHandler.download',
20+
new=Mock(return_value=None)) as _, \
21+
patch('rekcurd.data_servers.GcsHandler.upload',
22+
new=Mock(return_value=None)) as _, \
1923
patch('builtins.open', new_callable=mock_open) as _:
2024
return func(*args, **kwargs)
2125
return inner_method
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest
2+
3+
from rekcurd.utils import RekcurdConfig, ModelModeEnum
4+
from rekcurd.data_servers import GcsHandler
5+
6+
from . import patch_predictor
7+
8+
9+
class GcsHandlerTest(unittest.TestCase):
10+
"""Tests for GcsHandlerTest.
11+
"""
12+
13+
def setUp(self):
14+
config = RekcurdConfig("./test/test-settings.yml")
15+
config.set_configurations(
16+
model_mode=ModelModeEnum.GCS.value, gcs_access_key="xxx",
17+
gcs_secret_key="xxx", gcs_bucket_name="xxx")
18+
self.handler = GcsHandler(config)
19+
20+
@patch_predictor()
21+
def test_download(self):
22+
self.assertIsNone(self.handler.download("remote","local"))
23+
24+
@patch_predictor()
25+
def test_upload(self):
26+
self.assertIsNone(self.handler.upload("remote","local"))

0 commit comments

Comments
 (0)