Skip to content

Commit

Permalink
Merge pull request #20 from jgeewax/storage
Browse files Browse the repository at this point in the history
Fixed #5 - Adding support for Google Cloud Storage
  • Loading branch information
jgeewax committed Feb 19, 2014
2 parents 651839c + b7f1b77 commit 120c767
Show file tree
Hide file tree
Showing 23 changed files with 2,516 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.py[cod]
*.sw[op]

# C extensions
*.so
Expand Down
4 changes: 4 additions & 0 deletions docs/_static/style.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions docs/_templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,23 @@ <h3>{{ _('Navigation') }}</h3>
{%- block sidebartoc %}
{%- include "localtoc.html" %}
{%- endblock %}

<h3>All API Docs</h3>
<nav class="gc-toc">
{{ toctree(includehidden=True, maxdepth=1, titles_only=True) }}
</nav>

{%- block sidebarrel %}
{%- include "relations.html" %}
{# include "relations.html" #}
{%- endblock %}
{%- block sidebarsourcelink %}
{%- include "sourcelink.html" %}
{# include "sourcelink.html" #}
{%- endblock %}
{%- if customsidebar %}
{%- include customsidebar %}
{%- endif %}
{%- block sidebarsearch %}
{%- include "searchbox.html" %}
{#- include "searchbox.html" #}
{%- endblock %}
{%- endif %}
</div>
Expand Down
18 changes: 18 additions & 0 deletions docs/common-api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Cloud Common
============

Connections
-----------

.. automodule:: gcloud.connection
:members:
:undoc-members:
:show-inheritance:

Credentials
-----------

.. automodule:: gcloud.credentials
:members:
:undoc-members:
:show-inheritance:
7 changes: 6 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary',
'sphinx.ext.todo', 'sphinx.ext.viewcode']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down Expand Up @@ -247,3 +248,7 @@

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# This pulls class descriptions from the class docstring,
# and parameter definitions from the __init__ docstring.
autoclass_content = 'both'
4 changes: 2 additions & 2 deletions docs/datastore-api.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Cloud Datastore API Documentation
=================================
Cloud Datastore
===============

:mod:`gcloud.datastore`
-----------------------
Expand Down
40 changes: 29 additions & 11 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
:tocdepth: 2
:maxdepth: 1

.. toctree::
:hidden:

datastore-api
storage-api
common-api

Google Cloud Python API
=======================
Expand All @@ -14,21 +21,32 @@ If you've never used ``gcloud`` before,
you should probably take a look at
:doc:`getting-started`.

Supported services
------------------
Cloud Datastore
---------------

- Google's `official documentation <https://developers.google.com/datastore/>`_
- :doc:`datastore-quickstart`
- :doc:`datastore-getting-started`
- :doc:`Cloud Datastore API Documentation <datastore-api>`

* **Cloud Datastore**
(`official documentation <https://developers.google.com/datastore/>`_)
Cloud Storage
-------------

- :doc:`datastore-quickstart`
- :doc:`datastore-getting-started`
- :doc:`datastore-api`
- Google's `official documentation <https://developers.google.com/storage/>`_
- :doc:`storage-quickstart`
- :doc:`Cloud Storage API Documentation <storage-api>`

I found a bug!
Common modules
--------------

Awesome!
- :doc:`Common Module API Documentation <common-api>`

How to contribute
-----------------

Want to help out?
That's awesome.
The library is open source
and `lives on GitHub <https://github.com/jgeewax/gcloud>`_.
Open an issue,
Open an issue
or fork the library and submit a pull request.
58 changes: 58 additions & 0 deletions docs/storage-api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Cloud Storage
=============

:mod:`gcloud.storage`
-----------------------

.. automodule:: gcloud.storage.__init__
:members:
:undoc-members:
:show-inheritance:

Connections
-----------

.. automodule:: gcloud.storage.connection
:members:
:undoc-members:
:show-inheritance:

Buckets
-------

.. automodule:: gcloud.storage.bucket
:members:
:undoc-members:
:show-inheritance:

Keys
----

.. automodule:: gcloud.storage.key
:members:
:undoc-members:
:show-inheritance:

Access Control
--------------

.. automodule:: gcloud.storage.acl
:members:
:undoc-members:
:show-inheritance:

Iterators
---------

.. automodule:: gcloud.storage.iterator
:members:
:undoc-members:
:show-inheritance:

Exceptions
----------

.. automodule:: gcloud.storage.exceptions
:members:
:undoc-members:
:show-inheritance:
67 changes: 67 additions & 0 deletions docs/storage-quickstart.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Cloud Storage in 10 seconds
===========================

Install the library
-------------------

The source code for the library
(and demo code)
lives on GitHub,
You can install the library quickly with ``pip``::

$ pip install gcloud

Run the
`example script <https://github.com/jgeewax/gcloud/blob/master/gcloud/storage/demo.py>`_
included in the package::

$ python -m gcloud.storage.demo

And that's it!
You should be walking through
a demonstration of using ``gcloud.storage``
to read and write data to Google Cloud Storage.

Try it yourself
---------------

You can interact with a demo dataset
in a Python interactive shell.

Start by importing the demo module
and instantiating the demo connection::

>>> from gcloud.storage import demo
>>> connection = demo.get_connection()

Once you have the connection,
you can create buckets and keys::

>>> connection.get_all_buckets()
[<Bucket: ...>, ...]
>>> bucket = connection.create_bucket('my-new-bucket')
>>> print bucket
<Bucket: my-new-bucket>
>>> key = bucket.new_key('my-test-file.txt')
>>> print key
<Key: my-new-bucket, my-test-file.txt>
>>> key = key.set_contents_from_string('this is test content!')
>>> print key.get_contents_as_string()
'this is test content!'
>>> print bucket.get_all_keys()
[<Key: my-new-bucket, my-test-file.txt>]
>>> bucket.delete()

.. note::
The ``get_connection`` method is just a shortcut for::

>>> from gcloud import storage
>>> from gcloud.storage import demo
>>> connection = storage.get_connection(
>>> demo.PROJECT_NAME, demo.CLIENT_EMAIL, demo.PRIVATE_KEY_PATH)

OK, that's it!
--------------

And you can always check out
the :doc:`storage-api`.
40 changes: 40 additions & 0 deletions gcloud/connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import httplib2


class Connection(object):
"""A generic connection to Google Cloud Platform.
Subclasses should understand
only the basic types
in method arguments,
however they should be capable
of returning advanced types.
"""

API_BASE_URL = 'https://www.googleapis.com'
"""The base of the API call URL."""

_EMPTY = object()
"""A pointer to represent an empty value for default arguments."""

def __init__(self, credentials=None):
"""
:type credentials: :class:`gcloud.credentials.Credentials`
:param credentials: The OAuth2 Credentials to use for this connection.
"""

self._credentials = credentials

@property
def http(self):
"""A getter for the HTTP transport used in talking to the API.
:rtype: :class:`httplib2.Http`
:returns: A Http object used to transport data.
"""
if not hasattr(self, '_http'):
self._http = httplib2.Http()
if self._credentials:
self._http = self._credentials.authorize(self._http)
return self._http

15 changes: 9 additions & 6 deletions gcloud/datastore/credentials.py → gcloud/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@ class Credentials(object):
which use this class under the hood.
"""

SCOPE = ('https://www.googleapis.com/auth/datastore '
'https://www.googleapis.com/auth/userinfo.email')
"""The scope required for authenticating as a Cloud Datastore consumer."""

@classmethod
def get_for_service_account(cls, client_email, private_key_path):
def get_for_service_account(cls, client_email, private_key_path, scope=None):
"""Gets the credentials for a service account.
:type client_email: string
Expand All @@ -30,8 +26,15 @@ def get_for_service_account(cls, client_email, private_key_path):
:param private_key_path: The path to a private key file (this file was
given to you when you created the service
account).
:type scope: string or tuple of strings
:param scope: The scope against which to authenticate.
(Different services require different scopes,
check the documentation for which scope is required
for the different levels of access
to any particular API.)
"""
return client.SignedJwtAssertionCredentials(
service_account_name=client_email,
private_key=open(private_key_path).read(),
scope=cls.SCOPE)
scope=scope)
10 changes: 7 additions & 3 deletions gcloud/datastore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@

__version__ = '0.1.2'

SCOPE = ('https://www.googleapis.com/auth/datastore ',
'https://www.googleapis.com/auth/userinfo.email')
"""The scope required for authenticating as a Cloud Datastore consumer."""


def get_connection(client_email, private_key_path):
"""Shortcut method to establish a connection to the Cloud Datastore.
Expand All @@ -58,11 +62,11 @@ def get_connection(client_email, private_key_path):
:rtype: :class:`gcloud.datastore.connection.Connection`
:returns: A connection defined with the proper credentials.
"""
from connection import Connection
from credentials import Credentials
from gcloud.credentials import Credentials
from gcloud.datastore.connection import Connection

credentials = Credentials.get_for_service_account(
client_email, private_key_path)
client_email, private_key_path, scope=SCOPE)
return Connection(credentials=credentials)

def get_dataset(dataset_id, client_email, private_key_path):
Expand Down
3 changes: 2 additions & 1 deletion gcloud/datastore/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Connection(object):
This class should understand only the basic types (and protobufs)
in method arguments, however should be capable of returning advanced types.
:type credentials: :class:`gcloud.datastore.credentials.Credentials`
:type credentials: :class:`gcloud.credentials.Credentials`
:param credentials: The OAuth2 Credentials to use for this connection.
"""

Expand Down Expand Up @@ -41,6 +41,7 @@ def http(self):
:rtype: :class:`httplib2.Http`
:returns: A Http object used to transport data.
"""

if not self._http:
self._http = httplib2.Http()
if self._credentials:
Expand Down
Loading

0 comments on commit 120c767

Please sign in to comment.