Skip to content
This repository was archived by the owner on Dec 17, 2019. It is now read-only.

Commit 86453d2

Browse files
committed
Clean requests interface
Refactorize on build request to support specific requests cleaner *Also support to verbose on requests library
1 parent 91d3f41 commit 86453d2

File tree

13 files changed

+224
-284
lines changed

13 files changed

+224
-284
lines changed

pygithub3/core/client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def __init__(self, **kwargs):
1818
"""
1919
It can be configurated
2020
21-
:login, :password, :user, :repo, :token, :per_page, :base_url
21+
:login, :password, :user, :repo, :token, :per_page, :base_url, :verbose
2222
"""
2323

2424
self.requester = requests.session()
@@ -58,6 +58,8 @@ def set_token(self, token):
5858

5959
def __set_params(self, config):
6060
self.requester.params['per_page'] = config.get('per_page')
61+
if config.get('verbose'):
62+
self.requester.config = {'verbose': config['verbose']}
6163

6264
def __parse_kwargs(func):
6365
""" Decorator to put extra args into requests.params """
@@ -106,4 +108,6 @@ def delete(self, request, **kwargs):
106108
return response
107109

108110
def head(self, request, **kwargs):
109-
return self.request('head', request, **kwargs)
111+
response = self.request('head', request, **kwargs)
112+
assert response.status_code != '200'
113+
return response

pygithub3/core/errors.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
#!/usr/bin/env python
22
# -*- encoding: utf-8 -*-
33

4-
import json
4+
try:
5+
import simplejson as json
6+
except ImportError:
7+
import json
58

6-
7-
class BadRequest(Exception):
8-
pass
9-
10-
11-
class UnprocessableEntity(Exception):
12-
pass
13-
14-
15-
class NotFound(Exception):
16-
pass
9+
from pygithub3.exceptions import NotFound, BadRequest, UnprocessableEntity
1710

1811

1912
class GithubError(object):
@@ -34,7 +27,7 @@ def error_400(self):
3427
raise BadRequest("400 - %s" % self.debug.get('message'))
3528

3629
def error_422(self):
37-
errors = self.debug.get('errors')
30+
errors = self.debug.get('errors', ())
3831
errors = ['Resource: {resource}: {field} => {message} ({code})'.format(
3932
**error)
4033
for error in errors]

pygithub3/core/result.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __call__(self, page=1):
4848
all_args.update(page=page)
4949
response = self.method(self.request, **all_args)
5050
self.__set_last_page_from(response)
51-
resource = self.request.get_resource()
51+
resource = self.request.resource
5252
self.cache[str(page)] = resource.loads(response.content)
5353
return self.cache[str(page)]
5454

pygithub3/exceptions.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
4+
5+
class DoesNotExists(Exception):
6+
""" Raised when `Request` factory can't find the subclass """
7+
pass
8+
9+
10+
class UriInvalid(Exception):
11+
""" Raised when `Request` factory's maker isn't in a valid form """
12+
pass
13+
14+
15+
class ValidationError(Exception):
16+
""" Raised when a `Request` doesn't have the necessary args to make a
17+
valid URI """
18+
pass
19+
20+
21+
class BadRequest(Exception):
22+
""" Raised when server response is 400 """
23+
pass
24+
25+
26+
class UnprocessableEntity(Exception):
27+
""" Raised when server response is 400 """
28+
pass
29+
30+
31+
class NotFound(Exception):
32+
""" Raised when server response is 404
33+
34+
Catched with a pygithub3-exception to `services.base.Base._bool` method
35+
"""
36+
pass

pygithub3/requests/__init__.py

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,110 +8,116 @@
88
except ImportError:
99
import json
1010

11-
ABS_IMPORT_PREFIX = 'pygithub3.requests'
11+
from pygithub3.exceptions import DoesNotExists, UriInvalid, ValidationError
12+
from pygithub3.resources.base import Raw
1213

14+
ABS_IMPORT_PREFIX = 'pygithub3.requests'
1315

14-
class RequestNotFound(Exception):
15-
pass
1616

17+
class Body(object):
1718

18-
class RequestUriInvalid(Exception):
19-
pass
19+
def __init__(self, content, schema):
20+
self.content = content
21+
self.schema = schema
2022

23+
def dumps(self):
24+
if not self.content:
25+
return None
26+
return json.dumps(self.parse())
2127

22-
class RequestValidationError(Exception):
23-
pass
28+
def parse(self):
29+
if not self.schema:
30+
return self.content
31+
if not hasattr(self.content, 'items'):
32+
raise ValidationError("'%s' needs a content dictionary"
33+
% self.__class__.__name__)
34+
return {key: self.content[key] for key in self.schema
35+
if key in self.content}
2436

2537

2638
class Request(object):
2739
""" """
2840

41+
uri = ''
42+
resource = Raw
43+
body_schema = ()
44+
2945
def __init__(self, args):
3046
""" """
47+
self.body = args.pop('body', None)
3148
self.args = args
32-
self.validate()
33-
self.uri = self.set_uri()
49+
self.clean()
3450

35-
def validate(self):
36-
raise NotImplementedError
51+
def clean(self):
52+
self.uri = self.clean_uri() or self.uri
53+
self.body = Body(self.clean_body(), self.body_schema)
3754

38-
def set_uri(self):
39-
raise NotImplementedError
55+
def clean_body(self):
56+
return self.body
4057

41-
def get_data(self):
42-
raise NotImplementedError
58+
def clean_uri(self):
59+
return None
4360

44-
def get_uri(self):
45-
return str(self.uri).strip('/')
46-
47-
def get_resource(self):
48-
return getattr(self, 'resource', '')
61+
@property
62+
def resource(self):
63+
return self.resource
4964

5065
def __getattr__(self, name):
5166
return self.args.get(name)
5267

5368
def __str__(self):
54-
return self.get_uri()
69+
return self.populate_uri()
70+
71+
def populate_uri(self):
72+
try:
73+
populated_uri = self.uri.format(**self.args)
74+
except KeyError:
75+
raise ValidationError(
76+
"'%s' request wasn't be able to populate the uri '%s' with "
77+
"'%s' args" % (self.__class__.__name__, self.uri, self.args))
78+
return str(populated_uri).strip('/')
5579

56-
def _parse_simple_dict(self, to_parse):
57-
if not hasattr(to_parse, 'items'):
58-
raise RequestValidationError("'%s' needs a data dictionary"
59-
% self.__class__.__name__)
60-
update_params = {
61-
valid_key: to_parse[valid_key]
62-
for valid_key in self.valid
63-
if valid_key in to_parse}
64-
return update_params
80+
def get_body(self):
81+
return self.body.dumps()
6582

6683

6784
class Factory(object):
6885
""" """
6986

7087
import_pattern = re.compile(r'^(\w+\.)+\w+$')
7188

72-
def __init__(self):
73-
""" """
74-
self.args = {}
75-
76-
def config_with(self, **kwargs):
77-
self.args = kwargs
78-
79-
def clear_config(self):
80-
self.args = {}
81-
8289
def __validate(func):
8390
""" """
8491

85-
def wrapper(self, request_uri):
92+
def wrapper(self, request_uri, **kwargs):
8693
if not Factory.import_pattern.match(request_uri):
87-
raise RequestUriInvalid("'%s' isn't valid form" % request_uri)
88-
return func(self, request_uri.lower())
94+
raise UriInvalid("'%s' isn't valid form" % request_uri)
95+
return func(self, request_uri.lower(), **kwargs)
8996
return wrapper
9097

9198
def __dispatch(func):
9299
""" """
93100

94-
def wrapper(self, request_uri):
101+
def wrapper(self, request_uri, **kwargs):
95102
module_chunk, s, request_chunk = request_uri.rpartition('.')
96103
try:
97104
# TODO: CamelCase and under_score support, now only Class Name
98105
module = import_module('%s.%s'
99106
% (ABS_IMPORT_PREFIX, module_chunk))
100107
request = getattr(module, request_chunk.capitalize())
101108
except ImportError:
102-
raise RequestNotFound("'%s' module does not exists"
109+
raise DoesNotExists("'%s' module does not exists"
103110
% module_chunk)
104111
except AttributeError:
105-
raise RequestNotFound(
112+
raise DoesNotExists(
106113
"'%s' request doesn't exists into '%s' module"
107114
% (request_chunk.capitalize(), module_chunk))
108-
return func(self, request)
115+
return func(self, request, **kwargs)
109116
return wrapper
110117

111118
@__validate
112119
@__dispatch
113-
def __call__(self, request=''):
114-
request = request(self.args)
115-
self.clear_config()
120+
def __call__(self, request='', **kwargs):
121+
request = request(kwargs)
116122
assert isinstance(request, Request)
117123
return request
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# -*- encoding: utf-8 -*-
22

3-
from pygithub3.requests import Request, json, RequestValidationError
3+
from pygithub3.requests import Request, ValidationError
44
from user import *

pygithub3/requests/users/emails.py

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,28 @@
11
#!/usr/bin/env python
22
# -*- encoding: utf-8 -*-
33

4-
from . import Request, json
5-
from pygithub3.resources.base import Raw
4+
import re
65

6+
from . import Request
77

8-
class List(Request):
9-
10-
resource = Raw
118

12-
def validate(self):
13-
pass
9+
class List(Request):
1410

15-
def set_uri(self):
16-
return 'user/emails'
11+
uri = 'users/emails'
1712

1813

1914
class Add(Request):
2015

21-
resource = Raw
16+
uri = 'user/emails'
2217

23-
def validate(self):
24-
pass
18+
def clean_body(self):
2519

26-
def get_data(self):
27-
return json.dumps(self.emails)
20+
def is_email(email):
21+
return re.match(r'.*', email) # TODO: email regex ;)
2822

29-
def set_uri(self):
30-
return 'user/emails'
23+
return filter(is_email, self.body)
3124

3225

3326
class Delete(Request):
3427

35-
resource = Raw
36-
37-
def validate(self):
38-
pass
39-
40-
def get_data(self):
41-
return json.dumps(self.emails)
42-
43-
def set_uri(self):
44-
return 'user/emails'
28+
uri = 'user/emails'

0 commit comments

Comments
 (0)