1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from pygithub3.core.client import Client
from pygithub3.core.result import Result
from pygithub3.requests import Factory
from pygithub3.core.errors import NotFound
class Service(object):
"""
You can configure each service with this keyword variables:
:param str login: Username to authenticate
:param str password: Username to authenticate
:param str user: Default username in requests
:param str repo: Default repository in requests
:param str token: Token to OAuth
:param int per_page: Items in each page of multiple returns
:param str base_url: To support another github-related API (untested)
:param stream verbose: Stream to write debug logs
You can configure the **authentication** with BasicAuthentication (login
and password) and with `OAuth <http://developer.github.com/v3/oauth/>`_ (
token).
If you include ``login``, ``password`` and ``token`` in config; Oauth has
precedence
Some API requests need ``user`` and/or ``repo`` arguments (e.g
:ref:`repos service <config precedence>`).
You can configure the default value here to avoid repeating
Some API requests return multiple resources with pagination. You can
configure how many items has each page.
You can configure ``verbose`` logging like `requests library <http://docs.
python-requests.org/en/v0.10.6/user/advanced/#verbose-logging>`_
"""
def __init__(self, **config):
self._client = Client(**config)
self.request_builder = Factory()
def get_user(self):
return self._client.user
def set_user(self, user):
""" Set user
:param str user: Default username in requests
"""
self._client.user = user
def get_repo(self):
return self._client.repo
def set_repo(self, repo):
""" Set repository
:param str repo: Default repository in requests
"""
self._client.repo = repo
def set_credentials(self, login, password):
""" Set Basic Authentication
:param str login: Username to authenticate
:param str password: Username to authenticate
"""
self._client.set_credentials(login, password)
def set_token(self, token):
""" Set OAuth token
:param str token: Token to OAuth
"""
self._client.set_token(token)
def make_request(self, request, **kwargs):
if 'user' in kwargs:
kwargs['user'] = kwargs['user'] or self.get_user()
if 'repo' in kwargs:
kwargs['repo'] = kwargs['repo'] or self.get_repo()
return self.request_builder(request, **kwargs)
def _bool(self, request, **kwargs):
try:
self._client.head(request, **kwargs)
return True
except NotFound:
return False
def _patch(self, request, **kwargs):
input_data = request.get_body()
response = self._client.patch(request, data=input_data, **kwargs)
return request.resource.loads(response.content)
def _put(self, request, **kwargs):
""" Bug in Github API? requests library?
I must send data as empty string when the specifications' of some PUT
request are 'Not send input data'. If I don't do that and send data as
None, the requests library doesn't send 'Content-length' header and the
server returns 411 - Required Content length (at least 0)
For instance:
- follow-user request doesn't send input data
- merge-pull request send data
For that reason I must do a conditional because I don't want to return
an empty string on follow-user request because it could be confused
Related: https://github.com/github/developer.github.com/pull/52
"""
input_data = request.get_body() or ''
response = self._client.put(request, data=input_data, **kwargs)
if response.status_code != 204: # != NO_CONTENT
return request.resource.loads(response.content)
def _delete(self, request, **kwargs):
input_data = request.get_body()
self._client.delete(request, data=input_data, **kwargs)
def _post(self, request, **kwargs):
input_data = request.get_body()
response = self._client.post(request, data=input_data, **kwargs)
return request.resource.loads(response.content)
def _get(self, request, **kwargs):
response = self._client.get(request, **kwargs)
return request.resource.loads(response.content)
def _get_result(self, request, **kwargs):
return Result(self._client, request, **kwargs)
class MimeTypeMixin(object):
"""
Mimetype support to Services that inherit this Mixin
Adds 4 public functions to service:
1. set_raw_mimetype
2. set_text_mimetype
3. set_html_mimetype
4. set_full_mimetype
"""
VERSION = 'beta'
def __set_mimetype(self, mimetype):
self.mimetype = 'application/vnd.github.%s.%s+json' % (
self.VERSION, mimetype)
def set_raw_mimetype(self):
self.__set_mimetype('raw')
def set_text_mimetype(self):
self.__set_mimetype('text')
def set_html_mimetype(self):
self.__set_mimetype('html')
def set_full_mimetype(self):
self.__set_mimetype('full')
def _get_mimetype_as_header(self):
try:
return {'headers': {'Accept': self.mimetype}}
except AttributeError:
return {}
|