8000 Adding Bigtable factories and shell classes. by dhermes · Pull Request #1229 · googleapis/google-cloud-python · GitHub
[go: up one dir, main page]

Skip to content

Adding Bigtable factories and shell classes. #1229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 32 additions & 0 deletions gcloud/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import calendar
import datetime
import os
import six
import socket

try:
Expand Down Expand Up @@ -264,6 +265,37 @@ def _millis_from_datetime(value):
return _millis(value)


def _to_bytes(value, encoding='ascii'):
"""Converts a string value to bytes, if necessary.

Unfortunately, ``six.b`` is insufficient for this task since in
Python2 it does not modify ``unicode`` objects.

:type value: str / bytes or unicode
:param value: The string/bytes value to be converted.

:type encoding: str
:param encoding: The encoding to use to convert unicode to bytes. Defaults
to "ascii", which will not allow any characters from
ordinals larger than 127. Other useful values are
"latin-1", which which will only allows byte ordinals
(up to 255) and "utf-8", which will encode any unicode
that needs to be.

:rtype: str / bytes
:returns: The original value converted to bytes (if unicode) or as passed
in if it started out as bytes.
:raises: :class:`TypeError <exceptions.TypeError>` if the value
could not be converted to bytes.
"""
result = (value.encode(encoding)
if isinstance(value, six.text_type) else value)
if isinstance(result, six.binary_type):
return result
else:
raise TypeError('%r could not be converted to bytes' % (value,))


try:
from pytz import UTC # pylint: disable=unused-import
except ImportError:
Expand Down
26 changes: 26 additions & 0 deletions gcloud/bigtable/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from gcloud.bigtable._generated import bigtable_table_service_pb2
from gcloud.bigtable._generated import operations_pb2
from gcloud.bigtable._helpers import make_stub
from gcloud.bigtable.cluster import Cluster
from gcloud.client import _ClientFactoryMixin
from gcloud.client import _ClientProjectMixin
from gcloud.credentials import get_credentials
Expand Down Expand Up @@ -349,3 +350,28 @@ def stop(self):
self._cluster_stub_internal = None
self._operations_stub_internal = None
self._table_stub_internal = None

def cluster(self, zone, cluster_id, display_name=None, serve_nodes=3):
"""Factory to create a cluster associated with this client.

:type zone: str
:param zone: The name of the zone where the cluster resides.

:type cluster_id: str
:param cluster_id: The ID of the cluster.

:type display_name: str
:param display_name: (Optional) The display name for the cluster in the
Cloud Console UI. (Must be between 4 and 30
characters.) If this value is not set in the
constructor, will fall back to the cluster ID.

:type serve_nodes: int
:param serve_nodes: (Optional) The number of nodes in the cluster.
Defaults to 3.

:rtype: :class:`.Cluster`
:returns: The cluster owned by this client.
"""
return Cluster(zone, cluster_id, self,
display_name=display_name, serve_nodes=serve_nodes)
62 changes: 62 additions & 0 deletions gcloud/bigtable/cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""User friendly container for Google Cloud Bigtable Cluster."""


from gcloud.bigtable.table import Table


class Cluster(object):
"""Representation of a Google Cloud Bigtable Cluster.

:type zone: str
:param zone: The name of the zone where the cluster resides.

:type cluster_id: str
:param cluster_id: The ID of the cluster.

:type client: :class:`.client.Client`
:param client: The client that owns the cluster. Provides
authorization and a project ID.

:type display_name: str
:param display_name: (Optional) The display name for the cluster in the
Cloud Console UI. (Must be between 4 and 30
characters.) If this value is not set in the
constructor, will fall back to the cluster ID.

:type serve_nodes: int
:param serve_nodes: (Optional) The number of nodes in the cluster.
Defaults to 3.
"""

def __init__(self, zone, cluster_id, client,
display_name=None, serve_nodes=3):
self.zone = zone
self.cluster_id = cluster_id
self.display_name = display_name or cluster_id
self.serve_nodes = serve_nodes
self._client = client

def table(self, table_id):
"""Factory to create a table associated with this cluster.

:type table_id: str
:param table_id: The ID of the table.

:rtype: :class:`Table <gcloud.bigtable.table.Table>`
:returns: The table owned by this cluster.
"""
return Table(table_id, self)
31 changes: 31 additions & 0 deletions gcloud/bigtable/column_family.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""User friendly container for Google Cloud Bigtable Column Family."""


class ColumnFamily(object):
"""Representation of a Google Cloud Bigtable Column Family.

:type column_family_id: str
:param column_family_id: The ID of the column family. Must be of the
form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.

:type table: :class:`Table <gcloud_bigtable.table.Table>`
:param table: The table that owns the column family.
"""

def __init__(self, column_family_id, table):
self.column_family_id = column_family_id
self._table = table
33 changes: 33 additions & 0 deletions gcloud/bigtable/row.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""User friendly container for Google Cloud Bigtable Row."""


from gcloud._helpers import _to_bytes


class Row(object):
"""Representation of a Google Cloud Bigtable Row.

:type row_key: bytes
:param row_key: The key for the current row.

:type table: :class:`Table <gcloud_bigtable.table.Table>`
:param table: The table that owns the row.
"""

def __init__(self, row_key, table):
self._row_key = _to_bytes(row_key)
self._table = table
57 changes: 57 additions & 0 deletions gcloud/bigtable/table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""User friendly container for Google Cloud Bigtable Table."""


from gcloud.bigtable.column_family import ColumnFamily
from gcloud.bigtable.row import Row


class Table(object):
"""Representation of a Google Cloud Bigtable Table.

:type table_id: str
:param table_id: The ID of the table.

:type cluster: :class:`.cluster.Cluster`
:param cluster: The cluster that owns the table.
"""

def __init__(self, table_id, cluster):
self.table_id = table_id
self._cluster = cluster

def column_family(self, column_family_id):
"""Factory to create a column family associated with this table.

:type column_family_id: str
:param column_family_id: The ID of the column family. Must be of the
form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.

:rtype: :class:`.column_family.ColumnFamily`
:returns: A column family owned by this table.
"""
return ColumnFamily(column_family_id, self)

def row(self, row_key):
"""Factory to create a row associated with this table.

:type row_key: bytes
:param row_key: The key for the row being created.

:rtype: :class:`.Row`
:returns: A row owned by this table.
"""
return Row(row_key, self)
20 changes: 20 additions & 0 deletions gcloud/bigtable/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,26 @@ def test_stop_while_stopped(self):
# Make sure the cluster stub did not change.
self.assertEqual(client._cluster_stub_internal, cluster_stub)

def test_cluster_factory(self):
from gcloud.bigtable.cluster import Cluster

credentials = _Credentials()
project = 'PROJECT'
client = self._makeOne(project=project, credentials=credentials)

zone = 'zone'
cluster_id = 'cluster-id'
display_name = 'display-name'
serve_nodes = 42
cluster = client.cluster(zone, cluster_id, display_name=display_name,
serve_nodes=serve_nodes)
self.assertTrue(isinstance(cluster, Cluster))
self.assertEqual(cluster.zone, zone)
self.assertEqual(cluster.cluster_id, cluster_id)
self.assertEqual(cluster.display_name, display_name)
self.assertEqual(cluster.serve_nodes, serve_nodes)
self.assertTrue(cluster._client is client)


class _Credentials(object):

Expand Down
67 changes: 67 additions & 0 deletions gcloud/bigtable/test_cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import unittest2


class TestCluster(unittest2.TestCase):

def _getTargetClass(self):
from gcloud.bigtable.cluster import Cluster
return Cluster

def _makeOne(self, *args, **kwargs):
return self._getTargetClass()(*args, **kwargs)

def test_constructor_defaults(self):
zone = 'zone'
cluster_id = 'cluster-id'
client = object()

cluster = self._makeOne(zone, cluster_id, client)
self.assertEqual(cluster.zone, zone)
self.assertEqual(cluster.cluster_id, cluster_id)
self.assertEqual(cluster.display_name, cluster_id)
self.assertEqual(cluster.serve_nodes, 3)
self.assertTrue(cluster._client is client)

def test_constructor_non_default(self):
zone = 'zone'
cluster_id = 'cluster-id'
display_name = 'display_name'
serve_nodes = 8
client = object()

cluster = self._makeOne(zone, cluster_id, client,
display_name=display_name,
serve_nodes=serve_nodes)
self.assertEqual(cluster.zone, zone)
self.assertEqual(cluster.cluster_id, cluster_id)
self.assertEqual(cluster.display_name, display_name)
self.assertEqual(cluster.serve_nodes, serve_nodes)
self.assertTrue(cluster._client is client)

def test_table_factory(self):
from gcloud.bigtable.table import Table

zone = 'zone'
cluster_id = 'cluster-id'
cluster = self._makeOne(zone, cluster_id, None)

table_id = 'table_id'
table = cluster.table(table_id)
self.assertTrue(isinstance(table, Table))
self.assertEqual(table.table_id, table_id)
self.assertEqual(table._cluster, cluster)
34 changes: 34 additions & 0 deletions gcloud/bigtable/test_column_family.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import unittest2


class TestColumnFamily(unittest2.TestCase):

def _getTargetClass(self):
from gcloud.bigtable.column_family import ColumnFamily
return ColumnFamily

def _makeOne(self, *args, **kwargs):
return self._getTargetClass()(*args, **kwargs)

def test_constructor(self):
column_family_id = u'column-family-id'
table = object()
column_family = self._makeOne(column_family_id, table)

self.assertEqual(column_family.column_family_id, column_family_id)
self.assertTrue(column_family._table is table)
Loading
0