Permalink
Browse files

Merge pull request #28 from BYK/multiple-pk

Implement multiple pk support.
  • Loading branch information...
2 parents 19aaf14 + 961f09f commit b3b22295e8912dc11ecee42f2701ed546bba7c1d @berkerpeksag berkerpeksag committed Aug 10, 2012
Showing with 133 additions and 94 deletions.
  1. +8 −8 docs/tutorial.rst
  2. +34 −26 pyresto/apis/github/__init__.py
  3. +91 −60 pyresto/core.py
View
@@ -17,7 +17,7 @@ will hold the common values such as the API host, the common model
representation using ``__repr__`` etc:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 7-14
+ :lines: 7-18
Simple Models
@@ -27,7 +27,7 @@ Then continue with implementing simple models which does not refer to any other
model, such as the ``Comment`` model for GitHub:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 17-19
+ :lines: 21-23
Note that we didn't define *any* attributes except for the mandatory ``_path``
@@ -47,7 +47,7 @@ After defining some "simple" models, you can start implementing models having
relations with each other:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 22-25
+ :lines: 26-29
Note that we used the attribute name ``comments`` which will "shadow" any
attribute named "comments" sent by the server as documented in
@@ -74,7 +74,7 @@ If we were expecting lots of items to be in the collection, or an unknown
number of items in the collection, we could have used ``lazy=True`` like this:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 47-54
+ :lines: 51-59
Using ``lazy=True`` will result in a :class:`LazyList<.core.LazyList>` type of
field on the model when accessed, which is basically a generator. So you can
@@ -85,7 +85,7 @@ You can also use the :class:`Foreign<.core.Foreign>` relation to refer to
other models:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 36-39
+ :lines: 40-43
When used in its simplest form, just like in the code above, this relation
expects the primary key value for the model it is referencing, ``Commit`` here,
@@ -105,7 +105,7 @@ not always possible to put all relation definitons inside the class definition.
For those cases, you can simply late bind the relations as follows:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 74-79
+ :lines: 79-87
Authentication
@@ -116,7 +116,7 @@ means of authentication is essential. Define the possible authentication
mechanisms for the service:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 4,81-82
+ :lines: 4,89-81
Make sure you use the provided authentication classes by :mod:`requests.auth`
if they suit your needs. If you still need a custom authentication class, make
@@ -127,7 +127,7 @@ will set the default authentication method and credentials for all requests for
convenience:
.. literalinclude:: ../pyresto/apis/github/__init__.py
- :lines: 84-85
+ :lines: 92-93
Above, we provide the list of methods/classes we have previously defined, the
base class for our service since all other models inherit from that and will
@@ -8,35 +8,39 @@ class GitHubModel(Model):
_url_base = 'https://api.github.com'
def __repr__(self):
- descriptor = getattr(self, "url",
- '`{0}`: {1}'.format(self._pk, self._id))
+ if hasattr(self, '_links'):
+ desc = self._links['self']
+ elif hasattr(self, 'url'):
+ desc = self.url
+ else:
+ desc = self._current_path
- return '<GitHub.{0} [{1}]>'.format(self.__class__.__name__, descriptor)
+ return '<GitHub.{0} [{1}]>'.format(self.__class__.__name__, desc)
class Comment(GitHubModel):
_path = '/repos/{user}/{repo}/comments/{id}'
- _pk = 'id'
+ _pk = ('user', 'repo', 'id')
class Commit(GitHubModel):
_path = '/repos/{user}/{repo}/commits/{sha}'
- _pk = 'sha'
- comments = Many(Comment, '{commit.url}/comments?per_page=100')
+ _pk = ('user', 'repo', 'sha')
+ comments = Many(Comment, '{self._current_path}/comments?per_page=100')
class Branch(GitHubModel):
_path = '/repos/{user}/{repo}/branches/{name}'
- _pk = 'name'
- commit = Foreign(Commit)
- commits = Many(Commit, '{repo.url}/commits?per_page=100&sha={branch._id}',
- lazy=True)
+ _pk = ('user', 'repo', 'name')
+ commit = Foreign(Commit, embedded=True)
+ commits = Many(Commit, '/repos/{user}/{repo}/commits'
+ '?per_page=100&sha={self._id}', lazy=True)
class Tag(GitHubModel):
- _path = '/repos/{user}/{repo}/tags/{id}'
- _pk = 'name'
- commit = Foreign(Commit)
+ _path = '/repos/{user}/{repo}/tags/{name}'
+ _pk = ('user', 'repo', 'name')
+ commit = Foreign(Commit, embedded=True)
class Key(GitHubModel):
@@ -46,37 +50,41 @@ class Key(GitHubModel):
class Repo(GitHubModel):
_path = '/repos/{user}/{name}'
- _pk = 'name'
- commits = Many(Commit, '{repo.url}/commits?per_page=100', lazy=True)
- comments = Many(Comment, '{repo.url}/comments?per_page=100')
- tags = Many(Tag, '{repo.url}/tags?per_page=100')
- branches = Many(Branch, '{repo.url}/branches?per_page=100')
- keys = Many(Key, '{repo.url}/keys?per_page=100')
+ _pk = ('user', 'name')
+ commits = Many(Commit, '{self._current_path}/commits?per_page=100',
+ lazy=True)
+ comments = Many(Comment, '{self._current_path}/comments?per_page=100')
+ tags = Many(Tag, '{self._current_path}/tags?per_page=100')
+ branches = Many(Branch, '{self._current_path}/branches?per_page=100')
+ keys = Many(Key, '{self._current_path}/keys?per_page=100')
class User(GitHubModel):
_path = '/users/{login}'
_pk = 'login'
- repos = Many(Repo, '{user.url}/repos?type=all&per_page=100')
- keys = Many(Key, '/user/keys?per_page=100')
+ repos = Many(Repo, '{self._current_path}/repos?type=all&per_page=100')
class Me(User):
_path = '/user'
repos = Many(Repo, '/user/repos?type=all&per_page=100')
+ keys = Many(Key, '/user/keys?per_page=100')
@classmethod
def get(cls, **kwargs):
return super(Me, cls).get(None, **kwargs)
# Late bindings due to circular references
-Repo.contributors = Many(User, '{repo.url}/contributors?per_page=100')
-Repo.owner = Foreign(User, 'owner')
-Repo.watcher_list = Many(User, '{repo.url}/watchers?per_page=100')
-User.follower_list = Many(User, '{user.url}/followers?per_page=100')
-User.watched = Many(Repo, '{user.url}/watched?per_page=100')
+Commit.committer = Foreign(User, '__committer', embedded=True)
+Commit.author = Foreign(User, '__author', embedded=True)
+Repo.contributors = Many(User,
+ '{self._current_path}/contributors?per_page=100')
+Repo.owner = Foreign(User, '__owner', embedded=True)
+Repo.watcher_list = Many(User, '{self._current_path}/watchers?per_page=100')
+User.follower_list = Many(User, '{self._current_path}/followers?per_page=100')
+User.watched = Many(Repo, '{self._current_path}/watched?per_page=100')
# Define authentication methods
auths = AuthList(basic=HTTPBasicAuth)
Oops, something went wrong.

0 comments on commit b3b2229

Please sign in to comment.