Visitar URL original
Merge pull request #190 from sigmavirus24/feature-deployments-api · goodwillcoding/github3.py@63a7b45 · GitHub
Skip to content

Commit 63a7b45

Browse files
committed
Merge pull request sigmavirus24#190 from sigmavirus24/feature-deployments-api
Deployments API
2 parents 012c842 + ff4bef7 commit 63a7b45

9 files changed

Lines changed: 247 additions & 0 deletions

‎docs/repos.rst‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ This part of the documentation covers:
88
- :class:`Repository <github3.repos.repo.Repository>`
99
- :class:`Branch <github3.repos.branch.Branch>`
1010
- :class:`Contents <github3.repos.contents.Contents>`
11+
- :class:`Deployment <github3.repos.deployment.Deployment>`
12+
- :class:`DeploymentStatus <github3.repos.deployment.DeploymentStatus>`
1113
- :class:`Hook <github3.repos.hook.Hook>`
1214
- :class:`RepoTag <github3.repos.tag.RepoTag>`
1315
- :class:`RepoComment <github3.repos.comment.RepoComment>`
@@ -46,6 +48,16 @@ Repository Objects
4648

4749
---------
4850

51+
.. autoclass:: github3.repos.deployment.Deployment
52+
:members:
53+
54+
---------
55+
56+
.. autoclass:: github3.repos.deployment.DeploymentStatus
57+
:members:
58+
59+
---------
60+
4961
.. autoclass:: github3.repos.release.Release
5062
:members:
5163

‎github3/repos/deployment.py‎

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# -*- coding: utf-8 -*-
2+
from json import loads
3+
4+
from github3.models import GitHubCore
5+
from github3.users import User
6+
7+
8+
class Deployment(GitHubCore):
9+
CUSTOM_HEADERS = {
10+
'Accept': 'application/vnd.github.cannonball-preview+json'
11+
}
12+
13+
def __init__(self, deployment, session=None):
14+
super(Deployment, self).__init__(deployment, session)
15+
self._api = deployment.get('url')
16+
17+
#: GitHub's id of this deployment
18+
self.id = deployment.get('id')
19+
20+
#: SHA of the branch on GitHub
21+
self.sha = deployment.get('sha')
22+
23+
#: User object representing the creator of the deployment
24+
self.creator = deployment.get('creator')
25+
if self.creator:
26+
self.creator = User(self.creator, self)
27+
28+
#: JSON string payload of the Deployment
29+
self.payload = deployment.get('payload')
30+
31+
#: Date the Deployment was created
32+
self.created_at = deployment.get('created_at')
33+
if self.created_at:
34+
self.created_at = self._strptime(self.created_at)
35+
36+
#: Date the Deployment was updated
37+
self.updated_at = deployment.get('updated_at')
38+
if self.updated_at:
39+
self.updated_at = self._strptime(self.updated_at)
40+
41+
#: Description of the deployment
42+
self.description = deployment.get('description')
43+
44+
#: URL to get the statuses of this deployment
45+
self.statuses_url = deployment.get('statuses_url')
46+
47+
def __repr__(self):
48+
return '<Deployment [{0} @ {1}]>'.format(self.id, self.sha)
49+
50+
def create_status(self, state, target_url='', description=''):
51+
"""Create a new deployment status for this deployment.
52+
53+
:param str state: (required), The state of the status. Can be one of
54+
``pending``, ``success``, ``error``, or ``failure``.
55+
:param str target_url: The target URL to associate with this status.
56+
This URL should contain output to keep the user updated while the
57+
task is running or serve as historical information for what
58+
happened in the deployment. Default: ''.
59+
:param str description: A short description of the status. Default: ''.
60+
:return: partial :class:`DeploymentStatus <DeploymentStatus>`
61+
"""
62+
json = None
63+
64+
if state in ('pending', 'success', 'error', 'failure'):
65+
data = {'state': state, 'target_url': target_url,
66+
'description': description}
67+
response = self._post(self.statuses_url, data=data,
68+
headers=Deployment.CUSTOM_HEADERS)
69+
json = self._json(response, 201)
70+
71+
return DeploymentStatus(json, self) if json else None
72+
73+
def iter_statuses(self, number=-1, etag=None):
74+
"""Iterate over the deployment statuses for this deployment.
75+
76+
:param int number: (optional), the number of statuses to return.
77+
Default: -1, returns all statuses.
78+
:param str etag: (optional), the ETag header value from the last time
79+
you iterated over the statuses.
80+
:returns: generator of :class:`DeploymentStatus`\ es
81+
"""
82+
i = self._iter(int(number), self.statuses_url, DeploymentStatus,
83+
etag=etag)
84+
i.headers = Deployment.CUSTOM_HEADERS
85+
return i
86+
87+
88+
class DeploymentStatus(GitHubCore):
89+
def __init__(self, status, session=None):
90+
super(DeploymentStatus, self).__init__(status, session)
91+
self._api = status.get('url')
92+
93+
#: GitHub's id for this deployment status
94+
self.id = status.get('id')
95+
96+
#: State of the deployment status
97+
self.state = status.get('state')
98+
99+
#: Creater of the deployment status
100+
self.creator = status.get('creator')
101+
if self.creator:
102+
self.creator = User(self.creator, self)
103+
104+
#: JSON payload as a string
105+
self.payload = status.get('payload', '')
106+
107+
#: Parsed JSON payload
108+
self.json_payload = loads(self.payload)
109+
110+
#: Target URL of the deployment
111+
self.target_url = status.get('target_url')
112+
113+
#: Date the deployment status was created
114+
self.created_at = status.get('created_at')
115+
if self.created_at:
116+
self.created_at = self._strptime(self.created_at)
117+
118+
#: Date the deployment status was updated
119+
self.updated_at = status.get('updated_at')
120+
if self.updated_at:
121+
self.updated_at = self._strptime(self.updated_at)
122+
123+
#: Description of the deployment
124+
self.description = status.get('description')
125+
126+
def __repr__(self):
127+
return '<DeploymentStatus [{0}]>'.format(self.id)

‎github3/repos/repo.py‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from github3.repos.commit import RepoCommit
2727
from github3.repos.comparison import Comparison
2828
from github3.repos.contents import Contents, validate_commmitter
29+
from github3.repos.deployment import Deployment
2930
from github3.repos.hook import Hook
3031
from github3.repos.status import Status
3132
from github3.repos.stats import ContributorStats
@@ -517,6 +518,32 @@ def create_commit(self, message, tree, parents, author={}, committer={}):
517518
json = self._json(self._post(url, data=data), 201)
518519
return Commit(json, self) if json else None
519520

521+
@requires_auth
522+
def create_deployment(self, ref, force=False, payload='',
523+
auto_merge=False, description=''):
524+
"""Create a deployment.
525+
526+
:param str ref: (required), The ref to deploy. This can be a branch,
527+
tag, or sha.
528+
:param bool force: Optional parameter to bypass any ahead/behind
529+
checks or commit status checks. Default: False
530+
:param str payload: Optional JSON payload with extra information about
531+
the deployment. Default: ""
532+
:param bool auto_merge: Optional parameter to merge the default branch
533+
into the requested deployment branch if necessary. Default: False
534+
:param str description: Optional short description. Default: ""
535+
:returns: :class:`Deployment <github3.repos.deployment.Deployment>`
536+
"""
537+
json = None
538+
if ref:
539+
url = self._build_url('deployments', base_url=self._api)
540+
data = {'ref': ref, 'force': force, 'payload': payload,
541+
'auto_merge': auto_merge, 'description': description}
542+
headers = Deployment.CUSTOM_HEADERS
543+
json = self._json(self._post(url, data=data, headers=headers),
544+
201)
545+
return Deployment(json, self) if json else None
546+
520547
@requires_auth
521548
def create_file(self, path, message, content, branch=None,
522549
committer=None, author=None):
@@ -1210,6 +1237,21 @@ def iter_contributor_statistics(self, number=-1, etag=None):
12101237
url = self._build_url('stats', 'contributors', base_url=self._api)
12111238
return self._iter(int(number), url, ContributorStats, etag=etag)
12121239

1240+
def iter_deployments(self, number=-1, etag=None):
1241+
"""Iterate over deployments for this repository.
1242+
1243+
:param int number: (optional), number of deployments to return.
1244+
Default: -1, returns all available deployments
1245+
:param str etag: (optional), ETag from a previous request for all
1246+
deployments
1247+
:returns: generator of
1248+
:class:`Deployment <github3.repos.deployment.Deployment>`\ s
1249+
"""
1250+
url = self._build_url('deployments', base_url=self._api)
1251+
i = self._iter(int(number), url, Deployment, etag=etag)
1252+
i.headers.update(Deployment.CUSTOM_HEADERS)
1253+
return i
1254+
12131255
def iter_events(self, number=-1, etag=None):
12141256
"""Iterate over events on this repository.
12151257
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": "", "headers": {"Accept-Encoding": "gzip, deflate, compress", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/0.8.0", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic <BASIC_AUTH>"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"base64_string": "H4sIAAAAAAAAA62YTW/jNhCG/4ohYHupY1qW/Akstnvpx20P20svBiXRFhFJFEjKqVfIf+87+rJstHYSFggCW+Y8fDmcoWZYezLxdsHan699f+oVPBfezjtKm1ZRMCvP3tQ7VFm2734w8pjzk9SVWYTsapR6KYT2drWXqaMswBgPBYWmWYTzTTCfevzELdf7SmcYl1pbmh1jR90+nsUqZ+1HFvvhJliuks32sF0sxWq78NebSAg/2QY8Pqy/JJ8b80/B10+LX/EnE1FYGavCzFp1RMPzkK/99SqcB2GccLFZr8NNGIn1Yu1vIr5crGZlcfxJf/4bQnsde1LsPVIAg+tl8FKOpmaVEdqwG1+kNs9uV994vFn7zeCDyjL1AsqNxcOJ2GBJm9hQZHH8IAWWNVM2Fdg2LOmVHCWNfb+oxqpG7BgLDxPHIBa0SN4trLODLAq915ppUaoGWEUm1rK0EnHwfuzYGjSlj7yQP/jHaLA2gJC090tprGAtTojq95u3ZjUrtTzx+Eyu0SIW8gRnfxB5Yw+iPZd0YvyJoCDXSyv2PMnpBDjwzIjXqddMbzGoeTBFwr81+q9PmEQMu4oJv51tqopJJiPN9XlyUHoiCyv0gceI1ckL8mmCcJ38Ju3vVTT5+u2PUwCBGPc8KLmbuY3zr5LxWg6RHuzJXQTSEwBIehZnJw7Z1wz/u3yKkeo8Uppb9ejQuC/wClSz8VeKJSt47iS8AQCUKuXmyQYAkDSmEm8K7fsLbziG9flTVHnUHnlvyZr76JYArdzgnC+EcPLgAKmbFw3tCtKhiFM3bM+oWfup2W1+dJJK9iQvU5ETB6911kBqZlLevofs3lUdUYlxBdXi4CyVGAPUasf9bmQSZEDiJWix9U46ewarO49mvDhW/OhGHSDYdXpVH/mPh0XM/dy5UIBEjWe1jCr3Q+7CIaXt2x/57ubSC+YCbQqS+/XIAweMSpPGBXkuH9UF94kd4irs/wcsxektmr4/LmMeyyVGzS5ncnvod3QX73anfq+T1Zc5KNjctbcMVv9ccpvSyYWpSq6Fi+gOweqIo9iazWZ1KnhTVudCO2ZwSwCK6zhF1eiis+4ZqHpybptq/UAyE1TvmeKJU7oNEADbbXTR2hLGMVaiBXYS2ADGxFxmwlhVuJ2xF8qYXSgrDzJ+S8dyP92uQPUXI4tYTHmWTRG16LIl4hi1Nu0iCk7h5qGWgGXgBoKIWmQCIe3k9Z5Rs7bTjLVAI5LsuUUDsZj7i6d58OQH3/3tbrnZLYO/MG9VJldjwqf54mkRfp8Hu/lqt1zRmLIy6QhzM2RJQ3ACdiGIT3S78e/9/ailoFsDGBqTXgx/uZjt/uPqpTOLM8TSTdC/fc7T7WvpsSmkpioXJcqE7hJnWGVQnmfwdIL2K1GxmaEHZrQy+QNDl5vN+qogiFVVYD/8Fa6fXrhF7YpX7/hhX0gMTR9Nzc2+TVNvZ3VFXSWeXI6B0cMX+SyHjq9t2jp6uMUpKbVW3VVUgSRFv1+KomMPMoK2cTTejmxGI6Abv/Wyu1Uk4sCrzO7b4hmyE1T9mSopcoTOoZsuJuiurOuU2xVQVPWrofOi/YwGuhD2Bb1ir4YkjMuU3lfh6z9owAImzRMAAA==", "encoding": "utf-8"}, "headers": {"status": "200 OK", "x-ratelimit-remaining": "4991", "x-github-media-type": "github.v3; param=full; format=json", "x-content-type-options": "nosniff", "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", "transfer-encoding": "chunked", "x-github-request-id": "48A0D539:732B:4B2936D:530C0BD5", "content-encoding": "gzip", "vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "server": "GitHub.com", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Mon, 24 Feb 2014 03:06:56 GMT", "x-ratelimit-limit": "5000", "etag": "\"327326af871222fe773d0830dce89c73\"", "access-control-allow-credentials": "true", "date": "Tue, 25 Feb 2014 03:19:50 GMT", "access-control-allow-origin": "*", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1393300536"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py", "status_code": 200}, "recorded_at": "2014-02-25T03:18:12"}, {"request": {"body": "", "headers": {"Accept-Encoding": "gzip, deflate, compress", "Accept": "application/vnd.github.cannonball-preview+json", "User-Agent": "github3.py/0.8.0", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic <BASIC_AUTH>"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/deployments?per_page=100"}, "response": {"body": {"base64_string": "H4sIAAAAAAAAA+1Wy27bMBD8FwLpybFIihZFAUHRS78gvfSBYEXSMgFZEkjaqWvk37uSHdcPJIaCHHoIpAOx5gx3Z5dj/diSla9JQRYxdqFIEujctHJxsSqnul0m3nZtSIKrlrB2fhW4SHa/ptNukxjb1e1maZsYkpwyMiHOkAJXExIWgKwAtBQzqVMtM8WBGqCzMpOSaSuEVjmd29II6JEdbOoWEE5+4oMBY4P2rouubTCIAe0txNaTYkvqtnJ99Dix/elc0DylEwJriOAfTqur/C481LZbJpqJPJ1lJldzxWcW82QyL61lRqWg5/KzuRvEuUm/3PCv+DqDBTvdNuFIKYwLkExmgqZCG7C5lCIXpZVcsryEGc+mXVN98ne/MdHnPB56vci1DBDwapNWwfrTJiFiEZf1efX/+nom3Lyt6/YRWc4QZ9NweVByQOKRu7VrqjeyIHKbtHFhsW1Y0lMvlAtxfFIDaouTGiIq3PMEnAVvzejE9jhM67HBjLbDhRgIV+VhPMcneIJGttZX0Lg/0A/7eDZEByQZ7uroCgcUou26v8aj4TvYNum8W4Pe9NJ4q61bo9hvpDzDI2PcdBbvyTccil56F+0DmGXvAHOog33aewMeCRH3ccrELeW3XNxTXnBeCPEdcavOQLyyB/sdcfau6DDKFZNnTvI0eTe3lUpiRb174OrgtrwUSoFg81mmgGegc6ZQC6YgLSFVWuSKCWkQ+eG2L/p9Pymv/SVemiAiPtz2w20vPp4uJ2X3PYXz8kZr/K/dNr3ntKBZwejLbnu6573dFr3wyG1//QWCvNPd3QoAAA==", "encoding": "utf-8"}, "headers": {"status": "200 OK", "x-ratelimit-remaining": "4990", "x-github-media-type": "github.cannonball-preview; format=json", "x-content-type-options": "nosniff", "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", "transfer-encoding": "chunked", "x-github-request-id": "48A0D539:732B:4B2938C:530C0BD6", "content-encoding": "gzip", "vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "server": "GitHub.com", "cache-control": "private, max-age=60, s-maxage=60", "x-ratelimit-limit": "5000", "etag": "\"52769a23a89e1985df79e1ec5a980fb5\"", "access-control-allow-credentials": "true", "date": "Tue, 25 Feb 2014 03:19:50 GMT", "access-control-allow-origin": "*", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1393300536"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/deployments?per_page=100", "status_code": 200}, "recorded_at": "2014-02-25T03:18:12"}, {"request": {"body": "{\"state\": \"success\", \"target_url\": \"\", \"description\": \"\"}", "headers": {"Content-Length": "57", "Accept-Encoding": "gzip, deflate, compress", "Accept": "application/vnd.github.cannonball-preview+json", "User-Agent": "github3.py/0.8.0", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic <BASIC_AUTH>"}, "method": "POST", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/deployments/801/statuses"}, "response": {"body": {"string": "{\"url\":\"https://api.github.com/repos/sigmavirus24/github3.py/deployments/801/statuses/420\",\"id\":420,\"state\":\"success\",\"payload\":\"\\\"\\\"\",\"description\":\"\",\"target_url\":\"\",\"creator\":{\"login\":\"sigmavirus24\",\"id\":240830,\"avatar_url\":\"https://gravatar.com/avatar/c148356d89f925e692178bee1d93acf7?d=https%3A%2F%2Fidenticons.github.com%2F4a71764034cdae877484be72718ba526.png&r=x\",\"gravatar_id\":\"c148356d89f925e692178bee1d93acf7\",\"url\":\"https://api.github.com/users/sigmavirus24\",\"html_url\":\"https://github.com/sigmavirus24\",\"followers_url\":\"https://api.github.com/users/sigmavirus24/followers\",\"following_url\":\"https://api.github.com/users/sigmavirus24/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/sigmavirus24/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/sigmavirus24/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/sigmavirus24/subscriptions\",\"organizations_url\":\"https://api.github.com/users/sigmavirus24/orgs\",\"repos_url\":\"https://api.github.com/users/sigmavirus24/repos\",\"events_url\":\"https://api.github.com/users/sigmavirus24/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/sigmavirus24/received_events\",\"type\":\"User\",\"site_admin\":false},\"created_at\":\"2014-02-25T03:19:50Z\",\"updated_at\":\"2014-02-25T03:19:50Z\"}", "encoding": "utf-8"}, "headers": {"status": "201 Created", "x-ratelimit-remaining": "4989", "x-github-media-type": "github.cannonball-preview; format=json", "x-content-type-options": "nosniff", "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", "x-github-request-id": "48A0D539:732B:4B293BA:530C0BD6", "cache-control": "private, max-age=60, s-maxage=60", "vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "content-length": "1292", "server": "GitHub.com", "x-ratelimit-limit": "5000", "location": "https://api.github.com/repos/sigmavirus24/github3.py/deployments/801/statuses/420", "access-control-allow-credentials": "true", "date": "Tue, 25 Feb 2014 03:19:50 GMT", "etag": "\"86218b29258eb09da185aa12c281ebe3\"", "content-type": "application/json; charset=utf-8", "access-control-allow-origin": "*", "x-ratelimit-reset": "1393300536"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/deployments/801/statuses", "status_code": 201}, "recorded_at": "2014-02-25T03:18:13"}], "recorded_with": "betamax"}

0 commit comments

Comments
 (0)