10000 Merge pull request #415 from mwielgoszewski/develop · jim-minter/github3.py@dcb4e48 · GitHub
[go: up one dir, main page]

Skip to content

Commit dcb4e48

Browse files
committed
Merge pull request sigmavirus24#415 from mwielgoszewski/develop
Add support for filtering team/organization members by role
2 parents c04637a + c86e2a2 commit dcb4e48

File tree

9 files changed

+551
-12
lines changed

9 files changed

+551
-12
lines changed

github3/models.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,19 +218,20 @@ def _api(self, uri):
218218
self._uri = urlparse(uri)
219219
self.url = uri
220220

221-
def _iter(self, count, url, cls, params=None, etag=None):
221+
def _iter(self, count, url, cls, params=None, etag=None, headers=None):
222222
"""Generic iterator for this project.
223223
224224
:param int count: How many items to return.
225225
:param int url: First URL to start with
226226
:param class cls: cls to return an object of
227227
:param params dict: (optional) Parameters for the request
228228
:param str etag: (optional), ETag from the last call
229+
:param dict headers: (optional) HTTP Headers for the request
229230
:returns: A lazy iterator over the pagianted resource
230231
:rtype: :class:`GitHubIterator <github3.structs.GitHubIterator>`
231232
"""
232233
from .structs import GitHubIterator
233-
return GitHubIterator(count, url, cls, self, params, etag)
234+
return GitHubIterator(count, url, cls, self, params, etag, headers)
234235

235236
@property
236237
def ratelimit_remaining(self):

github3/orgs.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,25 @@ class Team(GitHubCore):
3737
3838
"""
3939

40+
# Roles available to members on a team.
41+
members_roles = frozenset(['member', 'maintainer', 'all'])
42+
4043
def _update_attributes(self, team):
4144
self._api = team.get('url', '')
4245
#: This team's name.
4346
self.name = team.get('name')
4447
#: Unique ID of the team.
4548
self.id = team.get('id')
46-
#: Permission leve of the grou F438 p
49+
#: Permission level of the group.
4750
self.permission = team.get('permission')
4851
#: Number of members in this team.
4952
self.members_count = team.get('members_count')
5053
members = team.get('members_url')
51-
#: Members URL Template. Expands with ``member``
54+
#: Members URL Template. Expands with ``member``.
5255
self.members_urlt = URITemplate(members) if members else None
5356
#: Number of repos owned by this team.
5457
self.repos_count = team.get('repos_count')
55-
#: Repositories url (not a template)
58+
#: Repositories url (not a template).
5659
self.repositories_url = team.get('repositories_url')
5760

5861
def _repr(self):
@@ -143,17 +146,26 @@ def is_member(self, username):
143146
return self._boolean(self._get(url), 204, 404)
144147

145148
@requires_auth
146-
def members(self, number=-1, etag=None):
149+
def members(self, role=None, number=-1, etag=None):
147150
r"""Iterate over the members of this team.
148151
152+
:param str role: (optional), filter members returned by their role
153+
in the team. Can be one of: ``"member"``, ``"maintainer"``,
154+
``"all"``. Default: ``"all"``.
149155
:param int number: (optional), number of users to iterate over.
150156
Default: -1 iterates over all values
151157
:param str etag: (optional), ETag from a previous request to the same
152158
endpoint
153159
:returns: generator of :class:`User <github3.users.User>`\ s
154160
"""
161+
headers = {}
162+
params = {}
163+
if role in self.members_roles:
164+
params['role'] = role
165+
headers['Accept'] = 'application/vnd.github.ironman-preview+json'
155166
url = self._build_url('members', base_url=self._api)
156-
return self._iter(int(number), url, User, etag=etag)
167+
return self._iter(int(number), url, User, params=params, etag=etag,
168+
headers=headers)
157169

158170
@requires_auth
159171
def repositories(self, number=-1, etag=None):
@@ -234,6 +246,13 @@ class Organization(BaseAccount):
234246
235247
"""
236248

249+
# Filters available when listing members. Note: ``"2fa_disabled"``
250+
# is only available for organization owners.
251+
members_filters = frozenset(['2fa_disabled', 'all'])
252+
253+
# Roles available to members in an organization.
254+
members_roles = frozenset(['all', 'admin', 'member'])
255+
237256
def _update_attributes(self, org):
238257
super(Organization, self)._update_attributes(org)
239258
self.type = self.type or 'Organization'
@@ -444,24 +463,32 @@ def events(self, number=-1, etag=None):
444463
url = self._build_url('events', base_url=self._api)
445464
return self._iter(int(number), url, Event, etag=etag)
446465

447-
def members(self, filter=None, number=-1, etag=None):
466+
def members(self, filter=None, role=None, number=-1, etag=None):
448467
r"""Iterate over members of this organization.
449468
450469
:param str filter: (optional), filter members returned by this method.
451470
Can be one of: ``"2fa_disabled"``, ``"all",``. Default: ``"all"``.
452471
Filtering by ``"2fa_disabled"`` is only available for organization
453472
owners with private repositories.
473+
:param str role: (optional), filter members returned by their role.
474+
Can be one of: ``"all"``, ``"admin"``, ``"member"``. Default:
475+
``"all"``.
454476
:param int number: (optional), number of members to return. Default:
455477
-1 will return all available.
456478
:param str etag: (optional), ETag from a previous request to the same
457479
endpoint
458480
:returns: generator of :class:`User <github3.users.User>`\ s
459481
"""
482+
headers = {}
460483
params = {}
461-
if filter in set(["2fa_disabled", "all"]):
484+
if filter in self.members_filters:
462485
params['filter'] = filter
486+
if role in self.members_roles:
487+
params['role'] = role
488+
headers['Accept'] = 'application/vnd.github.ironman-preview+json'
463489
url = self._build_url('members', base_url=self._api)
464-
return self._iter(int(number), url, User, params=params, etag=etag)
490+
return self._iter(int(number), url, User, params=params, etag=etag,
491+
headers=headers)
465492

466493
def public_members(self, number=-1, etag=None):
467494
r"""Iterate over public members of this organization.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"http_interactions": [
3+
{
4+
"recorded_at": "2014-07-21T02:20:59",
5+
"request": {
6+
"body": {
7+
"encoding": "utf-8",
8+
"string": ""
9+
},
10+
"headers": {
11+
"Accept": "application/vnd.github.v3.full+json",
12+
"Accept-Charset": "utf-8",
13+
"Accept-Encoding": "gzip, deflate",
14+
"Authorization": "Basic <BASIC_AUTH>",
15+
"Content-Type": "application/json",
16+
"User-Agent": "github3.py/1.0.0"
17+
},
18+
"method": "GET",
19+
"uri": "https://api.github.com/orgs/github3py"
20+
},
21+
"response": {
22+
"body": {
23+
"base64_string": "H4sIAAAAAAAAA52SPW/CMBCG/0rlOSROIFB5adcOVRekSl2iS3CMVce2bAdEEf+9ZxJKSie6Jed77+N570iUEVITRoQM276e2wNJiNwQlq8ei7xcJqR3Cp+3IVjPsgysTIfUtDFdZpzw2VTquDW+ukOTnRXYlO+4DvdJBwlqO97V3N0nHjXHbPg4YRnb10o21X+q/ZZOi8IOArhbJOegH1H2nrvG6IAAzlT7bKT/hENp6PjVn/RsECZZ0IdJWBoM12gmYbpXKkFfGwjSRGtfYSO90cnD+0vk3IFER4escezBA1b+IBDSB08YTUhrlDJ7hDv5kxrb4Ns2dOpmscltTM+icRwC31QQcJ6C5sWMlrNitaYLVpRsvvzAwXq7+ZWzmNHVrKDrfMkoZfMi5oSDjTDenAAtv4YFMWoCqMo6iVR5NS6D85m9xp5/45fIdUsE9Fn1HgRWz+kiElYKauMgmHH1WiqFi1cjPyJcCm2bQrRMpZ3UqTC7ZxHpRhPjOSlA/MeLg63jHKPeQoNd5nRVUJzxdrrT6Rvyb5wJlAMAAA==",
24+
"encoding": "utf-8",
25+
"string": ""
26+
},
27+
"headers": {
28+
"access-control-allow-credentials": "true",
29+
"access-control-allow-origin": "*",
30+
"access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
31+
"cache-control": "private, max-age=60, s-maxage=60",
32+
"content-encoding": "gzip",
33+
"content-security-policy": "default-src 'none'",
34+
"content-type": "application/json; charset=utf-8",
35+
"date": "Mon, 21 Jul 2014 02:20:58 GMT",
36+
"etag": "\"7a807b488b5268f40ea462dc5a957426\"",
37+
"last-modified": "Sun, 20 Jul 2014 16:00:32 GMT",
38+
"server": "GitHub.com",
39+
"status": "200 OK",
40+
"strict-transport-security": "max-age=31536000; includeSubdomains",
41+
"transfer-encoding": "chunked",
42+
"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding",
43+
"x-content-type-options": "nosniff",
44+
"x-frame-options": "deny",
45+
"x-github-media-type": "github.v3; param=full; format=json",
46+
"x-github-request-id": "48A0C4D3:55C1:7111A9:53CC790A",
47+
"x-ratelimit-limit": "5000",
48+
"x-ratelimit-remaining": "4948",
49+
"x-ratelimit-reset": "1405911623",
50+
"x-served-by": "a8d8e492d6966f0c23dee2eed64c678a",
51+
"x-xss-protection": "1; mode=block"
52+
},
53+
"status": {
54+
"code": 200,
55+
"message": "OK"
56+
},
57+
"url": "https://api.github.com/orgs/github3py"
58+
}
59+
},
60+
{
61+
"recorded_at": "2014-07-21T02:20:59",
62+
"request": {
63+
"body": {
64+
"encoding": "utf-8",
65+
"string": ""
66+
},
67+
"headers": {
68+
"Accept": "application/vnd.github.v3.full+json",
69+
"Accept-Charset": "utf-8",
70+
"Accept-Encoding": "gzip, deflate",
71+
"Authorization": "Basic <BASIC_AUTH>",
72+
"Content-Type": "application/json",
73+
"User-Agent": "github3.py/1.0.0"
74+
},
75+
"method": "GET",
76+
"uri": "https://api.github.com/orgs/github3py/members?per_page=100&filter=2fa_disabled"
77+
},
78+
"response": {
79+
"body": {
80+
"base64_string": "H4sIAAAAAAAAA62TXW+CMBSG/wvXxspHFbzZr9jVsphSDtgMKWkLxhH/+07FbJYtxjKvIKTPe14OPG9DUMtKNME2AM24gQ/N8mARiCLYrtOMZuEiYD0zTO06VeOpvTGt3hIyPtTLSph9l3caFJeNgcYsuTyQjozwC0ZV6hpgM4MVUAijgvKkTDOAJKbRpkxXrKAJBZrHCEwGteI6ZEzGSZo4XffmUE/aja0ugHO0lHUtj5gwfZv7Q8g3h/XGe9FUszKQG4g0e8CF4quc7YKENr6FLsxA7GUnCpui8RspKDxLXSmsdGywzUAUtPIS1+WaK9EaIRvfcg6LWVJVrBGfbE4WshojbC3fGhcGWejxt/SFR2ggrRI94ye7EgUcRI8rnhU4oTHPnFpAI17xN7ALFwZ2rDhYF0tWazgvftzUojqwXqhORwmetSZFySqNVzPtHOHfdvIwSWO6LtKszCIK6ywKN2kOEBZZzHi5wdkP2Dlpe9/PyWEvQ2/Z+Y7+kfIfS524f3nqJD3PVDf21nP8vN6uOmm+tjqwv68O/hxjJ40c4x9w9v0LOH8telEHAAA=",
81+
"encoding": "utf-8",
82+
"string": ""
83+
},
84+
"headers": {
85+
"access-control-allow-credentials": "true",
86+
"access-control-allow-origin": "*",
87+
"access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
88+
"cache-control": "private, max-age=60, s-maxage=60",
89+
"content-encoding": "gzip",
90+
"content-security-policy": "default-src 'none'",
91+
"content-type": "application/json; charset=utf-8",
92+
"date": "Mon, 21 Jul 2014 02:20:58 GMT",
93+
"etag": "\"b9889daf1e146f0dc5ac6d7f9852a69a\"",
94+
"server": "GitHub.com",
95+
"status": "200 OK",
96+
"strict-transport-security": "max-age=31536000; includeSubdomains",
97+
"transfer-encoding": "chunked",
98+
"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding",
99+
"x-content-type-options": "nosniff",
100+
"x-frame-options": "deny",
101+
"x-github-media-type": "github.v3; param=full; format=json",
102+
"x-github-request-id": "48A0C4D3:55C1:7111DD:53CC790A",
103+
"x-ratelimit-limit": "5000",
104+
"x-ratelimit-remaining": "4947",
105+
"x-ratelimit-reset": "1405911623",
106+
"x-served-by": "88d924ed861736d2749ce1a55766cb53",
107+
"x-xss-protection": "1; mode=block"
108+
},
109+
"status": {
110+
"code": 200,
111+
"message": "OK"
112+
},
113+
"url": "https://api.github.com/orgs/github3py/members?per_page=100"
114+
}
115+
}
116+
],
117+
"recorded_with": "betamax/{version}"
118+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"http_interactions": [
3+
{
4+
"recorded_at": "2014-07-21T02:20:59",
5+
"request": {
6+
"body": {
7+
"encoding": "utf-8",
8+
"string": ""
9+
},
10+
"headers": {
11+
"Accept": "application/vnd.github.v3.full+json",
12+
"Accept-Charset": "utf-8",
13+
"Accept-Encoding": "gzip, deflate",
14+
"Authorization": "Basic <BASIC_AUTH>",
15+
"Content-Type": "application/json",
16+
"User-Agent": "github3.py/1.0.0"
17+
},
18+
"method": "GET",
19+
"uri": "https://api.github.com/orgs/github3py"
20+
},
21+
"response": {
22+
"body": {
23+
"base64_string": "H4sIAAAAAAAAA52SPW/CMBCG/0rlOSROIFB5adcOVRekSl2iS3CMVce2bAdEEf+9ZxJKSie6Jed77+N570iUEVITRoQM276e2wNJiNwQlq8ei7xcJqR3Cp+3IVjPsgysTIfUtDFdZpzw2VTquDW+ukOTnRXYlO+4DvdJBwlqO97V3N0nHjXHbPg4YRnb10o21X+q/ZZOi8IOArhbJOegH1H2nrvG6IAAzlT7bKT/hENp6PjVn/RsECZZ0IdJWBoM12gmYbpXKkFfGwjSRGtfYSO90cnD+0vk3IFER4escezBA1b+IBDSB08YTUhrlDJ7hDv5kxrb4Ns2dOpmscltTM+icRwC31QQcJ6C5sWMlrNitaYLVpRsvvzAwXq7+ZWzmNHVrKDrfMkoZfMi5oSDjTDenAAtv4YFMWoCqMo6iVR5NS6D85m9xp5/45fIdUsE9Fn1HgRWz+kiElYKauMgmHH1WiqFi1cjPyJcCm2bQrRMpZ3UqTC7ZxHpRhPjOSlA/MeLg63jHKPeQoNd5nRVUJzxdrrT6Rvyb5wJlAMAAA==",
24+
"encoding": "utf-8",
25+
"string": ""
26+
},
27+
"headers": {
28+
"access-control-allow-credentials": "true",
29+
"access-control-allow-origin": "*",
30+
"access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
31+
"cache-control": "private, max-age=60, s-maxage=60",
32+
"content-encoding": "gzip",
33+
"content-security-policy": "default-src 'none'",
34+
"content-type": "application/json; charset=utf-8",
35+
"date": "Mon, 21 Jul 2014 02:20:58 GMT",
36+
"etag": "\"7a807b488b5268f40ea462dc5a957426\"",
37+
"last-modified": "Sun, 20 Jul 2014 16:00:32 GMT",
38+
"server": "GitHub.com",
39+
"status": "200 OK",
40+
"strict-transport-security": "max-age=31536000; includeSubdomains",
41+
"transfer-encoding": "chunked",
42+
"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding",
43+
"x-content-type-options": "nosniff",
44+
"x-frame-options": "deny",
45+
"x-github-media-type": "github.v3; param=full; format=json",
46+
"x-github-request-id": "48A0C4D3:55C1:7111A9:53CC790A",
47+
"x-ratelimit-limit": "5000",
48+
"x-ratelimit-remaining": "4948",
49+
"x-ratelimit-reset": "1405911623",
50+
"x-served-by": "a8d8e492d6966f0c23dee2eed64c678a",
51+
"x-xss-protection": "1; mode=block"
52+
},
53+
"status": {
54+
"code": 200,
55+
"message": "OK"
56+
},
57+
"url": "https://api.github.com/orgs/github3py"
58+
}
59+
},
60+
{
61+
"recorded_at": "2014-07-21T02:20:59",
62+
"request": {
63+
"body": {
64+
"encoding": "utf-8",
65+
"string": ""
66+
},
67+
"headers": {
68+
"Accept": "application/vnd.github.v3.full+json",
69+
"Accept-Charset": "utf-8",
70+
"Accept-Encoding": "gzip, deflate",
71+
"Authorization": "Basic <BASIC_AUTH>",
72+
"Content-Type": "application/json",
73+
"User-Agent": "github3.py/1.0.0"
74+
},
75+
"method": "GET",
76+
"uri": "https://api.github.com/orgs/github3py/members?per_page=100&role=all"
77+
},
78+
"response": {
79+
"body": {
80+
"base64_string": "H4sIAAAAAAAAA62TXW+CMBSG/wvXxspHFbzZr9jVsphSDtgMKWkLxhH/+07FbJYtxjKvIKTPe14OPG9DUMtKNME2AM24gQ/N8mARiCLYrtOMZuEiYD0zTO06VeOpvTGt3hIyPtTLSph9l3caFJeNgcYsuTyQjozwC0ZV6hpgM4MVUAijgvKkTDOAJKbRpkxXrKAJBZrHCEwGteI6ZEzGSZo4XffmUE/aja0ugHO0lHUtj5gwfZv7Q8g3h/XGe9FUszKQG4g0e8CF4quc7YKENr6FLsxA7GUnCpui8RspKDxLXSmsdGywzUAUtPIS1+WaK9EaIRvfcg6LWVJVrBGfbE4WshojbC3fGhcGWejxt/SFR2ggrRI94ye7EgUcRI8rnhU4oTHPnFpAI17xN7ALFwZ2rDhYF0tWazgvftzUojqwXqhORwmetSZFySqNVzPtHOHfdvIwSWO6LtKszCIK6ywKN2kOEBZZzHi5wdkP2Dlpe9/PyWEvQ2/Z+Y7+kfIfS524f3nqJD3PVDf21nP8vN6uOmm+tjqwv68O/hxjJ40c4x9w9v0LOH8telEHAAA=",
81+
"encoding": "utf-8",
82+
"string": ""
83+
},
84+
"headers": {
85+
"access-control-allow-credentials": "true",
86+
"access-control-allow-origin": "*",
87+
"access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval",
88+
"cache-control": "private, max-age=60, s-maxage=60",
89+
"content-encoding": "gzip",
90+
"content-security-policy": "default-src 'none'",
91+
"content-type": "application/json; charset=utf-8",
92+
"date": "Mon, 21 Jul 2014 02:20:58 GMT",
93+
"etag": "\"b9889daf1e146f0dc5ac6d7f9852a69a\"",
94+
"server": "GitHub.com",
95+
"status": "200 OK",
96+
"strict-transport-security": "max-age=31536000; includeSubdomains",
97+
"transfer-encoding": "chunked",
98+
"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding",
99+
"x-content-type-options": "nosniff",
100+
"x-frame-options": "deny",
101+
"x-github-media-type": "github.v3; param=full; format=json",
102+
"x-github-request-id": "48A0C4D3:55C1:7111DD:53CC790A",
103+
"x-ratelimit-limit": "5000",
104+
"x-ratelimit-remaining": "4947",
105+
"x-ratelimit-reset": "1405911623",
106+
"x-served-by": "88d924ed861736d2749ce1a55766cb53",
107+
"x-xss-protection": "1; mode=block"
108+
},
109+
"status": {
110+
"code": 200,
111+
"message": "OK"
112+
},
113+
"url": "https://api.github.com/orgs/github3py/members?per_page=100"
114+
}
115+
}
116+
],
117+
"recorded_with": "betamax/{version}"
118+
}

0 commit comments

Comments
 (0)
0