8000 Initial commit for implementing ImportIssue Beta API · pythonthings/github3.py@08eb621 · GitHub
[go: up one dir, main page]

Skip to content

Commit 08eb621

Browse files
Initial commit for implementing ImportIssue Beta API
Two new methods have been added to repo.py - import_issue and imported_issue.
1 parent b250397 commit 08eb621

File tree

7 files changed

+182
-2
lines changed

7 files changed

+182
-2
lines changed

docs/repos.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This part of the documentation covers:
1212
- :class:`Deployment <github3.repos.deployment.Deployment>`
1313
- :class:`DeploymentStatus <github3.repos.deployment.DeploymentStatus>`
1414
- :class:`Hook <github3.repos.hook.Hook>`
15+
- :class:`ImportedIssue <github3.repos.issue_import.ImportedIssue>`
1516
- :class:`PagesInfo <github3.repos.pages.PagesInfo>`
1617
- :class:`PagesBuild <github3.repos.pages.PagesBuild>`
1718
- :class:`Release <github3.repos.release.Release>`
@@ -89,6 +90,13 @@ Repository Objects
8990

9091
---------
9192

93+
.. module:: github3.repos.imported_issue
94+
95+
.. autoclass:: github3.repos.issue_import.ImportedIssue
96+
:members:
97+
98+
---------
99+
92100
.. module:: github3.repos.pages
93101

94102
.. autoclass:: github3.repos.pages.PagesInfo

github3/repos/issue_import.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: utf-8 -*-
2+
from ..models import GitHubCore
3+
"""
4+
github3.repos.issue_import
5+
==========================
6+
7+
This module contains the ImportedIssue object for Github's import issue API
8+
9+
"""
10+
11+
12+
class ImportedIssue(GitHubCore):
13+
"""
14+
The :class:`ImportedIssue <ImportedIssue>` object. This represents
15+
information from the Import Issue API.
16+
17+
See also: https://gist.github.com/jonmagic/5282384165e0f86ef105
18+
"""
19+
20+
IMPORT_CUSTOM_HEADERS = {
21+
'Accept': 'application/vnd.github.golden-comet-preview+json'
22+
}
23+
24+
def _update_attributes(self, json):
25+
self.id = json.get('id', None)
26+
self.status = json.get('status', None)
27+
self.url = json.get('url', None)
28+
# Since created_at and updated_at returns slightly different format
29+
# we can't use self._strptime
30+
# For example, repo correctly returns '2015-04-15T03:40:51Z'
31+
# For ImportedIssue, the format is '2016-01-14T10:57:56-08:00'
32+
self.created_at = json.get('created_at', None)
33+
self.updated_at = json.get('updated_at', None)
34+
self.import_issues_url = json.get('import_issues_url')
35+
self.repository_url = json.get('repository_url', None)

github3/repos/repo.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from .contents import Contents, validate_commmitter
2929
from .deployment import Deployment
3030
from .hook import Hook
31+
from .issue_import import ImportedIssue
3132
from ..licenses import License
3233
from .pages import PagesBuild, PagesInfo
3334
from .status import Status
@@ -1264,6 +1265,60 @@ def ignore(self):
12641265
json = self._json(self._put(url, data=dumps({'ignored': True})), 200)
12651266
return self._instance_or_null(Subscription, json)
12661267

1268+
@requires_auth
1269+
def imported_issue(self, imported_issue_id):
1270+
"""Retrieve imported issue specified by imported issue id.
1271+
1272+
:param int imported_issue_id: (required) id of imported issue
1273+
:returns: :class:`Imported Issue <github3.repos.
1274+
issue_import.ImportedIssue>`
1275+
"""
1276+
url = self._build_url('import/issues', imported_issue_id,
1277+
base_url=self._api)
1278+
data = self._get(url, headers=ImportedIssue.IMPORT_CUSTOM_HEADERS)
1279+
json = self._json(data, 200)
1280+
return self._instance_or_null(ImportedIssue, json)
1281+
1282+
@requires_auth
1283+
def import_issue(self, title, body, created_at, assignee=None,
1284+
milestone=None, closed=None, labels=None, comments=None):
1285+
"""Import issue into this repository.
1286+
1287+
:param string title: (required) Title of issue
1288+
:param string body: (required) Body of issue
1289+
:param timestamp created_at: (required) Creation timestamp
1290+
:param string assignee: (optional) Username to assign issue to
1291+
:param int milestone: (optional) Milestone ID
1292+
:param boolean closed: (optional) Status of issue is Closed if True
1293+
:param list labels: (optional) List of labels containing string names
1294+
:param list comments: (optional) List of dictionaries which contain
1295+
created_at and body attributes
1296+
:returns: :class:`ImportedIssue <github3.repos.
1297+
issue_import.ImportedIssue>`
1298+
"""
1299+
1300+
issue = {
1301+
'issue': {
1302+
'title': title,
1303+
'body': body,
1304+
'created_at': created_at,
1305+
'assignee': assignee,
1306+
'milestone': milestone,
1307+
'closed': closed,
1308+
'labels': labels,
1309+
'comments': comments
1310+
}
1311+
}
1312+
1313+
self._remove_none(issue['issue'])
1314+
url = self._build_url('import/issues', base_url=self._api)
1315+
1316+
data = self._post(url, data=issue,
1317+
headers=ImportedIssue.IMPORT_CUSTOM_HEADERS)
1318+
1319+
json = self._json(data, 200)
1320+
return self._instance_or_null(ImportedIssue, json)
1321+
12671322
def is_assignee(self, username):
12681323
"""Check if the user can be assigned an issue on this repository.
12691324
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "GET", "uri": "https://api.github.com/repos/github3py/test_rename1"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+2Yz27jNhDG30XXumYcb7a7BortG/TSUy8GLdESEYkUSMpGIuTd+w2p/yhkO7wGCAJJ1vz0cThDzrBNZJYc9vtvu93T95+bRPFKJIfECeuORtDdLtkk56Ysj91PuXRFc9rXb2zxkr4qYZJDm5Q6lwqQ4U0Q6Cu7P348716+bxJ+4Y6bY2NKvFU4V9sDY+Gh3QarxgqTauWEcttUV6xhnfWvy5978HLTQQic4MECVssOFKxBs2yqp3BVuRAQfvbvT98867LUV9gv9a5+gg1m5D6PkCr/DAJmLdOuEHAYhvFBg5fWPSjHm7QYGOZVZgSxmAIjssckdUYQRJP90TIjau1pzcmmRtZOavWgtJkpUNrkXMl3/gkUTC0IJOpBEd4EpuKCiHvQNti0rDbywtM3cocRqZAXePczvIUxcO6tpqz8e+IZ8rl04sizipLtzEsrPjaJ1+Dwsn+wQXbdFefLXM7EMJshvc7avA7Q1VzznhwzaEkm0A3/rhGQV7DH4F/FWwyGzFuG/102pEhRftKGO30r01flzTgtm95SXDjBqxjZ3h6cQusoL3p7cKS1jbgrSFdH7TGW9YmgmuoUVqp7wn+VHABQyq2VuRIixnsDo2X9UnoyXKVFFLVHtCxc+XnmeYxQMgflVOpTDAbbGPOMltmCh53DHSO1EZQQM6YR51ihhBiYzsTNtBdJjIGIncth0mNU9gjWdt4sucobnkdBBwYt6NiSc/5+s9ZYzZgRAiKVUEaemuhVbcSQzrDZI8ej3DlSRqYvINZrkvXRT+oQP/6qkrf281VgR5hFezyV4nNJpvvbxcdNsYRo2bgEhyW+g0d4tlvje5XTT3SFekww9AjW/lZzV9BahS/V3IgIyR2BtSeO4mi73baF4L74rYSJS9sAAImbtEClF6Gy7REobSrufFF9JpEZiuxS8yzGrwMDvDCDEUoDYDrzNRrDGHnefgqsZInWU6uoNXWETNFKO3mW6T19xWqSzTjtLytVKja8LDeIVidTifhFz0YTiIpSRLknADAI9OGhrSgFQjnG40YERMtCG5gagX4hO3KHQv/5affy+9M3/P2zezm8/Djsn//FOJo6W3nnZUfv1I0tbmCw6HXBhyt0/P/XcM/aBWrhgba2GO3+Gq0O4XJ5FNFZpSWiaBHsd3/xstyDblpCZ6ErUaMcSA4KYU392Tuun2b7eqobBU/j4ZU7FJ7YQcdHfS3QAwpujyHnkoMzDbVzeDKm9OThVb7K6Uukww4NW2i6xg9V0hjdHcAErboWqvvWRFBotkjt5PeZen+TiTNvSncM9S/iqOLW4SwIUSFMhRHQoQCdDHXNahgLRUwvmdaBcI0ednoA8HWe1B22fZ0njSeF6ydvX+dJ89NOlBOzwyik5f3nSUq4K05cJmvCtPjvVpTdx39kO0E5RxYAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-github-media-type": "github.v3; param=full; format=json", "x-oauth-scopes": "admin:public_key, gist, repo, user", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "x-accepted-oauth-scopes": "repo", "etag": "W/\"c68f5ce7b37c113680b45bf278d8a0e8\"", "cache-control": "private, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "4998", "x-served-by": "2811da37fbdda4367181b328b22b2499", "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": "3F91CA23:B792:8B05480:5697FC33", "access-control-allow-credentials": "true", "last-modified": "Sat, 04 Apr 2015 15:58:51 GMT", "date": "Thu, 14 Jan 2016 19:51:21 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1452804639"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/github3py/test_rename1"}, "recorded_at": "2016-01-14T19:51:21"}, {"request": {"body": {"string": "{\"issue\": {\"body\": \"bar\", \"title\": \"foo\", \"created_at\": \"2014-03-16T17:15:42Z\"}}", "encoding": "utf-8"}, "headers": {"Content-Length": "80", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.golden-comet-preview+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "POST", "uri": "https://api.github.com/repos/github3py/test_rename1/import/issues"}, "response": {"body": {"string": "{\"id\":399790,\"status\":\"pending\",\"url\":\"https://api.github.com/repos/github3py/test_rename1/import/issues/399790\",\"import_issues_url\":\"https://api.github.com/repos/github3py/test_rename1/import/issues\",\"repository_url\":\"https://api.github.com/repos/github3py/test_rename1\",\"created_at\":\"2016-01-14T11:51:21-08:00\",\"updated_at\":\"2016-01-14T11:51:21-08:00\"}", "encoding": "utf-8"}, "headers": {"status": "202 Accepted", "x-accepted-oauth-scopes": "", "content-length": "354", "x-github-media-type": "github.golden-comet-preview; format=json", "x-content-type-options": "nosniff", "content-security-policy": "default-src 'none'", "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": "3F91CA23:B792:8B05A4D:5697FC39", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "x-ratelimit-remaining": "4997", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-oauth-scopes": "admin:public_key, gist, repo, user", "access-control-allow-credentials": "true", "date": "Thu, 14 Jan 2016 19:51:21 GMT", "x-frame-options": "deny", "access-control-allow-origin": "*", "content-type": "application/json; charset=utf-8", "x-xss-protection": "1; mode=block", "x-ratelimit-reset": "1452804639"}, "status": {"message": "Accepted", "code": 202}, "url": "https://api.github.com/repos/github3py/test_rename1/import/issues"}, "recorded_at": "2016-01-14T19:51:23"}], "recorded_with": "betamax/0.5.0"}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{&qu 10000 ot;request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "GET", "uri": "https://api.github.com/repos/github3py/test_rename1"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+2YzW7jNhDH30XXumYUb7a7BortG/TSUy8GLdESEUkUSMpGIuTd+x+S+rBQyHZ4DRAEssT5cTicIWemT2Se7He7b2n69P3nJml4LZJ9YoWxBy3oV5psklNXVYfwqZC27I679o0tBqlLI3Sy75NKFbIBZBwJAs2S/vHjOX35vkn4mVuuD52uMKq0tjV7xvxLs/VSnRE6U40Vjd1mqmYdC9K/zn/uwCt0gBA4wYsFrJUB5KVBM2yuT2nraqGA/+zGz0eeVFWpC+SX+q5OwUYxMp9DyKb4DAJiPVO2FDAYlvFBi5fGPqiOE+mxMOyrzAlisAVa5I+pFISgEG32R8+0aJWjdUeTadlaqZoHVbsSBUrpgjfynX8CBVEDAin1oBJOBKLiDI97UNbL9KzV8syzNzKHFpmQZ1j3M7yFMHD2raWo/HtmGbK5tOLA85qC7cQrIz42idPBYrB7sUF03eXny1jOxbibPrxOSr+O0NVYc5acImhJJtAN+64REFeQx+JfxVsMhsR7hv8hGjKEKD8qza26Femr6l1xejb/SX5hBa9j1Hby4JRKRVnRyYMjjenEXU66umqHMWwIhKarj/6kusf9V8keAE25MbJohIix3sjo2XCUHjVvsjKKOiB65p/cPvMiRlESB+VYqWMMBtcYc4yemZL7m8MeInUjKCGumFqcYhUlxMi0Om6nnZLEGIm4uSw2PUbLAcH6YM2KN0XHiyjoyKADHVdywd9v5hqrETNBQKQUSstjF32qTRjS01/2iPEoc06UiekSiPWcZH31szzErb+u5a37fBUYCFfeHk8l/1yS6fft5OOmsoTo2XQE+yM+wCMsG874Qcv5FCFRj3GGAcH631puSzqrMFPLtYhQORBYf+RIjrbbbV8K7pLfWui4sPUAkLjOSmR6EVr2AwKpTc2tS6pPpGSOJLtSPI+x68gAz+9ghKYeMN/5FoVhjHpOfg6sZYXSUzVRZ+oEmaMbZeVJZvfUFatBdsXpfxnZZGLDq2oDb7Uyk/Bf1Gy0gcgoRZR5PACLQB3uy4pKwJVjLK6FR/TMl4GZFqgX8gO3SPSfn9KX35++4e+f9GX/8mO/e/4X6+jafGXMS0pj2s6UNzA49ILz4QkV//8V3FflApXwQBtTTnJ/TVJ7/7hsRQSprIIXLZz97hnPyzvopiT0LFUtWqQDyb6BW1N99o7np6t7PVNdA0vj5YVbJJ64QadXQy4wAEpuDj7mkr3VHZVzeDOF9OzlRb7K+SDSw4wFmy+6polqqbUKDRivq2pFE+YaFEqpcUHFFmk7+45GzqS9+5iLE+8qe/D5L/yo5saiFwSvELrGCqgpQJ2hUKz6tZDHDCrTOeCfUcPOGwBf/aTQbPvqJ02dwvXO21c/6brbiXTiqhmFsLy/n9QIe8EhMDuk5sl/OFHSj/8AY3HIZUcWAAA=", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-github-media-type": "github.v3; param=full; format=json", "x-oauth-scopes": "admin:public_key, gist, repo, user", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "x-accepted-oauth-scopes": "repo", "etag": "W/\"e619b5d14c30e3dcd78e53e65820ff71\"", "cache-control": "private, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "4996", "x-served-by": "4c8b2d4732c413f4b9aefe394bd65569", "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": "3F91CA23:12180:7F4807A:5697FC60", "access-control-allow-credentials": "true", "last-modified": "Sat, 04 Apr 2015 15:58:51 GMT", "date": "Thu, 14 Jan 2016 19:52:00 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1452804639"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/github3py/test_rename1"}, "recorded_at": "2016-01-14T19:52:03"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.golden-comet-preview+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "GET", "uri": "https://api.github.com/repos/github3py/test_rename1/import/issues/399790"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA62QSw7CMAxE7+J1W8ctv+Yc7KPQRhCJ0ih2FhXi7oRG7FHF9sl6npkn+BF01/fHXlXAYiUxaPBTmKO4ESpI8Z7BTSSwRrTBN1cvt3RphnnC6MLMWEAXFhTHYqJ72MkRFgl65uQYy48sLNgUbP6kz941i5c5LtulWTNEZ3NzYyXXbhUdakU17c5Eek+6pVqdtFKfYcL42+HadHum74AErzdEdv1KrgEAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-github-media-type": "github.golden-comet-preview; format=json", "x-oauth-scopes": "admin:public_key, gist, repo, user", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "x-accepted-oauth-scopes": "", "etag": "W/\"606e4220537a9c67c63ad836e0d0874c\"", "cache-control": "private, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "4995", "x-served-by": "cee4c0729c8e9147e7abcb45b9d69689", "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": "3F91CA23:12180:7F4815B:5697FC60", "access-control-allow-credentials": "true", "date": "Thu, 14 Jan 2016 19:52:03 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1452804639"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/github3py/test_rename1/import/issues/399790"}, "recorded_at": "2016-01-14T19:52:03"}], "recorded_with": "betamax/0.5.0"}

tests/integration/test_repos_repo.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,32 @@ def test_issue(self):
573573
issue = repository.issue(525)
574574
assert isinstance(issue, github3.issues.issue.Issue)
575575

576+
def test_imported_issue(self):
577+
"""Test the ability to retrieve an imported issue by id."""
578+
self.token_login()
579+
cassette_name = self.cassette_name('imported_issue')
580+
with self.recorder.use_cassette(cassette_name):
581+
repository = self.gh.repository('github3py', 'test_rename1')
582+
imported_issue = repository.imported_issue(399790)
583+
584+
assert isinstance(imported_issue,
585+
github3.repos.issue_import.ImportedIssue)
586+
587+
def test_import_issue(self):
588+
"""Test the ability to import an issue."""
589+
self.token_login()
590+
cassette_name = self.cassette_name('import_issue')
591+
with self.recorder.use_cassette(cassette_name):
592+
issue = {
593+
'title': 'foo',
594+
'body': 'bar',
595+
'created_at': '2014-03-16T17:15:42Z'
596+
}
597+
repository = self.gh.repository('github3py', 'test_rename1')
598+
imported_issue = repository.import_issue(**issue)
599+
600+
isinstance(imported_issue, github3.repos.issue_import.ImportedIssue)
601+
576602
def test_issue_events(self):
577603
"""Test that a user can iterate over issue events in a repo."""
578604
cassette_name = self.cassette_name('issue_events')
@@ -786,7 +812,7 @@ def test_latest_release(self):< 6555 /div>
786812
assert isinstance(release, github3.repos.release.Release)
787813

788814
def test_release_from_tag(self):
789-
"""Test the ability to retrieve a release by tag name"""
815+
"""Test the ability to retrieve a release by tag name."""
790816
cassette_name = self.cassette_name('release_from_tag')
791817
with self.recorder.use_cassette(cassette_name):
792818
repository = self.gh.repository('sigmavirus24', 'github3.py')

0 commit comments

Comments
 (0)
0