Skip to content

Commit

Permalink
Add Bigtable hello world sample.
Browse files Browse the repository at this point in the history
  • Loading branch information
tswast committed Jun 8, 2016
1 parent f67e7c2 commit 50609c4
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 4 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[run]
include =
appengine/*
bigtable/*
bigquery/*
blog/*
cloud_logging/*
Expand Down
67 changes: 67 additions & 0 deletions bigtable/hello/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Cloud Bigtable Hello World

This is a simple application that demonstrates using the [Google Cloud Client
Library][gcloud-python] to connect to and interact with Cloud Bigtable.

[gcloud-python]: https://github.com/GoogleCloudPlatform/gcloud-python


## Provision a cluster

Follow the instructions in the [user documentation](https://cloud.google.com/bigtable/docs/creating-cluster)
to create a Google Cloud Platform project and Cloud Bigtable cluster if necessary.
You'll need to reference your project ID, zone and cluster ID to run the application.


## Run the application

First, set your [Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials)

Install the dependencies with pip.

```
$ pip install -r requirements.txt
```

Run the application. Replace the command-line parameters with values for your cluster.

```
$ python main.py my-project my-cluster us-central1-c
```

You will see output resembling the following:

```
Create table Hello-Bigtable-1234
Write some greetings to the table
Scan for all greetings:
greeting0: Hello World!
greeting1: Hello Cloud Bigtable!
greeting2: Hello HappyBase!
Delete table Hello-Bigtable-1234
```

## Understanding the code

The [application](main.py) uses the [Google Cloud Bigtable HappyBase
package][Bigtable HappyBase], an implementation of the [HappyBase][HappyBase]
library, to make calls to Cloud Bigtable. It demonstrates several basic
concepts of working with Cloud Bigtable via this API:

[Bigtable HappyBase]: https://googlecloudplatform.github.io/gcloud-python/stable/happybase-package.html
[HappyBase]: http://happybase.readthedocs.io/en/latest/index.html

- Creating a [Connection][HappyBase Connection] to a Cloud Bigtable
[Cluster][Cluster API].
- Using the [Connection][HappyBase Connection] interface to create, disable and
delete a [Table][HappyBase Table].
- Using the Connection to get a Table.
- Using the Table to write rows via a [put][HappyBase Table Put] and scan
across multiple rows using [scan][HappyBase Table Scan].

[Cluster API]: https://googlecloudplatform.github.io/gcloud-python/stable/bigtable-cluster.html
[HappyBase Connection]: https://googlecloudplatform.github.io/gcloud-python/stable/happybase-connection.html
[HappyBase Table]: https://googlecloudplatform.github.io/gcloud-python/stable/happybase-table.html
[HappyBase Table Put]: https://googlecloudplatform.github.io/gcloud-python/stable/happybase-table.html#gcloud.bigtable.happybase.table.Table.put
[HappyBase Table Scan]: https://googlecloudplatform.github.io/gcloud-python/stable/happybase-table.html#gcloud.bigtable.happybase.table.Table.scan

93 changes: 93 additions & 0 deletions bigtable/hello/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python

# Copyright 2016 Google Inc.
#
# 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.

"""Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites:
- Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster
- Set your Google Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-credentials
- Set the GCLOUD_PROJECT environment variable to your project ID.
https://support.google.com/cloud/answer/6158840
"""

import argparse

from gcloud import bigtable
from gcloud.bigtable import happybase


def main(project, cluster_id, zone, table_name):
column_family_name = 'cf1'
column_name = '{fam}:greeting'.format(fam=column_family_name)
greetings = [
'Hello World!',
'Hello Cloud Bigtable!',
'Hello HappyBase!',
]

# The client must be created with admin=True because it will create a
# table.
client = bigtable.Client(project=project, admin=True)

with client:
cluster = client.cluster(zone, cluster_id)
cluster.reload()
connection = happybase.Connection(cluster=cluster)

print('Creating the {} table.'.format(table_name))
connection.create_table(
table_name,
{
column_family_name: dict() # Use default options.
})
table = connection.table(table_name)

print('Writing some greetings to the table.')
for i, value in enumerate(greetings):
row_key = 'greeting{}'.format(i)
table.put(row_key, {column_name: value})

print('Scanning for all greetings:')
for key, row in table.scan():
print('\t{}: {}'.format(key, row[column_name]))

print('Deleting the {} table.'.format(table_name))
connection.delete_table(table_name)


if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='A sample application that connects to Cloud' +
' Bigtable.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'project',
help='Google Cloud Platform project ID that contains the Cloud' +
' Bigtable cluster.')
parser.add_argument(
'cluster', help='ID of the Cloud Bigtable cluster to connect to.')
parser.add_argument(
'zone', help='Zone that contains the Cloud Bigtable cluster.')
parser.add_argument(
'--table',
help='Table to create and destroy.',
default='Hello-Bigtable')

args = parser.parse_args()
main(args.project, args.cluster, args.zone, args.table)
47 changes: 47 additions & 0 deletions bigtable/hello/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2016 Google Inc.
#
# 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 random
import re
import sys

from hello import main

import pytest

TABLE_NAME_FORMAT = 'Hello-Bigtable-{}'
TABLE_NAME_RANGE = 10000


@pytest.mark.skipif(
sys.version_info >= (3, 0),
reason=("grpc doesn't yet support python3 "
'https://github.com/grpc/grpc/issues/282'))
def test_main(cloud_config, capsys):
table_name = TABLE_NAME_FORMAT.format(
random.randrange(TABLE_NAME_RANGE))
main(
cloud_config.project,
cloud_config.bigtable_cluster,
cloud_config.bigtable_zone,
table_name)

out, _ = capsys.readouterr()
assert re.search(
re.compile(r'Creating the Hello-Bigtable-[0-9]+ table\.'), out)
assert re.search(re.compile(r'Writing some greetings to the table\.'), out)
assert re.search(re.compile(r'Scanning for all greetings'), out)
assert re.search(re.compile(r'greeting0: Hello World!'), out)
assert re.search(
re.compile(r'Deleting the Hello-Bigtable-[0-9]+ table\.'), out)
1 change: 1 addition & 0 deletions bigtable/hello/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gcloud[grpc]==0.14.0
4 changes: 3 additions & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def cloud_config():
return Namespace(
project=os.environ.get('GCLOUD_PROJECT'),
storage_bucket=os.environ.get('CLOUD_STORAGE_BUCKET'),
client_secrets=os.environ.get('GOOGLE_CLIENT_SECRETS'))
client_secrets=os.environ.get('GOOGLE_CLIENT_SECRETS'),
bigtable_cluster=os.environ.get('BIGTABLE_CLUSTER'),
bigtable_zone=os.environ.get('BIGTABLE_ZONE'))


def get_resource_path(resource, local_path):
Expand Down
9 changes: 7 additions & 2 deletions nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@
'-x', '--no-success-flaky-report', '--cov', '--cov-config',
'.coveragerc', '--cov-append', '--cov-report=']

# Speech is temporarily disabled.
TESTS_BLACKLIST = set(('./appengine/standard', './testing', './speech'))
# Bigtable and Speech are disabled because they use gRPC, which does not yet
# support Python 3. See: https://github.com/grpc/grpc/issues/282
TESTS_BLACKLIST = set((
'./appengine/standard',
'./bigtable',
'./speech',
'./testing'))
APPENGINE_BLACKLIST = set()


Expand Down
8 changes: 7 additions & 1 deletion scripts/prepare-testing-project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ echo "Creating cloud storage bucket."
gsutil mb gs://$GCLOUD_PROJECT
gsutil defacl set public-read gs://$GCLOUD_PROJECT

echo "Creating bigtable resources."
gcloud alpha bigtable clusters create bigtable-test \
--description="Test cluster" \
--nodes=3 \
--zone=us-central1-c

echo "Creating bigquery resources."
gcloud alpha bigquery datasets create test_dataset
gcloud alpha bigquery datasets create ephemeral_test_dataset
Expand All @@ -38,4 +44,4 @@ echo "Creating pubsub resources."
gcloud alpha pubsub topics create gae-mvm-pubsub-topic

echo "To finish setup, follow this link to enable APIs."
echo "https://console.cloud.google.com/flows/enableapi?project=${GCLOUD_PROJECT}&apiid=bigquery,cloudmonitoring,compute_component,datastore,datastore.googleapis.com,dataproc,dns,plus,pubsub,logging,storage_api,vision.googleapis.com"
echo "https://console.cloud.google.com/flows/enableapi?project=${GCLOUD_PROJECT}&apiid=bigtable,bigtableclusteradmin,bigtabletableadmin,bigquery,cloudmonitoring,compute_component,datastore,datastore.googleapis.com,dataproc,dns,plus,pubsub,logging,storage_api,vision.googleapis.com"
2 changes: 2 additions & 0 deletions testing/resources/test-env.tmpl.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Environment variables for system tests.
export GCLOUD_PROJECT=your-project-id
export CLOUD_STORAGE_BUCKET=$GCLOUD_PROJECT
export BIGTABLE_CLUSTER=bigtable-test
export BIGTABLE_ZONE=us-central1-c

# Environment variables for App Engine Flexible system tests.
export GA_TRACKING_ID=
Expand Down

0 comments on commit 50609c4

Please sign in to comment.