From bb540725ce15dcafd5ac5e5bb93e5a232ff4f33a Mon Sep 17 00:00:00 2001 From: David Medina Date: Fri, 4 Nov 2011 01:21:50 +0100 Subject: Refactor base to handler design --- github3/errors.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 github3/errors.py (limited to 'github3/errors.py') diff --git a/github3/errors.py b/github3/errors.py new file mode 100644 index 0000000..6932360 --- /dev/null +++ b/github3/errors.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# author: David Medina + +import json +import github3.exceptions as exceptions + +class GithubError(object): + """ Handler for API errors """ + + def __init__(self, response): + self._parser = json + self.status_code = response.status_code + self.debug = self._parser.loads(response.content) + + def error_400(self): + return exceptions.BadRequest("400 - %s" % self.debug.get('message')) + + def error_404(self) + return exceptions.NotFound("404 - %s" % self.debug.get('message')) + + def error_422(self): + errors = self.debug.get('errors') + if errors: + errors = ['{resource}: {code} => {field}'.format(**error) + for error in errors] + return exceptions.UnprocessableEntity( + '422 - %s %s' % (self.debug.get('message'), errors)) + + def process(self): + raise_error = getattr(self, 'error_%s' % self.status_code, False) + if raise_error: + raise raise_error() -- cgit v1.2.3-59-g8ed1b From bdc593ac5ae97f4f9d65df15fcc18b632fae7666 Mon Sep 17 00:00:00 2001 From: David Medina Date: Sat, 5 Nov 2011 20:47:14 +0100 Subject: Fix litle bugs and args to request --- github3/api.py | 33 ++++++++++++++++++++++++++++----- github3/errors.py | 7 +++++-- 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'github3/errors.py') diff --git a/github3/api.py b/github3/api.py index 3376bea..d82bd3a 100644 --- a/github3/api.py +++ b/github3/api.py @@ -14,16 +14,21 @@ class GithubCore(object): """ Wrapper for requests """ requests_remaining = None + base_url = 'https://api.github.com/' def __init__(self): self.session = requests.session() self.session.params = {'per_page': RESOURCES_PER_PAGE} self._parser = json - #@paginate to slice a generator after - def get(self, request, **kwargs): + def get(self, request, paginate=False, **kwargs): + print '\nGET %s %s\n' % (request, kwargs) response = self._request('GET', request, **kwargs) - return self._parser.loads(response.content) + content = self._parser.loads(response.content) + if paginate: + return response.headers.get('link'), content + else: + return content def head(self, request, **kwargs): return self._request('HEAD', request, **kwargs).headers @@ -56,10 +61,28 @@ class GithubCore(object): response = self._request('DELETE', request, **kwargs) assert response.status_code == 204 + def _parse_args(self, request_args): + request_core = ( + 'params','data','headers','cookies','files','auth','tiemout', + 'allow_redirects','proxies','return_response','config') + request_params = request_args.get('params') + extra_params = {} + for k, v in request_args.items(): + if k in request_core: continue + extra_params.update({k: v}) + del request_args[k] + if request_params: + request_args['params'].update(extra_params) + else: + request_args['params'] = extra_params + + return request_args + def _request(self, verb, request, **kwargs): - request = settings.base_url + request - response = self.session.request(verb, request, **kwargs) + request = self.base_url + request + parsed_args = self._parse_args(kwargs) + response = self.session.request(verb, request, **parsed_args) self.requests_remaining = response.headers.get( 'x-ratelimit-remaining',-1) error = GithubError(response) diff --git a/github3/errors.py b/github3/errors.py index 6932360..96693be 100644 --- a/github3/errors.py +++ b/github3/errors.py @@ -12,12 +12,15 @@ class GithubError(object): def __init__(self, response): self._parser = json self.status_code = response.status_code - self.debug = self._parser.loads(response.content) + if response.content: + self.debug = self._parser.loads(response.content) + else: + self.debug = {} def error_400(self): return exceptions.BadRequest("400 - %s" % self.debug.get('message')) - def error_404(self) + def error_404(self): return exceptions.NotFound("404 - %s" % self.debug.get('message')) def error_422(self): -- cgit v1.2.3-59-g8ed1b From 40cbe596f0d726461d65d6473c2d197f63232641 Mon Sep 17 00:00:00 2001 From: David Medina Date: Wed, 9 Nov 2011 02:10:29 +0100 Subject: Fixing bugs. Crazy night :S --- github3/api.py | 8 +++++++- github3/errors.py | 6 +++--- github3/handlers/base.py | 16 +++++++--------- github3/handlers/user.py | 26 +++++++++++++------------- github3/models/orgs.py | 2 +- github3/models/repos.py | 4 ++-- 6 files changed, 33 insertions(+), 29 deletions(-) (limited to 'github3/errors.py') diff --git a/github3/api.py b/github3/api.py index 2066e94..b7435ff 100644 --- a/github3/api.py +++ b/github3/api.py @@ -43,7 +43,7 @@ class GithubCore(object): def head(self, request, **kwargs): """ HEAD request """ - return self._request('HEAD', request, **kwargs).headers + return self._request('HEAD', request, **kwargs) def post(self, request, data=None, **kwargs): """ @@ -71,11 +71,17 @@ class GithubCore(object): """ PUT request """ response = self._request('PUT', request, **kwargs) assert response.status_code == 204 + return response def delete(self, request, **kwargs): """ DELETE request """ + + data = kwargs.get('data') + if data: + kwargs['data'] = self._parser.dumps(data) response = self._request('DELETE', request, **kwargs) assert response.status_code == 204 + return response def _parse_args(self, request_args): """ diff --git a/github3/errors.py b/github3/errors.py index 96693be..09e616b 100644 --- a/github3/errors.py +++ b/github3/errors.py @@ -12,10 +12,10 @@ class GithubError(object): def __init__(self, response): self._parser = json self.status_code = response.status_code - if response.content: + try: self.debug = self._parser.loads(response.content) - else: - self.debug = {} + except ValueError: + self.debug = {'message': response.content} def error_400(self): return exceptions.BadRequest("400 - %s" % self.debug.get('message')) diff --git a/github3/handlers/base.py b/github3/handlers/base.py index 6bf13bf..50e2df8 100644 --- a/github3/handlers/base.py +++ b/github3/handlers/base.py @@ -15,9 +15,9 @@ class Handler(object): def _prefix_resource(self, resource): prefix = getattr(self, 'prefix', '') - return '/'.join((prefix, resource)) + return '/'.join((prefix, resource)).rstrip('/') - def _get_converter(self, kwargs): + def _get_converter(self, **kwargs): converter = kwargs.get( 'converter', # 1. in kwargs getattr(self, 'converter', # 2. in handler @@ -28,13 +28,11 @@ class Handler(object): def _put(self, resource, **kwargs): """ Put proxy request""" - resource = self._prefix_resource(resource) return self._bool(resource, method='put', **kwargs) def _delete(self, resource, **kwargs): """ Delete proxy request""" - resource = self._prefix_resource(resource) return self._bool(resource, method='delete', **kwargs) def _bool(self, resource, **kwargs): @@ -43,7 +41,7 @@ class Handler(object): from github3.exceptions import NotFound resource = self._prefix_resource(resource) try: - callback = getattr(self._gh, kwargs.get(method,''), self._gh.head) + callback = getattr(self._gh, kwargs.get('method',''), self._gh.head) response = callback(resource, **kwargs) except NotFound: return False @@ -55,13 +53,13 @@ class Handler(object): """ Hander request to multiple resources """ resource = self._prefix_resource(resource) - page_resources = Paginate(resource, self._gh.get, kwargs) + page_resources = Paginate(resource, self._gh.get, **kwargs) counter = 1 for page in page_resources: for raw_resource in page: if limit and counter > limit: break counter += 1 - converter = self._get_converter(kwargs) + converter = self._get_converter(**kwargs) converter.inject(model) yield converter.loads(raw_resource) else: @@ -73,7 +71,7 @@ class Handler(object): resource = self._prefix_resource(resource) raw_resource = self._gh.get(resource) - converter = self._get_converter(kwargs) + converter = self._get_converter(**kwargs) converter.inject(model) return converter.loads(raw_resource) @@ -82,6 +80,6 @@ class Handler(object): resource = self._prefix_resource(resource) raw_resource = self._gh.post(resource, data=data) - converter = self._get_converter(kwargs) + converter = self._get_converter(**kwargs) converter.inject(model) return converter.loads(raw_resource) diff --git a/github3/handlers/user.py b/github3/handlers/user.py index 75a0d3f..fb893b4 100644 --- a/github3/handlers/user.py +++ b/github3/handlers/user.py @@ -29,37 +29,37 @@ class User(Handler): def get(self): """ Return user """ - self._get_resource('', model=models.User) + return self._get_resource('', model=models.User) def get_followers(self): """ Return user's followers """ - self._get_resources('followers', model=models.User) + return self._get_resources('followers', model=models.User) def get_following(self): """ Return users that follow """ - self._get_resources('following', model=models.User) + return self._get_resources('following', model=models.User) def get_repos(self): """ Return user's public repositories """ - self._get_resources('repos', model=models.Repo) + return self._get_resources('repos', model=models.Repo) def get_watched(self): """ Return repositories that user whatch """ - self._get_resources('watched', model=models.Repo) + return self._get_resources('watched', model=models.Repo) def get_orgs(self): """ Return user's public organizations """ - self._get_resources('orgs', model=models.Org) + return self._get_resources('orgs', model=models.Org) def get_gists(self): """ Return user's gists """ - self._get_resources('gists', model=models.Gist) + return self._get_resources('gists', model=models.Gist) class AuthUser(User): """ User handler with public and private access """ @@ -70,7 +70,7 @@ class AuthUser(User): return ' %s>' % self._gh.session.auth[0] def get(self): - self._get_resource('', model=models.AuthUser) + return self._get_resource('', model=models.AuthUser) def get_emails(self): """ Return list of emails """ @@ -119,9 +119,9 @@ class AuthUser(User): """ parse_user = str(getattr(user, 'login', user)) - return self._put('following/%s', % parse_user) + return self._put('following/%s' % parse_user) - def unfollow(self, user) + def unfollow(self, user): """ Unfollow user @@ -129,14 +129,14 @@ class AuthUser(User): """ parse_user = str(getattr(user, 'login', user)) - return self._delete('following/%s', % parse_user) + return self._delete('following/%s' % parse_user) def get_keys(self): """ Get public keys """ return self._get_resources('keys', model=models.Key) - def get_key(self, key_id) + def get_key(self, key_id): """ Get public key by id """ return self._get_resource('keys/%s' % key_id, model=models.Key) @@ -151,7 +151,7 @@ class AuthUser(User): #TODO: render key.pub file key = { - 'title': kwargs.get('title','') + 'title': kwargs.get('title',''), 'key': kwargs.get('key','') } return self._post_resource('keys', data=key, model=models.Key) diff --git a/github3/models/orgs.py b/github3/models/orgs.py index 840b51a..5e66c35 100644 --- a/github3/models/orgs.py +++ b/github3/models/orgs.py @@ -18,7 +18,7 @@ class Org(BaseResource): 'following', 'total_private_repos', 'owned_private_repos', 'private_gists', 'disk_usage', 'collaborators'], 'dates': ['created_at'], - 'maps': {'plan': plan} + 'maps': {'plan': Plan} } def __repr__(self): diff --git a/github3/models/repos.py b/github3/models/repos.py index ba6ac33..d1b7b75 100644 --- a/github3/models/repos.py +++ b/github3/models/repos.py @@ -22,8 +22,8 @@ class Repo(BaseResource): 'maps': { 'owner': User, 'organization': Org, - 'parent': 'self', - 'source': 'self', + 'parent': self.__class__, + 'source': self.__class__, } } -- cgit v1.2.3-59-g8ed1b