From 21a9e38b404e7bda98f2561b5191dff00b1b5c9a Mon Sep 17 00:00:00 2001 From: Jerjou Cheng Date: Mon, 25 Apr 2016 15:47:51 -0700 Subject: [PATCH] Add snippets for ndb/properties --- appengine/ndb/properties/README.md | 11 ++ appengine/ndb/properties/snippets.py | 150 ++++++++++++++++++++++ appengine/ndb/properties/snippets_test.py | 119 +++++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 appengine/ndb/properties/README.md create mode 100644 appengine/ndb/properties/snippets.py create mode 100644 appengine/ndb/properties/snippets_test.py diff --git a/appengine/ndb/properties/README.md b/appengine/ndb/properties/README.md new file mode 100644 index 000000000000..de937a8c994b --- /dev/null +++ b/appengine/ndb/properties/README.md @@ -0,0 +1,11 @@ +## App Engine Datastore NDB Properties Samples + +This contains snippets used in the NDB properties documentation, demonstrating +various operation on ndb properties. + + +These samples are used on the following documentation page: + +> https://cloud.google.com/appengine/docs/python/ndb/properties + + diff --git a/appengine/ndb/properties/snippets.py b/appengine/ndb/properties/snippets.py new file mode 100644 index 000000000000..9c98ac6701d1 --- /dev/null +++ b/appengine/ndb/properties/snippets.py @@ -0,0 +1,150 @@ +# Copyright 2016 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. + +# [START notestore_imports] +from google.appengine.ext import ndb +from google.appengine.ext.ndb import msgprop +# [END notestore_imports] +from protorpc import messages + + +class Account(ndb.Model): + username = ndb.StringProperty() + userid = ndb.IntegerProperty() + email = ndb.StringProperty() + + +class Employee(ndb.Model): + full_name = ndb.StringProperty('n') + retirement_age = ndb.IntegerProperty('r') + + +class Article(ndb.Model): + title = ndb.StringProperty() + stars = ndb.IntegerProperty() + tags = ndb.StringProperty(repeated=True) + + +def create_article(): + article = Article( + title='Python versus Ruby', + stars=3, + tags=['python', 'ruby']) + article.put() + return article + + +class Address(ndb.Model): + type = ndb.StringProperty() # E.g., 'home', 'work' + street = ndb.StringProperty() + city = ndb.StringProperty() + + +class Contact(ndb.Model): + name = ndb.StringProperty() + addresses = ndb.StructuredProperty(Address, repeated=True) + + +class ContactWithLocalStructuredProperty(ndb.Model): + name = ndb.StringProperty() + addresses = ndb.LocalStructuredProperty(Address, repeated=True) + + +def create_contact(): + guido = Contact( + name='Guido', + addresses=[ + Address( + type='home', + city='Amsterdam'), + Address( + type='work', + street='Spear St', + city='SF')]) + + guido.put() + return guido + + +def create_contact_with_local_structured_property(): + guido = ContactWithLocalStructuredProperty( + name='Guido', + addresses=[ + Address( + type='home', + city='Amsterdam'), + Address( + type='work', + street='Spear St', + city='SF')]) + + guido.put() + return guido + + +class SomeEntity(ndb.Model): + name = ndb.StringProperty() + name_lower = ndb.ComputedProperty(lambda self: self.name.lower()) + + +def create_some_entity(): + entity = SomeEntity(name='Nick') + entity.put() + return entity + + +class Note(messages.Message): + text = messages.StringField(1, required=True) + when = messages.IntegerField(2) + + +class NoteStore(ndb.Model): + note = msgprop.MessageProperty(Note, indexed_fields=['when']) + name = ndb.StringProperty() + + +def create_note_store(): + my_note = Note(text='Excellent note', when=50) + + ns = NoteStore(note=my_note, name='excellent') + key = ns.put() + + new_notes = NoteStore.query(NoteStore.note.when >= 10).fetch() + return new_notes, key + + +class Notebook(messages.Message): + notes = messages.MessageField(Note, 1, repeated=True) + + +class SignedStorableNotebook(ndb.Model): + author = ndb.StringProperty() + nb = msgprop.MessageProperty( + Notebook, indexed_fields=['notes.text', 'notes.when']) + + +class Color(messages.Enum): + RED = 620 + GREEN = 495 + BLUE = 450 + + +class Part(ndb.Model): + name = ndb.StringProperty() + color = msgprop.EnumProperty(Color, required=True) + + +def print_part(): + p1 = Part(name='foo', color=Color.RED) + print p1.color # prints "RED" diff --git a/appengine/ndb/properties/snippets_test.py b/appengine/ndb/properties/snippets_test.py new file mode 100644 index 000000000000..f57d24c47812 --- /dev/null +++ b/appengine/ndb/properties/snippets_test.py @@ -0,0 +1,119 @@ +# Copyright 2016 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 inspect + +from google.appengine.ext import ndb +import pytest +import snippets + + +@pytest.yield_fixture +def client(testbed): + yield testbed + + for name, obj in inspect.getmembers(snippets): + if inspect.isclass(obj) and issubclass(obj, ndb.Model): + ndb.delete_multi(obj.query().iter(keys_only=True)) + + +def test_account(client): + account = snippets.Account( + username='flan', + userid=123, + email='flan@example.com') + account.put() + + +def test_employee(client): + employee = snippets.Employee( + full_name='Hob Gadling', + retirement_age=600) + employee.put() + + +def test_article(client): + article = snippets.create_article() + assert article.title == 'Python versus Ruby' + assert article.stars == 3 + assert sorted(article.tags) == sorted(['python', 'ruby']) + + +def test_create_contact(client): + guido = snippets.create_contact() + assert guido.name == 'Guido' + addresses = guido.addresses + assert addresses[0].type == 'home' + assert addresses[1].type == 'work' + assert addresses[0].street is None + assert addresses[1].street == 'Spear St' + assert addresses[0].city == 'Amsterdam' + assert addresses[1].city == 'SF' + + +def test_contact_with_local_structured_property(client): + guido = snippets.create_contact_with_local_structured_property() + assert guido.name == 'Guido' + addresses = guido.addresses + assert addresses[0].type == 'home' + assert addresses[1].type == 'work' + + +def test_create_some_entity(client): + entity = snippets.create_some_entity() + assert entity.name == 'Nick' + assert entity.name_lower == 'nick' + + +def test_computed_property(client): + entity = snippets.create_some_entity() + entity.name = 'Nick' + assert entity.name_lower == 'nick' + entity.name = 'Nickie' + assert entity.name_lower == 'nickie' + + +def test_create_note_store(client): + note_stores, _ = snippets.create_note_store() + assert len(note_stores) == 1 + assert note_stores[0].name == 'excellent' + assert note_stores[0].name == 'excellent' + assert note_stores[0].note.text == 'Excellent note' + assert note_stores[0].note.when == 50 + + +def test_notebook(client): + note1 = snippets.Note( + text='Refused to die.', + when=1389) + note2 = snippets.Note( + text='Printed some things', + when=1489) + note3 = snippets.Note( + text='Learned to use a sword', + when=1589) + + notebook = snippets.Notebook( + notes=[note1, note2, note3]) + stored_notebook = snippets.SignedStorableNotebook( + author='Hob Gadling', + nb=notebook) + + stored_notebook.put() + + +def test_part(client, capsys): + snippets.print_part() + stdout, _ = capsys.readouterr() + assert stdout.strip() == 'RED'