8000 Merge pull request #1229 from dhermes/bigtable-add-factories-and-shel… · googleapis/google-cloud-python@0773f5c · GitHub
[go: up one dir, main page]

Skip to content

Commit 0773f5c

Browse files
committed
Merge pull request #1229 from dhermes/bigtable-add-factories-and-shell-classes
Adding Bigtable factories and shell classes.
2 parents 46d8253 + 2547f84 commit 0773f5c

File tree

12 files changed

+495
-0
lines changed

12 files changed

+495
-0
lines changed

gcloud/_helpers.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import calendar
2020
import datetime
2121
import os
22+
import six
2223
import socket
2324

2425
try:
@@ -264,6 +265,37 @@ def _millis_from_datetime(value):
264265
return _millis(value)
265266

266267

268+
def _to_bytes(value, encoding='ascii'):
269+
"""Converts a string value to bytes, if necessary.
270+
271+
Unfortunately, ``six.b`` is insufficient for this task since in
272+
Python2 it does not modify ``unicode`` objects.
273+
274+
:type value: str / bytes or unicode
275+
:param value: The string/bytes value to be converted.
276+
277+
:type encoding: str
278+
:param encoding: The encoding to use to convert unicode to bytes. Defaults
279+
to "ascii", which will not allow any characters from
280+
ordinals larger than 127. Other useful values are
281+
"latin-1", which which will only allows byte ordinals
282+
(up to 255) and "utf-8", which will encode any unicode
283+
that needs to be.
284+
285+
:rtype: str / bytes
286+
:returns: The original value converted to bytes (if unicode) or as passed
287+
in if it started out as bytes.
288+
:raises: :class:`TypeError <exceptions.TypeError>` if the value
289+
could not be converted to bytes.
290+
"""
291+
result = (value.encode(encoding)
292+
if isinstance(value, six.text_type) else value)
293+
if isinstance(result, six.binary_type):
294+
return result
295+
else:
296+
raise TypeError('%r could not be converted to bytes' % (value,))
297+
298+
267299
try:
268300
from pytz import UTC # pylint: disable=unused-import
269301
except ImportError:

gcloud/bigtable/client.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from gcloud.bigtable._generated import bigtable_table_service_pb2
3535
from gcloud.bigtable._generated import operations_pb2
3636
from gcloud.bigtable._helpers import make_stub
37+
from gcloud.bigtable.cluster import Cluster
3738
from gcloud.client import _ClientFactoryMixin
3839
from gcloud.client import _ClientProjectMixin
3940
from gcloud.credentials import get_credentials
@@ -349,3 +350,28 @@ def stop(self):
349350
self._cluster_stub_internal = None
350351
self._operations_stub_internal = None
351352
self._table_stub_internal = None
353+
354+
def cluster(self, zone, cluster_id, display_name=None, serve_nodes=3):
355+
"""Factory to create a cluster associated with this client.
356+
357+
:type zone: str
358+
:param zone: The name of the zone where the cluster resides.
359+
360+
:type cluster_id: str
361+
:param cluster_id: The ID of the cluster.
362+
363+
:type display_name: str
364+
:param display_name: (Optional) The display name for the cluster in the
365+
Cloud Console UI. (Must be between 4 and 30
366+
characters.) If this value is not set in the
367+
constructor, will fall back to the cluster ID.
368+
369+
:type serve_nodes: int
370+
:param serve_nodes: (Optional) The number of nodes in the cluster.
371+
Defaults to 3.
372+
373+
:rtype: :class:`.Cluster`
374+
:returns: The cluster owned by this client.
375+
"""
376+
return Cluster(zone, cluster_id, self,
377+
display_name=display_name, serve_nodes=serve_nodes)

gcloud/bigtable/cluster.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""User friendly container for Google Cloud Bigtable Cluster."""
16+
17+
18+
from gcloud.bigtable.table import Table
19+
20+
21+
class Cluster(object):
22+
"""Representation of a Google Cloud Bigtable Cluster.
23+
24+
:type zone: str
25+
:param zone: The name of the zone where the cluster resides.
26+
27+
:type cluster_id: str
28+
:param cluster_id: The ID of the cluster.
29+
30+
:type client: :class:`.client.Client`
31+
:param client: The client that owns the cluster. Provides
32+
authorization and a project ID.
33+
34+
:type display_name: str
35+
:param display_name: (Optional) The display name for the cluster in the
36+
Cloud Console UI. (Must be between 4 and 30
37+
characters.) If this value is not set in the
38+
constructor, will fall back to the cluster ID.
39+
40+
:type serve_nodes: int
41+
:param serve_nodes: (Optional) The number of nodes in the cluster.
42+
Defaults to 3.
43+
"""
44+
45+
def __init__(self, zone, cluster_id, client,
46+
display_name=None, serve_nodes=3):
47+
self.zone = zone
48+
self.cluster_id = cluster_id
49+
self.display_name = display_name or cluster_id
50+
self.serve_nodes = serve_nodes
51+
self._client = client
52+
53+
def table(self, table_id):
54+
"""Factory to create a table associated with this cluster.
55+
56+
:type table_id: str
57+
:param table_id: The ID of the table.
58+
59+
:rtype: :class:`Table <gcloud.bigtable.table.Table>`
60+
:returns: The table owned by this cluster.
61+
"""
62+
return Table(table_id, self)

gcloud/bigtable/column_family.py

Lines changed: 31 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""User friendly container for Google Cloud Bigtable Column Family."""
16+
17+
18+
class ColumnFamily(object):
19+
"""Representation of a Google Cloud Bigtable Column Family.
20+
21+
:type column_family_id: str
22+
:param column_family_id: The ID of the column family. Must be of the
23+
form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
24+
25+
:type table: :class:`Table <gcloud_bigtable.table.Table>`
26+
:param table: The table that owns the column family.
27+
"""
28+
29+
def __init__(self, column_family_id, table):
30+
self.column_family_id = column_family_id
31+
self._table = table

gcloud/bigtable/row.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""User friendly container for Google Cloud Bigtable Row."""
16+
17+
18+
from gcloud._helpers import _to_bytes
19+
20+
21+
class Row(object):
22+
"""Representation of a Google Cloud Bigtable Row.
23+
24+
:type row_key: bytes
25+
:param row_key: The key for the current row.
26+
27+
:type table: :class:`Table <gcloud_bigtable.table.Table>`
28+
:param table: The table that owns the row.
29+
"""
30+
31+
def __init__(self, row_key, table):
32+
self._row_key = _to_bytes(row_key)
33+
self._table = table

gcloud/bigtable/table.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""User friendly container for Google Cloud Bigtable Table."""
16+
17+
18+
from gcloud.bigtable.column_family import ColumnFamily
19+
from gcloud.bigtable.row import Row
20+
21+
22+
class Table(object):
23+
"""Representation of a Google Cloud Bigtable Table.
24+
25+
:type table_id: str
26+
:param table_id: The ID of the table.
27+
28+
:type cluster: :class:`.cluster.Cluster`
29+
:param cluster: The cluster that owns the table.
30+
"""
31+
32+
def __init__(self, table_id, cluster):
33+
self.table_id = table_id
34+
self._cluster = cluster
35+
36+
def column_family(self, column_family_id):
37+
"""Factory to create a column family associated with this table.
38+
39+
:type column_family_id: str
40+
:param column_family_id: The ID of the column family. Must be of the
41+
form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
42+
43+
:rtype: :class:`.column_family.ColumnFamily`
44+
:returns: A column family owned by this table.
45+
"""
46+
return ColumnFamily(column_family_id, self)
47+
48+
def row(self, row_key):
49+
"""Factory to create a row associated with this table.
50+
51+
:type row_key: bytes
52+
:param row_key: The key for the row being created.
53+
54+
:rtype: :class:`.Row`
55+
:returns: A row owned by this table.
56+
"""
57+
return Row(row_key, self)

gcloud/bigtable/test_client.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,26 @@ def test_stop_while_stopped(self):
474474
# Make sure the cluster stub did not change.
475475
self.assertEqual(client._cluster_stub_internal, cluster_stub)
476476

477+
def test_cluster_factory(self):
478+
from gcloud.bigtable.cluster import Cluster
479+
480+
credentials = _Credentials()
481+
project = 'PROJECT'
482+
client = self._makeOne(project=project, credentials=credentials)
483+
484+
zone = 'zone'
485+
cluster_id = 'cluster-id'
486+
display_name = 'display-name'
487+
serve_nodes = 42
488+
cluster = client.cluster(zone, cluster_id, display_name=display_name,
489+
serve_nodes=serve_nodes)
490+
self.assertTrue(isinstance(cluster, Cluster))
491+
self.assertEqual(cluster.zone, zone)
492+
self.assertEqual(cluster.cluster_id, cluster_id)
493+
self.assertEqual(cluster.display_name, display_name)
494+
self.assertEqual(cluster.serve_nodes, serve_nodes)
495+
self.assertTrue(cluster._client is client)
496+
477497

478498
class _Credentials(object):
479499

gcloud/bigtable/test_cluster.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
import unittest2
17+
18+
19+
class TestCluster(unittest2.TestCase):
20+
21+
def _getTargetClass(self):
22+
from gcloud.bigtable.cluster import Cluster
23+
return Cluster
24+
25+
def _makeOne(self, *args, **kwargs):
26+
return self._getTargetClass()(*args, **kwargs)
27+
28+
def test_constructor_defaults(self):
29+
zone = 'zone'
30+
cluster_id = 'cluster-id'
31+
client = object()
32+
33+
cluster = self._makeOne(zone, cluster_id, client)
34+
self.assertEqual(cluster.zone, zone)
35+
self.assertEqual(cluster.cluster_id, cluster_id)
36+
self.assertEqual(cluster.display_name, cluster_id)
37+
self.assertEqual(cluster.serve_nodes, 3)
38+
self.assertTrue(cluster._client is client)
39+
40+
def test_constructor_non_default(self):
41+
zone = 'zone'
42+
cluster_id = 'cluster-id'
43+
display_name = 'display_name'
44+
serve_nodes = 8
45+
client = object()
46+
47+
cluster = self._makeOne(zone, cluster_id, client,
48+
display_name=display_name,
49+
serve_nodes=serve_nodes)
50+
self.assertEqual(cluster.zone, zone)
51+
self.assertEqual(cluster.cluster_id, cluster_id)
52+
self.assertEqual(cluster.display_name, display_name)
53+
self.assertEqual(cluster.serve_nodes, serve_nodes)
54+
self.assertTrue(cluster._client is client)
55+
56+
def test_table_factory(self):
57+
from gcloud.bigtable.table import Table
58+
59+
zone = 'zone'
60+
cluster_id = 'cluster-id'
61+
cluster = self._makeOne(zone, cluster_id, None)
62+
63+
table_id = 'table_id'
64+
table = cluster.table(table_id)
65+
self.assertTrue(isinstance(table, Table))
66+
self.assertEqual(table.table_id, table_id)
67+
self.assertEqual(table._cluster, cluster)

gcloud/bigtable/test_column_family.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
import unittest2
17+
18+
19+
class TestColumnFamily(unittest2.TestCase):
20+
21+
def _getTargetClass(self):
22+
from gcloud.bigtable.column_family import ColumnFamily
23+
return ColumnFamily
24+
25+
def _makeOne(self, *args, **kwargs):
26+
return self._getTargetClass()(*args, **kwargs)
27+
28+
def test_constructor(self):
29+
column_family_id = u'column-family-id'
30+
table = object()
31+
column_family = self._makeOne(column_family_id, table)
32+
33+
self.assertEqual(column_family.column_family_id, column_family_id)
34+
self.assertTrue(column_family._table is table)

0 commit comments

Comments
 (0)
0