Skip to content

Commit 120c767

Browse files
committed
Merge pull request #20 from jgeewax/storage
Fixed #5 - Adding support for Google Cloud Storage
2 parents 651839c + b7f1b77 commit 120c767

23 files changed

+2516
-27
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.py[cod]
2+
*.sw[op]
23

34
# C extensions
45
*.so

docs/_static/style.css

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/_templates/layout.html

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,23 @@ <h3>{{ _('Navigation') }}</h3>
5959
{%- block sidebartoc %}
6060
{%- include "localtoc.html" %}
6161
{%- endblock %}
62+
63+
<h3>All API Docs</h3>
64+
<nav class="gc-toc">
65+
{{ toctree(includehidden=True, maxdepth=1, titles_only=True) }}
66+
</nav>
67+
6268
{%- block sidebarrel %}
63-
{%- include "relations.html" %}
69+
{# include "relations.html" #}
6470
{%- endblock %}
6571
{%- block sidebarsourcelink %}
66-
{%- include "sourcelink.html" %}
72+
{# include "sourcelink.html" #}
6773
{%- endblock %}
6874
{%- if customsidebar %}
6975
{%- include customsidebar %}
7076
{%- endif %}
7177
{%- block sidebarsearch %}
72-
{%- include "searchbox.html" %}
78+
{#- include "searchbox.html" #}
7379
{%- endblock %}
7480
{%- endif %}
7581
</div>

docs/common-api.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Cloud Common
2+
============
3+
4+
Connections
5+
-----------
6+
7+
.. automodule:: gcloud.connection
8+
:members:
9+
:undoc-members:
10+
:show-inheritance:
11+
12+
Credentials
13+
-----------
14+
15+
.. automodule:: gcloud.credentials
16+
:members:
17+
:undoc-members:
18+
:show-inheritance:

docs/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

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

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

248249
# How to display URL addresses: 'footnote', 'no', or 'inline'.
249250
#texinfo_show_urls = 'footnote'
251+
252+
# This pulls class descriptions from the class docstring,
253+
# and parameter definitions from the __init__ docstring.
254+
autoclass_content = 'both'

docs/datastore-api.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Cloud Datastore API Documentation
2-
=================================
1+
Cloud Datastore
2+
===============
33

44
:mod:`gcloud.datastore`
55
-----------------------

docs/index.rst

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
:tocdepth: 2
1+
:maxdepth: 1
2+
3+
.. toctree::
4+
:hidden:
5+
6+
datastore-api
7+
storage-api
8+
common-api
29

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

17-
Supported services
18-
------------------
24+
Cloud Datastore
25+
---------------
26+
27+
- Google's `official documentation <https://developers.google.com/datastore/>`_
28+
- :doc:`datastore-quickstart`
29+
- :doc:`datastore-getting-started`
30+
- :doc:`Cloud Datastore API Documentation <datastore-api>`
1931

20-
* **Cloud Datastore**
21-
(`official documentation <https://developers.google.com/datastore/>`_)
32+
Cloud Storage
33+
-------------
2234

23-
- :doc:`datastore-quickstart`
24-
- :doc:`datastore-getting-started`
25-
- :doc:`datastore-api`
35+
- Google's `official documentation <https://developers.google.com/storage/>`_
36+
- :doc:`storage-quickstart`
37+
- :doc:`Cloud Storage API Documentation <storage-api>`
2638

27-
I found a bug!
39+
Common modules
2840
--------------
2941

30-
Awesome!
42+
- :doc:`Common Module API Documentation <common-api>`
43+
44+
How to contribute
45+
-----------------
46+
47+
Want to help out?
48+
That's awesome.
3149
The library is open source
3250
and `lives on GitHub <https://github.com/jgeewax/gcloud>`_.
33-
Open an issue,
51+
Open an issue
3452
or fork the library and submit a pull request.

docs/storage-api.rst

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Cloud Storage
2+
=============
3+
4+
:mod:`gcloud.storage`
5+
-----------------------
6+
7+
.. automodule:: gcloud.storage.__init__
8+
:members:
9+
:undoc-members:
10+
:show-inheritance:
11+
12+
Connections
13+
-----------
14+
15+
.. automodule:: gcloud.storage.connection
16+
:members:
17+
:undoc-members:
18+
:show-inheritance:
19+
20+
Buckets
21+
-------
22+
23+
.. automodule:: gcloud.storage.bucket
24+
:members:
25+
:undoc-members:
26+
:show-inheritance:
27+
28+
Keys
29+
----
30+
31+
.. automodule:: gcloud.storage.key
32+
:members:
33+
:undoc-members:
34+
:show-inheritance:
35+
36+
Access Control
37+
--------------
38+
39+
.. automodule:: gcloud.storage.acl
40+
:members:
41+
:undoc-members:
42+
:show-inheritance:
43+
44+
Iterators
45+
---------
46+
47+
.. automodule:: gcloud.storage.iterator
48+
:members:
49+
:undoc-members:
50+
:show-inheritance:
51+
52+
Exceptions
53+
----------
54+
55+
.. automodule:: gcloud.storage.exceptions
56+
:members:
57+
:undoc-members:
58+
:show-inheritance:

docs/storage-quickstart.rst

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Cloud Storage in 10 seconds
2+
===========================
3+
4+
Install the library
5+
-------------------
6+
7+
The source code for the library
8+
(and demo code)
9+
lives on GitHub,
10+
You can install the library quickly with ``pip``::
11+
12+
$ pip install gcloud
13+
14+
Run the
15+
`example script <https://github.com/jgeewax/gcloud/blob/master/gcloud/storage/demo.py>`_
16+
included in the package::
17+
18+
$ python -m gcloud.storage.demo
19+
20+
And that's it!
21+
You should be walking through
22+
a demonstration of using ``gcloud.storage``
23+
to read and write data to Google Cloud Storage.
24+
25+
Try it yourself
26+
---------------
27+
28+
You can interact with a demo dataset
29+
in a Python interactive shell.
30+
31+
Start by importing the demo module
32+
and instantiating the demo connection::
33+
34+
>>> from gcloud.storage import demo
35+
>>> connection = demo.get_connection()
36+
37+
Once you have the connection,
38+
you can create buckets and keys::
39+
40+
>>> connection.get_all_buckets()
41+
[<Bucket: ...>, ...]
42+
>>> bucket = connection.create_bucket('my-new-bucket')
43+
>>> print bucket
44+
<Bucket: my-new-bucket>
45+
>>> key = bucket.new_key('my-test-file.txt')
46+
>>> print key
47+
<Key: my-new-bucket, my-test-file.txt>
48+
>>> key = key.set_contents_from_string('this is test content!')
49+
>>> print key.get_contents_as_string()
50+
'this is test content!'
51+
>>> print bucket.get_all_keys()
52+
[<Key: my-new-bucket, my-test-file.txt>]
53+
>>> bucket.delete()
54+
55+
.. note::
56+
The ``get_connection`` method is just a shortcut for::
57+
58+
>>> from gcloud import storage
59+
>>> from gcloud.storage import demo
60+
>>> connection = storage.get_connection(
61+
>>> demo.PROJECT_NAME, demo.CLIENT_EMAIL, demo.PRIVATE_KEY_PATH)
62+
63+
OK, that's it!
64+
--------------
65+
66+
And you can always check out
67+
the :doc:`storage-api`.

gcloud/connection.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import httplib2
2+
3+
4+
class Connection(object):
5+
"""A generic connection to Google Cloud Platform.
6+
7+
Subclasses should understand
8+
only the basic types
9+
in method arguments,
10+
however they should be capable
11+
of returning advanced types.
12+
"""
13+
14+
API_BASE_URL = 'https://www.googleapis.com'
15+
"""The base of the API call URL."""
16+
17+
_EMPTY = object()
18+
"""A pointer to represent an empty value for default arguments."""
19+
20+
def __init__(self, credentials=None):
21+
"""
22+
:type credentials: :class:`gcloud.credentials.Credentials`
23+
:param credentials: The OAuth2 Credentials to use for this connection.
24+
"""
25+
26+
self._credentials = credentials
27+
28+
@property
29+
def http(self):
30+
"""A getter for the HTTP transport used in talking to the API.
31+
32+
:rtype: :class:`httplib2.Http`
33+
:returns: A Http object used to transport data.
34+
"""
35+
if not hasattr(self, '_http'):
36+
self._http = httplib2.Http()
37+
if self._credentials:
38+
self._http = self._credentials.authorize(self._http)
39+
return self._http
40+

gcloud/datastore/credentials.py renamed to gcloud/credentials.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,8 @@ class Credentials(object):
1515
which use this class under the hood.
1616
"""
1717

18-
SCOPE = ('https://www.googleapis.com/auth/datastore '
19-
'https://www.googleapis.com/auth/userinfo.email')
20-
"""The scope required for authenticating as a Cloud Datastore consumer."""
21-
2218
@classmethod
23-
def get_for_service_account(cls, client_email, private_key_path):
19+
def get_for_service_account(cls, client_email, private_key_path, scope=None):
2420
"""Gets the credentials for a service account.
2521
2622
:type client_email: string
@@ -30,8 +26,15 @@ def get_for_service_account(cls, client_email, private_key_path):
3026
:param private_key_path: The path to a private key file (this file was
3127
given to you when you created the service
3228
account).
29+
30+
:type scope: string or tuple of strings
31+
:param scope: The scope against which to authenticate.
32+
(Different services require different scopes,
33+
check the documentation for which scope is required
34+
for the different levels of access
35+
to any particular API.)
3336
"""
3437
return client.SignedJwtAssertionCredentials(
3538
service_account_name=client_email,
3639
private_key=open(private_key_path).read(),
37-
scope=cls.SCOPE)
40+
scope=scope)

gcloud/datastore/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535

3636
__version__ = '0.1.2'
3737

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

3943
def get_connection(client_email, private_key_path):
4044
"""Shortcut method to establish a connection to the Cloud Datastore.
@@ -58,11 +62,11 @@ def get_connection(client_email, private_key_path):
5862
:rtype: :class:`gcloud.datastore.connection.Connection`
5963
:returns: A connection defined with the proper credentials.
6064
"""
61-
from connection import Connection
62-
from credentials import Credentials
65+
from gcloud.credentials import Credentials
66+
from gcloud.datastore.connection import Connection
6367

6468
credentials = Credentials.get_for_service_account(
65-
client_email, private_key_path)
69+
client_email, private_key_path, scope=SCOPE)
6670
return Connection(credentials=credentials)
6771

6872
def get_dataset(dataset_id, client_email, private_key_path):

gcloud/datastore/connection.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Connection(object):
1212
This class should understand only the basic types (and protobufs)
1313
in method arguments, however should be capable of returning advanced types.
1414
15-
:type credentials: :class:`gcloud.datastore.credentials.Credentials`
15+
:type credentials: :class:`gcloud.credentials.Credentials`
1616
:param credentials: The OAuth2 Credentials to use for this connection.
1717
"""
1818

@@ -41,6 +41,7 @@ def http(self):
4141
:rtype: :class:`httplib2.Http`
4242
:returns: A Http object used to transport data.
4343
"""
44+
4445
if not self._http:
4546
self._http = httplib2.Http()
4647
if self._credentials:

0 commit comments

Comments
 (0)