Skip to content

Commit 2ed1727

Browse files
committed
Added core_test and fix some bugs / pep8
Readme to Markdown
1 parent bd3df24 commit 2ed1727

File tree

5 files changed

+156
-49
lines changed

5 files changed

+156
-49
lines changed
Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,34 @@
11
Fork
2-
======================================
2+
====
33
Refactor and complete api wrapper. Intensive work in progress
44

55
Use with auth user
6-
---------------------
6+
------------------
77

8-
```python
9-
from github3.api import Github
8+
from github3.api import Github
109

11-
gh = Github('user', 'password')
10+
gh = Github('user', 'password')
1211

13-
users_handler = gh.users
14-
for repo in users_handler.get_repos():
15-
print repo
16-
17-
gists_handler = gh.gists
18-
gists_handler.create_gist(
19-
u'Description',
20-
files={'file1.txt': {'content': u'Content of first file'}})
21-
```
12+
users_handler = gh.users
13+
for repo in users_handler.get_repos():
14+
print repo
2215

16+
gists_handler = gh.gists
17+
gists_handler.create_gist(
18+
u'Description',
19+
files={'file1.txt': {'content': u'Content of first file'}})
2320

2421
Installation
2522
------------
2623

27-
To install Github3, simply: ::
28-
29-
$ pip install github3
30-
31-
Or, if you absolutely must: ::
32-
33-
$ easy_install github3
34-
35-
But, you really shouldn't do that.
36-
24+
To install Github3, simply:
3725

26+
$ pip -e git+https://copitux@github.com/copitux/python-github3#egg=python-github3
3827

3928
License
4029
-------
4130

42-
ISC License. ::
31+
ISC License.
4332

4433
Copyright (c) 2011, Kenneth Reitz <me@kennethreitz.com>
4534

@@ -59,20 +48,16 @@ ISC License. ::
5948
Contribute
6049
----------
6150

62-
If you'd like to contribute, simply fork `the repository`_, commit your changes
51+
If you'd like to contribute, simply fork `the repository`, commit your changes
6352
to the **develop** branch (or branch off of it), and send a pull request. Make
64-
sure you add yourself to AUTHORS_.
65-
53+
sure you add yourself to `AUTHORS`.
6654

6755

6856
Roadmap
6957
-------
7058

7159
- Unittests
7260
- Handlers
73-
- Get it Started
74-
- HTTP BASIC
75-
- Get it working
76-
- Sphinx Documetnation
61+
- Sphinx Documentation
7762
- Examples
7863
- OAuth Last (how?)

github3/api.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
RESOURCES_PER_PAGE = 100
1212

13+
1314
class GithubCore(object):
1415
"""
1516
Wrapper to github api requests
@@ -88,22 +89,21 @@ def _parse_args(self, request_args):
8889
"""
8990
Arg's parser to `_request` method
9091
91-
It check keyword args to parse extra request args to params
92-
Sample:
93-
_parse_args(arg1=1, arg2=2) => params = {'arg1': 1, 'arg2': 2}
92+
Put extra request_args in params
9493
"""
9594
request_core = (
96-
'params','data','headers','cookies','files','auth','tiemout',
97-
'allow_redirects','proxies','return_response','config')
95+
'params', 'data', 'headers', 'cookies', 'files', 'auth', 'tiemout',
96+
'allow_redirects', 'proxies', 'return_response', 'config')
9897
request_params = request_args.get('params')
9998
extra_params = {}
10099
for k, v in request_args.items():
101-
if k in request_core: continue
100+
if k in request_core:
101+
continue
102102
extra_params.update({k: v})
103103
del request_args[k]
104-
if request_params:
104+
if request_params and getattr(request_params, 'update'):
105105
request_args['params'].update(extra_params)
106-
else:
106+
elif extra_params:
107107
request_args['params'] = extra_params
108108

109109
return request_args
@@ -117,26 +117,27 @@ def _request(self, verb, request, **kwargs):
117117
:param kwargs: Keyword args to request
118118
"""
119119
request = self.base_url + request
120-
parsed_args = self._parse_args(kwargs)
121-
response = self.session.request(verb, request, **parsed_args)
120+
self._parse_args(kwargs)
121+
response = self.session.request(verb, request, **kwargs)
122122
self.requests_remaining = response.headers.get(
123-
'x-ratelimit-remaining',-1)
123+
'x-ratelimit-remaining', -1)
124124
error = GithubError(response)
125125
error.process()
126126

127127
return response
128128

129+
129130
class Github(GithubCore):
130131
""" Library enter """
131132

132133
def __init__(self, *args):
133134
super(Github, self).__init__()
134135
self.authenticated = False
135136
auth = len(args)
136-
if auth == 2: # Basic auth
137-
self.session.auth = tuple(map(str,args))
137+
if auth == 2: # Basic auth
138+
self.session.auth = tuple(map(str, args))
138139
self.authenticated = True
139-
elif auth == 1: # Token oauth
140+
elif auth == 1: # Token oauth
140141
raise NotImplementedError
141142
elif auth > 2:
142143
raise TypeError("user, password or token")

github3/errors.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import json
77
import github3.exceptions as exceptions
88

9+
910
class GithubError(object):
1011
""" Handler for API errors """
1112

@@ -14,7 +15,7 @@ def __init__(self, response):
1415
self.status_code = response.status_code
1516
try:
1617
self.debug = self._parser.loads(response.content)
17-
except ValueError:
18+
except (ValueError, TypeError):
1819
self.debug = {'message': response.content}
1920

2021
def error_400(self):

github3/handlers/users.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import github3.models as models
88
from github3.converters import Rawlizer
99

10+
1011
class User(Handler):
1112
""" User handler with public access """
1213

@@ -25,6 +26,7 @@ def set_username(self, user):
2526
parse_user = str(getattr(user, 'login', user))
2627
self.username = parse_user
2728
self.prefix = '/'.join((self.prefix, parse_user))
29+
return self
2830

2931
def get(self):
3032
""" Return user """
@@ -61,6 +63,7 @@ def get_gists(self):
6163

6264
return self._get_resources('gists', model=models.Gist)
6365

66+
6467
class AuthUser(User):
6568
""" User handler with public and private access """
6669

@@ -116,6 +119,8 @@ def follow(self, user):
116119
Follow user
117120
118121
:param `user`: User model or username string
122+
123+
NOTE: Maybe bug in API, return text/html. Waitingf for answer
119124
"""
120125

121126
parse_user = str(getattr(user, 'login', user))
@@ -151,8 +156,8 @@ def create_key(self, **kwargs):
151156

152157
#TODO: render key.pub file
153158
key = {
154-
'title': kwargs.get('title',''),
155-
'key': kwargs.get('key','')
159+
'title': kwargs.get('title', ''),
160+
'key': kwargs.get('key', '')
156161
}
157162
return self._post_resource('keys', data=key, model=models.Key)
158163

github3/tests/test_core.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
4+
from mock import Mock, patch
5+
from unittest import TestCase
6+
from github3 import api
7+
from github3.exceptions import *
8+
import json
9+
import requests
10+
11+
12+
@patch.object(requests.sessions.Session, 'request')
13+
class TestGithubCore(TestCase):
14+
15+
def setUp(self):
16+
self.gh = api.GithubCore()
17+
self.assertEquals(self.gh.base_url, 'https://api.github.com/')
18+
self.assertEquals(self.gh._parser, json)
19+
self.base_url = self.gh.base_url
20+
self.parser = self.gh._parser
21+
22+
def test_parse_args(self, request_method):
23+
args = {
24+
'data': {'some': 'data'},
25+
'params': {'arg0': 'some'},
26+
'headers': 'out',
27+
'auth': 'out',
28+
'arg1': 'some',
29+
'arg2': 'some',
30+
'arg3': {'some': 'data', 'are': {'nested': 'true'}},
31+
}
32+
self.gh._parse_args(args)
33+
self.assertEquals(args, {
34+
'data': {'some': 'data'},
35+
'params': {'arg0': 'some', 'arg1': 'some', 'arg2': 'some',
36+
'arg3': {'some': 'data', 'are': {'nested': 'true'}}},
37+
'headers': 'out',
38+
'auth': 'out',
39+
})
40+
41+
def test_raise_errors(self, request_method):
42+
real_request = (self.gh._request, 'GET', 'test')
43+
request_method.return_value.status_code = 404
44+
self.assertRaises(NotFound, *real_request)
45+
46+
request_method.return_value.status_code = 400
47+
self.assertRaises(BadRequest, *real_request)
48+
49+
request_method.return_value.status_code = 422
50+
self.assertRaises(UnprocessableEntity, *real_request)
51+
52+
request_method.return_value.status_code = 401
53+
self.assertRaises(Unauthorized, *real_request)
54+
55+
def test_get(self, request_method):
56+
response = request_method.return_value
57+
response.content = self.parser.dumps({'test': 'test'})
58+
content = self.gh.get('core')
59+
request_method.assert_called_with('GET', self.base_url + 'core')
60+
self.assertEquals(content, {'test': 'test'})
61+
62+
response = request_method.return_value
63+
response.headers = {'link': 'url_with_links'}
64+
response.content = self.parser.dumps({'test': 'test'})
65+
header, content = self.gh.get('core', paginate=True)
66+
request_method.assert_called_with('GET', self.base_url + 'core')
67+
self.assertEquals(header, 'url_with_links')
68+
self.assertEquals(content, {'test': 'test'})
69+
70+
def test_head(self, request_method):
71+
pass # It has no sense using mocks
72+
73+
def test_post_and_patch(self, request_method):
74+
data = {'login': 'test', 'bio': 'test'}
75+
response = request_method.return_value
76+
response.status_code = 201
77+
response.content = self.parser.dumps({'post': 'done'})
78+
79+
content = self.gh.post('core', data=data)
80+
request_method.assert_called_with(
81+
'POST', self.base_url + 'core',
82+
data=self.parser.dumps(data))
83+
self.assertEquals(content, {'post': 'done'})
84+
85+
content = self.gh.post('core')
86+
request_method.assert_called_with(
87+
'POST', self.base_url + 'core',
88+
data=self.parser.dumps(None))
89+
self.assertEquals(content, {'post': 'done'})
90+
91+
response.status_code = 200
92+
content = self.gh.patch('core', data=data)
93+
request_method.assert_called_with(
94+
'PATCH', self.base_url + 'core',
95+
data=self.parser.dumps(data))
96+
self.assertEquals(content, {'post': 'done'})
97+
98+
content = self.gh.patch('core')
99+
request_method.assert_called_with(
100+
'PATCH', self.base_url + 'core',
101+
data=self.parser.dumps(None))
102+
self.assertEquals(content, {'post': 'done'})
103+
104+
def test_delete(self, request_method):
105+
data = {'test': 'test'}
106+
response = request_method.return_value
107+
response.status_code = 204
108+
response.content = self.parser.dumps({'delete': 'done'})
109+
delete = self.gh.delete('core', data=data)
110+
request_method.assert_called_with(
111+
'DELETE', self.base_url + 'core',
112+
data=self.parser.dumps(data))
113+
delete = self.gh.delete('core')
114+
request_method.assert_called_with(
115+
'DELETE', self.base_url + 'core')

0 commit comments

Comments
 (0)