From 1ebdec6d059f6a42ecd565f478c3cecd79590bb3 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Sun, 2 Feb 2014 02:21:11 -0800 Subject: [PATCH] Added DemoRunner and cleaned up demo scripts. --- gcloud/datastore/demo.py | 109 -------------------------- gcloud/datastore/demo/__init__.py | 14 ++++ gcloud/datastore/demo/__main__.py | 5 ++ gcloud/datastore/{ => demo}/demo.key | Bin gcloud/datastore/demo/demo.py | 81 +++++++++++++++++++ gcloud/demo.py | 108 ++++++++++++++++++++++++++ gcloud/storage/demo.py | 112 --------------------------- gcloud/storage/demo/__init__.py | 14 ++++ gcloud/storage/demo/__main__.py | 5 ++ gcloud/storage/{ => demo}/demo.key | Bin gcloud/storage/demo/demo.py | 39 ++++++++++ 11 files changed, 266 insertions(+), 221 deletions(-) delete mode 100644 gcloud/datastore/demo.py create mode 100644 gcloud/datastore/demo/__init__.py create mode 100644 gcloud/datastore/demo/__main__.py rename gcloud/datastore/{ => demo}/demo.key (100%) create mode 100644 gcloud/datastore/demo/demo.py create mode 100644 gcloud/demo.py delete mode 100644 gcloud/storage/demo.py create mode 100644 gcloud/storage/demo/__init__.py create mode 100644 gcloud/storage/demo/__main__.py rename gcloud/storage/{ => demo}/demo.key (100%) create mode 100644 gcloud/storage/demo/demo.py diff --git a/gcloud/datastore/demo.py b/gcloud/datastore/demo.py deleted file mode 100644 index e8c2400b6da5..000000000000 --- a/gcloud/datastore/demo.py +++ /dev/null @@ -1,109 +0,0 @@ -import os.path - -import gcloud.datastore -from gcloud.datastore.key import Key - - -__all__ = ['CLIENT_EMAIL', 'DATASET_ID', 'PRIVATE_KEY_PATH', - 'get_dataset', 'main'] - - -DATASET_ID = 'gcloud-datastore-demo' -CLIENT_EMAIL = '754762820716-gimou6egs2hq1rli7el2t621a1b04t9i@developer.gserviceaccount.com' -PRIVATE_KEY_PATH = os.path.dirname(gcloud.datastore.__file__) + '/demo.key' - - -def get_dataset(): - """A helper method to be used in a Python console.""" - - return gcloud.datastore.get_dataset( - DATASET_ID, CLIENT_EMAIL, PRIVATE_KEY_PATH) - - -def main(): - """A full example script demonstrating how to use the client.""" - - # Establish a connection to use for querying. - connection = gcloud.datastore.get_connection(CLIENT_EMAIL, PRIVATE_KEY_PATH) - dataset = connection.dataset(DATASET_ID) - - print '\nCreating a new Thing called Toy...' - toy = dataset.entity('Thing') - toy.update({'name': 'Toy', 'some_int_value': 1234}) - toy.save() - - print '\nLooking up the Toy...' - print dataset.get_entities([toy.key()]) - - print '\nDeleting the Toy...' - toy.delete() - - print '\nLooking up the Toy again (this should be empty)...' - print dataset.get_entities([toy.key()]) - - query = dataset.query().kind('Thing') - - print '\nShowing first 2 Things...' - print query.limit(2).fetch() - - print '\nShowing Things named Computer...' - print query.filter('name =', 'Computer').fetch() - - print '\nFilter by multiple things...' - print query.filter('name =', 'Computer').filter( - 'my_int_value =', 1234).fetch() - - print '\nStarting a transaction...' - with dataset.transaction(): - print 'Creating and savng an entity...' - thing = dataset.entity('Thing') - thing.key(thing.key().name('foo')) - thing['age'] = 10 - thing.save() - - print 'Creating and saving another entity...' - thing2 = dataset.entity('Thing') - thing2.key(thing2.key().name('bar')) - thing2['age'] = 15 - thing2.save() - - print 'Committing the transaction...', - - print 'done.' - - print '\nDeleting the entities...' - print thing.delete(), thing2.delete() - - print '\nStarting another transaction...' - with dataset.transaction() as t: - print 'Creating an entity...' - thing = dataset.entity('Thing') - thing.key(thing.key().name('another')) - thing.save() - - print 'Rolling back the transaction...' - t.rollback() - - print 'Was the entity actually created? ... ', - - if dataset.get_entities([thing.key()]): - print 'yes.' - else: - print 'no.' - - print '\nStarting one more transaction...' - with dataset.transaction(): - print 'Creating a simple thing' - thing = dataset.entity('Thing') - thing.save() - - print 'Before committing, the key should be incomplete...', thing.key() - - print 'After committing, the key should be complete...', thing.key() - - print 'Deleting the entity...' - thing.delete() - - -if __name__ == '__main__': - main() diff --git a/gcloud/datastore/demo/__init__.py b/gcloud/datastore/demo/__init__.py new file mode 100644 index 000000000000..43ae28b8394b --- /dev/null +++ b/gcloud/datastore/demo/__init__.py @@ -0,0 +1,14 @@ +import os +from gcloud import datastore + + +__all__ = ['get_dataset', 'CLIENT_EMAIL', 'DATASET_ID', 'PRIVATE_KEY_PATH'] + + +CLIENT_EMAIL = '754762820716-gimou6egs2hq1rli7el2t621a1b04t9i@developer.gserviceaccount.com' +DATASET_ID = 'gcloud-datastore-demo' +PRIVATE_KEY_PATH = os.path.join(os.path.dirname(__file__), 'demo.key') + + +def get_dataset(): + return datastore.get_dataset(DATASET_ID, CLIENT_EMAIL, PRIVATE_KEY_PATH) diff --git a/gcloud/datastore/demo/__main__.py b/gcloud/datastore/demo/__main__.py new file mode 100644 index 000000000000..69b07aee5281 --- /dev/null +++ b/gcloud/datastore/demo/__main__.py @@ -0,0 +1,5 @@ +from gcloud import demo +from gcloud import datastore + + +demo.DemoRunner.from_module(datastore).run() diff --git a/gcloud/datastore/demo.key b/gcloud/datastore/demo/demo.key similarity index 100% rename from gcloud/datastore/demo.key rename to gcloud/datastore/demo/demo.key diff --git a/gcloud/datastore/demo/demo.py b/gcloud/datastore/demo/demo.py new file mode 100644 index 000000000000..1818f8547b4e --- /dev/null +++ b/gcloud/datastore/demo/demo.py @@ -0,0 +1,81 @@ +# Welcome to the gCloud Datastore Demo! (hit enter) + +# We're going to walk through some of the basics... +# Don't worry though. You don't need to do anything, just keep hitting enter... + +# Let's start by importing the demo module and getting a dataset: +from gcloud.datastore import demo +dataset = demo.get_dataset() + +# Let's create a new entity of type "Thing" and name it 'Toy': +toy = dataset.entity('Thing') +toy.update({'name': 'Toy'}) + +# Now let's save it to our datastore: +toy.save() + +# If we look it up by its key, we should find it... +print dataset.get_entities([toy.key()]) + +# And we should be able to delete it... +toy.delete() + +# Since we deleted it, if we do another lookup it shouldn't be there again: +print dataset.get_entities([toy.key()]) + +# Now let's try a more advanced query. +# We'll start by look at all Thing entities: +query = dataset.query().kind('Thing') + +# Let's look at the first two. +print query.limit(2).fetch() + +# Now let's check for Thing entities named 'Computer' +print query.filter('name =', 'Computer').fetch() + +# If you want to filter by multiple attributes, +# you can string .filter() calls together. +print query.filter('name =', 'Computer').filter('age =', 10).fetch() + +# You can also work inside a transaction. +# (Check the official docs for explanations of what's happening here.) +with dataset.transaction(): + print 'Creating and savng an entity...' + thing = dataset.entity('Thing') + thing.key(thing.key().name('foo')) + thing['age'] = 10 + thing.save() + + print 'Creating and saving another entity...' + thing2 = dataset.entity('Thing') + thing2.key(thing2.key().name('bar')) + thing2['age'] = 15 + thing2.save() + + print 'Committing the transaction...' + +# Now that the transaction is commited, let's delete the entities. +print thing.delete(), thing2.delete() + +# To rollback a transaction, just call .rollback() +with dataset.transaction() as t: + thing = dataset.entity('Thing') + thing.key(thing.key().name('another')) + thing.save() + t.rollback() + +# Let's check if the entity was actually created: +created = dataset.get_entities([thing.key()]) +print 'yes' if created else 'no' + +# Remember, a key won't be complete until the transaction is commited. +# That is, while inside the transaction block, thing.key() will be incomplete. +with dataset.transaction(): + thing = dataset.entity('Thing') + thing.save() + print thing.key() # This will be partial + +print thing.key() # This will be complete + +# Now let's delete the entity. +thing.delete() diff --git a/gcloud/demo.py b/gcloud/demo.py new file mode 100644 index 000000000000..40fe3b6869cc --- /dev/null +++ b/gcloud/demo.py @@ -0,0 +1,108 @@ +from code import interact +import itertools +import os.path +import sys +import time + + +class DemoRunner(object): + """An interactive runner of demo scripts.""" + + KEYPRESS_DELAY = 0.05 + GLOBALS, LOCALS = globals(), locals() + CODE, COMMENT = 'code', 'comment' + + def __init__(self, fp): + self.lines = [line.rstrip() for line in fp.readlines()] + + @classmethod + def from_module(cls, module): + path = os.path.join(os.path.dirname(module.__file__), + 'demo', 'demo.py') + + return cls(open(path, 'r')) + + def run(self): + line_groups = itertools.groupby(self.lines, self.get_line_type) + + for group_type, lines in line_groups: + if group_type == self.COMMENT: + self.write(lines) + + elif group_type == self.CODE: + self.code(lines) + + interact('(Hit CTRL-D to exit...)', local=self.LOCALS) + + def wait(self): + raw_input() + + @classmethod + def get_line_type(cls, line): + if line.startswith('#'): + return cls.COMMENT + else: + return cls.CODE + + @staticmethod + def get_indent_level(line): + if not line.strip(): + return None + return len(line) - len(line.lstrip()) + + def write(self, lines): + print + print '\n'.join(lines), + self.wait() + + def code(self, lines): + code_lines = [] + + for line in lines: + indent = self.get_indent_level(line) + + # If we've completed a block, + # run whatever code was built up in code_lines. + if indent == 0: + self._execute_lines(code_lines) + code_lines = [] + + # Print the prefix for the line depending on the indentation level. + if indent == 0: + print '>>> ', + elif indent > 0: + print '\n... ', + elif indent is None: + continue + + # Break the line into the code section and the comment section. + if '#' in line: + code, comment = line.split('#', 2) + else: + code, comment = line, None + + # 'Type' out the comment section. + for char in code.rstrip(): + time.sleep(self.KEYPRESS_DELAY) + sys.stdout.write(char) + sys.stdout.flush() + + # Print the comment section (not typed out). + if comment: + sys.stdout.write(' # %s' % comment.strip()) + + # Add the current line to the list of lines to be run in this block. + code_lines.append(line) + + # If we had any code built up that wasn't part of a completed block + # (ie, the lines ended with an indented line), + # run that code. + if code_lines: + self._execute_lines(code_lines) + + def _execute_lines(self, lines): + if lines: + self.wait() + + # Yes, this is crazy unsafe... but it's demo code. + exec('\n'.join(lines), self.GLOBALS, self.LOCALS) diff --git a/gcloud/storage/demo.py b/gcloud/storage/demo.py deleted file mode 100644 index f701d14d8060..000000000000 --- a/gcloud/storage/demo.py +++ /dev/null @@ -1,112 +0,0 @@ -from code import interact -import os.path -import sys -import time - -from gcloud import storage - - -__all__ = ['CLIENT_EMAIL', 'PRIVATE_KEY_PATH', 'PROJECT_NAME', - 'get_connection', 'main'] - - -CLIENT_EMAIL = '606734090113-6ink7iugcv89da9sru7lii8bs3i0obqg@developer.gserviceaccount.com' -PRIVATE_KEY_PATH = os.path.join(os.path.dirname(storage.__file__), 'demo.key') -PROJECT_NAME = 'gcloud-storage-demo' - -extra_newline = False -code_globals, code_locals = globals(), locals() - - -def get_connection(): - return storage.get_connection(PROJECT_NAME, CLIENT_EMAIL, PRIVATE_KEY_PATH) - - -def write(*strings): - # Add an extra newline if necessary. - global extra_newline - if extra_newline: - print - - for string in strings: - print string - raw_input() - - # We don't need an extra newline after this. - extra_newline = False - - -def code(string, comment=None): - keypress_time = 0.05 - - print '>>> ', - for char in string: - time.sleep(keypress_time) - sys.stdout.write(char) - sys.stdout.flush() - - if comment: - sys.stdout.write(' # %s' % comment) - - # Wait for an enter key before continuing... - raw_input() - - # Yes, this is crazy unsafe... but it's demo code. - # Globalize these so our imports hang around... - global code_globals - global code_locals - exec(string, code_globals, code_locals) - - # In the next non-code piece, we need an extra newline. - global extra_newline - extra_newline = True - - -def main(): - write('Welcome to the gCloud Storage Demo! (hit enter)') - write('We\'re going to walk through some of the basics...', - 'Don\'t worry though. You don\'t need to do anything, just keep hitting enter...') - - write('Let\'s start by importing the demo module and getting a connection:') - code('from gcloud.storage import demo') - code('connection = demo.get_connection()') - - write('OK, now let\'s look at all of the buckets...') - code('print connection.get_all_buckets()', - 'This might take a second...') - - write('Now let\'s create a new bucket...') - code('import time') - code('bucket_name = ("bucket-%s" % time.time()).replace(".", "")', - 'Get rid of dots...') - code('print bucket_name') - code('bucket = connection.create_bucket(bucket_name)') - code('print bucket') - - write('Let\'s look at all of the buckets again...') - code('print connection.get_all_buckets()') - - write('How about we create a new key inside this bucket.') - code('key = bucket.new_key("my-new-file.txt")') - - write('Now let\'s put some data in there.') - code('key.set_contents_from_string("this is some data!")') - - write('... and we can read that data back again.') - code('print key.get_contents_as_string()') - - write('Now let\'s delete that key.') - code('print key.delete()') - - write('And now that we\'re done, let\'s delete that bucket...') - code('print bucket.delete()') - - write('Alright! That\'s all!', - 'Here\'s an interactive prompt for you now...') - - global code_locals - interact('(Hit CTRL-D to exit...)', local=code_locals) - - -if __name__ == '__main__': - main() diff --git a/gcloud/storage/demo/__init__.py b/gcloud/storage/demo/__init__.py new file mode 100644 index 000000000000..13d862564fc9 --- /dev/null +++ b/gcloud/storage/demo/__init__.py @@ -0,0 +1,14 @@ +import os +from gcloud import storage + + +__all__ = ['get_connection', 'CLIENT_EMAIL', 'PRIVATE_KEY_PATH', 'PROJECT_NAME'] + + +CLIENT_EMAIL = '606734090113-6ink7iugcv89da9sru7lii8bs3i0obqg@developer.gserviceaccount.com' +PRIVATE_KEY_PATH = os.path.join(os.path.dirname(__file__), 'demo.key') +PROJECT_NAME = 'gcloud-storage-demo' + + +def get_connection(): + return storage.get_connection(PROJECT_NAME, CLIENT_EMAIL, PRIVATE_KEY_PATH) diff --git a/gcloud/storage/demo/__main__.py b/gcloud/storage/demo/__main__.py new file mode 100644 index 000000000000..e02f2c06dad2 --- /dev/null +++ b/gcloud/storage/demo/__main__.py @@ -0,0 +1,5 @@ +from gcloud import demo +from gcloud import storage + + +demo.DemoRunner.from_module(storage).run() diff --git a/gcloud/storage/demo.key b/gcloud/storage/demo/demo.key similarity index 100% rename from gcloud/storage/demo.key rename to gcloud/storage/demo/demo.key diff --git a/gcloud/storage/demo/demo.py b/gcloud/storage/demo/demo.py new file mode 100644 index 000000000000..e0eb0c4b0a67 --- /dev/null +++ b/gcloud/storage/demo/demo.py @@ -0,0 +1,39 @@ +# Welcome to the gCloud Storage Demo! (hit enter) + +# We're going to walk through some of the basics..., +# Don't worry though. You don't need to do anything, just keep hitting enter... + +# Let's start by importing the demo module and getting a connection: +from gcloud.storage import demo +connection = demo.get_connection() + +# OK, now let's look at all of the buckets... +print connection.get_all_buckets() # This might take a second... + +# Now let's create a new bucket... +import time +bucket_name = ("bucket-%s" % time.time()).replace(".", "") # Get rid of dots... +print bucket_name +bucket = connection.create_bucket(bucket_name) +print bucket + +# Let's look at all of the buckets again... +print connection.get_all_buckets() + +# How about we create a new key inside this bucket. +key = bucket.new_key("my-new-file.txt") + +# Now let's put some data in there. +key.set_contents_from_string("this is some data!") + +# ... and we can read that data back again. +print key.get_contents_as_string() + +# Now let's delete that key. +print key.delete() + +# And now that we're done, let's delete that bucket... +print bucket.delete() + +# Alright! That's all! +# Here's an interactive prompt for you now...