diff --git a/.travis.yml b/.travis.yml index f0a3ab1c5756..e99696201aad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,15 +9,18 @@ script: - (cd core && tox -e py27) - (cd bigtable && tox -e py27) - (cd storage && tox -e py27) + - (cd datastore && tox -e py27) - tox -e py34 - (cd core && tox -e py34) - (cd bigtable && tox -e py34) - (cd storage && tox -e py34) + - (cd datastore && tox -e py34) - tox -e lint - tox -e cover - (cd core && tox -e cover) - (cd bigtable && tox -e cover) - (cd storage && tox -e cover) + - (cd datastore && tox -e cover) - tox -e system-tests - tox -e system-tests3 - scripts/update_docs.sh diff --git a/datastore/.coveragerc b/datastore/.coveragerc new file mode 100644 index 000000000000..08f3fdea2433 --- /dev/null +++ b/datastore/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +omit = + */_generated/*.py +fail_under = 100 +show_missing = True +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/datastore/MANIFEST.in b/datastore/MANIFEST.in new file mode 100644 index 000000000000..cb3a2b9ef4fa --- /dev/null +++ b/datastore/MANIFEST.in @@ -0,0 +1,4 @@ +include README.rst +graft google +graft unit_tests +global-exclude *.pyc diff --git a/datastore/README.rst b/datastore/README.rst new file mode 100644 index 000000000000..b3145186ef59 --- /dev/null +++ b/datastore/README.rst @@ -0,0 +1,67 @@ +Python Client for Google Cloud Datastore +======================================== + + Python idiomatic client for `Google Cloud Datastore`_ + +.. _Google Cloud Datastore: https://cloud.google.com/datastore/docs + +- `Homepage`_ +- `API Documentation`_ + +.. _Homepage: https://googlecloudplatform.github.io/google-cloud-python/ +.. _API Documentation: http://googlecloudplatform.github.io/google-cloud-python/ + +Quick Start +----------- + +:: + + $ pip install --upgrade google-cloud-datastore + +Authentication +-------------- + +With ``google-cloud-python`` we try to make authentication as painless as +possible. Check out the `Authentication section`_ in our documentation to +learn more. You may also find the `authentication document`_ shared by all +the ``google-cloud-*`` libraries to be helpful. + +.. _Authentication section: http://google-cloud-python.readthedocs.io/en/latest/google-cloud-auth.html +.. _authentication document: https://github.com/GoogleCloudPlatform/gcloud-common/tree/master/authentication + +Using the API +------------- + +Google `Cloud Datastore`_ (`Datastore API docs`_) is a fully managed, +schemaless database for storing non-relational data. Cloud Datastore +automatically scales with your users and supports ACID transactions, high +availability of reads and writes, strong consistency for reads and ancestor +queries, and eventual consistency for all other queries. + +.. _Cloud Datastore: https://cloud.google.com/datastore/docs +.. _Datastore API docs: https://cloud.google.com/datastore/docs/ + +See the ``google-cloud-python`` API `datastore documentation`_ to learn how to +interact with the Cloud Datastore using this Client Library. + +.. _datastore documentation: https://googlecloudplatform.github.io/google-cloud-python/stable/datastore-client.html + +See the `official Google Cloud Datastore documentation`_ for more details on +how to activate Cloud Datastore for your project. + +.. _official Google Cloud Datastore documentation: https://cloud.google.com/datastore/docs/activate + +.. code:: python + + from google.cloud import datastore + # Create, populate and persist an entity + entity = datastore.Entity(key=datastore.Key('EntityKind')) + entity.update({ + 'foo': u'bar', + 'baz': 1337, + 'qux': False, + }) + # Then query for entities + query = datastore.Query(kind='EntityKind') + for result in query.fetch(): + print(result) diff --git a/datastore/google/__init__.py b/datastore/google/__init__.py new file mode 100644 index 000000000000..b2b833373882 --- /dev/null +++ b/datastore/google/__init__.py @@ -0,0 +1,20 @@ +# 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. + +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/datastore/google/cloud/__init__.py b/datastore/google/cloud/__init__.py new file mode 100644 index 000000000000..8ac7b74af136 --- /dev/null +++ b/datastore/google/cloud/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2014 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. + +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/google/cloud/datastore/__init__.py b/datastore/google/cloud/datastore/__init__.py similarity index 100% rename from google/cloud/datastore/__init__.py rename to datastore/google/cloud/datastore/__init__.py diff --git a/google/cloud/datastore/_generated/__init__.py b/datastore/google/cloud/datastore/_generated/__init__.py similarity index 100% rename from google/cloud/datastore/_generated/__init__.py rename to datastore/google/cloud/datastore/_generated/__init__.py diff --git a/google/cloud/datastore/_generated/_datastore.proto b/datastore/google/cloud/datastore/_generated/_datastore.proto similarity index 100% rename from google/cloud/datastore/_generated/_datastore.proto rename to datastore/google/cloud/datastore/_generated/_datastore.proto diff --git a/google/cloud/datastore/_generated/_entity.proto b/datastore/google/cloud/datastore/_generated/_entity.proto similarity index 100% rename from google/cloud/datastore/_generated/_entity.proto rename to datastore/google/cloud/datastore/_generated/_entity.proto diff --git a/google/cloud/datastore/_generated/_query.proto b/datastore/google/cloud/datastore/_generated/_query.proto similarity index 100% rename from google/cloud/datastore/_generated/_query.proto rename to datastore/google/cloud/datastore/_generated/_query.proto diff --git a/google/cloud/datastore/_generated/datastore_grpc_pb2.py b/datastore/google/cloud/datastore/_generated/datastore_grpc_pb2.py similarity index 100% rename from google/cloud/datastore/_generated/datastore_grpc_pb2.py rename to datastore/google/cloud/datastore/_generated/datastore_grpc_pb2.py diff --git a/google/cloud/datastore/_generated/datastore_pb2.py b/datastore/google/cloud/datastore/_generated/datastore_pb2.py similarity index 100% rename from google/cloud/datastore/_generated/datastore_pb2.py rename to datastore/google/cloud/datastore/_generated/datastore_pb2.py diff --git a/google/cloud/datastore/_generated/entity_pb2.py b/datastore/google/cloud/datastore/_generated/entity_pb2.py similarity index 100% rename from google/cloud/datastore/_generated/entity_pb2.py rename to datastore/google/cloud/datastore/_generated/entity_pb2.py diff --git a/google/cloud/datastore/_generated/query_pb2.py b/datastore/google/cloud/datastore/_generated/query_pb2.py similarity index 100% rename from google/cloud/datastore/_generated/query_pb2.py rename to datastore/google/cloud/datastore/_generated/query_pb2.py diff --git a/google/cloud/datastore/batch.py b/datastore/google/cloud/datastore/batch.py similarity index 100% rename from google/cloud/datastore/batch.py rename to datastore/google/cloud/datastore/batch.py diff --git a/google/cloud/datastore/client.py b/datastore/google/cloud/datastore/client.py similarity index 100% rename from google/cloud/datastore/client.py rename to datastore/google/cloud/datastore/client.py diff --git a/google/cloud/datastore/connection.py b/datastore/google/cloud/datastore/connection.py similarity index 100% rename from google/cloud/datastore/connection.py rename to datastore/google/cloud/datastore/connection.py diff --git a/google/cloud/datastore/entity.py b/datastore/google/cloud/datastore/entity.py similarity index 100% rename from google/cloud/datastore/entity.py rename to datastore/google/cloud/datastore/entity.py diff --git a/google/cloud/datastore/helpers.py b/datastore/google/cloud/datastore/helpers.py similarity index 100% rename from google/cloud/datastore/helpers.py rename to datastore/google/cloud/datastore/helpers.py diff --git a/google/cloud/datastore/key.py b/datastore/google/cloud/datastore/key.py similarity index 100% rename from google/cloud/datastore/key.py rename to datastore/google/cloud/datastore/key.py diff --git a/google/cloud/datastore/query.py b/datastore/google/cloud/datastore/query.py similarity index 100% rename from google/cloud/datastore/query.py rename to datastore/google/cloud/datastore/query.py diff --git a/google/cloud/datastore/transaction.py b/datastore/google/cloud/datastore/transaction.py similarity index 100% rename from google/cloud/datastore/transaction.py rename to datastore/google/cloud/datastore/transaction.py diff --git a/datastore/setup.py b/datastore/setup.py new file mode 100644 index 000000000000..1067876e13b0 --- /dev/null +++ b/datastore/setup.py @@ -0,0 +1,69 @@ +# 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 os + +from setuptools import find_packages +from setuptools import setup + + +PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) + +with open(os.path.join(PACKAGE_ROOT, 'README.rst')) as file_obj: + README = file_obj.read() + +# NOTE: This is duplicated throughout and we should try to +# consolidate. +SETUP_BASE = { + 'author': 'Google Cloud Platform', + 'author_email': 'jjg+google-cloud-python@google.com', + 'scripts': [], + 'url': 'https://github.com/GoogleCloudPlatform/google-cloud-python', + 'license': 'Apache 2.0', + 'platforms': 'Posix; MacOS X; Windows', + 'include_package_data': True, + 'zip_safe': False, + 'classifiers': [ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Topic :: Internet', + ], +} + + +REQUIREMENTS = [ + 'google-cloud-core', + 'grpcio >= 1.0.0', +] + +setup( + name='google-cloud-datastore', + version='0.20.0dev', + description='Python Client for Google Cloud Datastore', + long_description=README, + namespace_packages=[ + 'google', + 'google.cloud', + ], + packages=find_packages(), + install_requires=REQUIREMENTS, + **SETUP_BASE +) diff --git a/datastore/tox.ini b/datastore/tox.ini new file mode 100644 index 000000000000..64f0d45463dd --- /dev/null +++ b/datastore/tox.ini @@ -0,0 +1,30 @@ +[tox] +envlist = + py27,py34,py35,cover + +[testing] +deps = + {toxinidir}/../core + pytest +covercmd = + py.test --quiet \ + --cov=google.cloud.datastore \ + --cov=unit_tests \ + --cov-config {toxinidir}/.coveragerc \ + unit_tests + +[testenv] +commands = + py.test --quiet {posargs} unit_tests +deps = + {[testing]deps} + +[testenv:cover] +basepython = + python2.7 +commands = + {[testing]covercmd} +deps = + {[testenv]deps} + coverage + pytest-cov diff --git a/unit_tests/datastore/__init__.py b/datastore/unit_tests/__init__.py similarity index 100% rename from unit_tests/datastore/__init__.py rename to datastore/unit_tests/__init__.py diff --git a/unit_tests/datastore/test_batch.py b/datastore/unit_tests/test_batch.py similarity index 100% rename from unit_tests/datastore/test_batch.py rename to datastore/unit_tests/test_batch.py diff --git a/unit_tests/datastore/test_client.py b/datastore/unit_tests/test_client.py similarity index 100% rename from unit_tests/datastore/test_client.py rename to datastore/unit_tests/test_client.py diff --git a/unit_tests/datastore/test_connection.py b/datastore/unit_tests/test_connection.py similarity index 100% rename from unit_tests/datastore/test_connection.py rename to datastore/unit_tests/test_connection.py diff --git a/unit_tests/datastore/test_entity.py b/datastore/unit_tests/test_entity.py similarity index 100% rename from unit_tests/datastore/test_entity.py rename to datastore/unit_tests/test_entity.py diff --git a/unit_tests/datastore/test_helpers.py b/datastore/unit_tests/test_helpers.py similarity index 100% rename from unit_tests/datastore/test_helpers.py rename to datastore/unit_tests/test_helpers.py diff --git a/unit_tests/datastore/test_key.py b/datastore/unit_tests/test_key.py similarity index 100% rename from unit_tests/datastore/test_key.py rename to datastore/unit_tests/test_key.py diff --git a/unit_tests/datastore/test_query.py b/datastore/unit_tests/test_query.py similarity index 100% rename from unit_tests/datastore/test_query.py rename to datastore/unit_tests/test_query.py diff --git a/unit_tests/datastore/test_transaction.py b/datastore/unit_tests/test_transaction.py similarity index 100% rename from unit_tests/datastore/test_transaction.py rename to datastore/unit_tests/test_transaction.py diff --git a/scripts/run_pylint.py b/scripts/run_pylint.py index e50202cb71c0..9c3a515b4851 100644 --- a/scripts/run_pylint.py +++ b/scripts/run_pylint.py @@ -32,7 +32,7 @@ IGNORED_DIRECTORIES = [ os.path.join('bigtable', 'google', 'cloud', 'bigtable', '_generated'), - os.path.join('google', 'cloud', 'datastore', '_generated'), + os.path.join('datastore', 'google', 'cloud', 'datastore', '_generated'), ] IGNORED_FILES = [ os.path.join('docs', 'conf.py'), diff --git a/scripts/verify_included_modules.py b/scripts/verify_included_modules.py index 68829f961b8f..71d52b13f43d 100644 --- a/scripts/verify_included_modules.py +++ b/scripts/verify_included_modules.py @@ -61,6 +61,7 @@ '', 'bigtable', 'core', + 'datastore', 'storage', ) diff --git a/setup.py b/setup.py index 1bcebe10e990..cc8e11714518 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,7 @@ REQUIREMENTS = [ 'google-cloud-bigtable', 'google-cloud-core', + 'google-cloud-datastore', 'google-cloud-storage', ] diff --git a/tox.ini b/tox.ini index 1778dcf258ec..9ee3733bb156 100644 --- a/tox.ini +++ b/tox.ini @@ -7,6 +7,7 @@ deps = {toxinidir}/core {toxinidir}/bigtable {toxinidir}/storage + {toxinidir}/datastore pytest covercmd = py.test --quiet \ @@ -32,6 +33,12 @@ covercmd = --cov-append \ --cov-config {toxinidir}/.coveragerc \ storage/unit_tests + py.test --quiet \ + --cov=google.cloud \ + --cov=unit_tests \ + --cov-append \ + --cov-config {toxinidir}/.coveragerc \ + datastore/unit_tests coverage report --show-missing --fail-under=100 [testenv] @@ -122,7 +129,7 @@ passenv = exclude = docs/conf.py, bigtable/google/cloud/bigtable/_generated/*, - google/cloud/datastore/_generated/* + datastore/google/cloud/datastore/_generated/* verbose = 1 [testenv:lint]