...
 
Commits (2)
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: PyGithub Name: PyGithub
Version: 1.43.3 Version: 1.43.7
Summary: Use the full Github API v3 Summary: Use the full Github API v3
Home-page: http://pygithub.readthedocs.io/en/latest/ Home-page: http://pygithub.readthedocs.io/en/latest/
Author: Vincent Jacques Author: Vincent Jacques
...@@ -39,9 +39,9 @@ Classifier: Programming Language :: Python ...@@ -39,9 +39,9 @@ Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development Classifier: Topic :: Software Development
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
Provides-Extra: integrations Provides-Extra: integrations
Metadata-Version: 2.1
Name: PyGithub
Version: 1.43.7
Summary: Use the full Github API v3
Home-page: http://pygithub.readthedocs.io/en/latest/
Author: Vincent Jacques
Author-email: vincent@vincent-jacques.net
License: UNKNOWN
Description: (Very short) Tutorial
=====================
First create a Github instance::
from github import Github
# using username and password
g = Github("user", "password")
# or using an access token
g = Github("access_token")
Then play with your Github objects::
for repo in g.get_user().get_repos():
print(repo.name)
repo.edit(has_wiki=False)
Reference documentation
=======================
See http://pygithub.readthedocs.io/en/latest/
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
Provides-Extra: integrations
COPYING
COPYING.LESSER
MANIFEST.in
README.md
setup.py
PyGithub.egg-info/PKG-INFO
PyGithub.egg-info/SOURCES.txt
PyGithub.egg-info/dependency_links.txt
PyGithub.egg-info/requires.txt
PyGithub.egg-info/top_level.txt
github/AuthenticatedUser.py
github/Authorization.py
github/AuthorizationApplication.py
github/Branch.py
github/BranchProtection.py
github/Clones.py
github/Commit.py
github/CommitCombinedStatus.py
github/CommitComment.py
github/CommitStats.py
github/CommitStatus.py
github/Comparison.py
github/Consts.py
github/ContentFile.py
github/Download.py
github/Event.py
github/File.py
github/Gist.py
github/GistComment.py
github/GistFile.py
github/GistHistoryState.py
github/GitAuthor.py
github/GitBlob.py
github/GitCommit.py
github/GitObject.py
github/GitRef.py
github/GitRelease.py
github/GitReleaseAsset.py
github/GitTag.py
github/GitTree.py
github/GitTreeElement.py
github/GithubException.py
github/GithubObject.py
github/GitignoreTemplate.py
github/Hook.py
github/HookDescription.py
github/HookResponse.py
github/InputFileContent.py
github/InputGitAuthor.py
github/InputGitTreeElement.py
github/Installation.py
github/InstallationAuthorization.py
github/Invitation.py
github/Issue.py
github/IssueComment.py
github/IssueEvent.py
github/IssuePullRequest.py
github/Label.py
github/Legacy.py
github/License.py
github/MainClass.py
github/Migration.py
github/Milestone.py
github/NamedUser.py
github/Notification.py
github/NotificationSubject.py
github/Organization.py
github/PaginatedList.py
github/Path.py
github/Permissions.py
github/Plan.py
github/Project.py
github/ProjectCard.py
github/ProjectColumn.py
github/PullRequest.py
github/PullRequestComment.py
github/PullRequestMergeStatus.py
github/PullRequestPart.py
github/PullRequestReview.py
github/Rate.py
github/RateLimit.py
github/Reaction.py
github/Referrer.py
github/Repository.py
github/RepositoryKey.py
github/Requester.py
github/RequiredPullRequestReviews.py
github/RequiredStatusChecks.py
github/SourceImport.py
github/Stargazer.py
github/StatsCodeFrequency.py
github/StatsCommitActivity.py
github/StatsContributor.py
github/StatsParticipation.py
github/StatsPunchCard.py
github/Tag.py
github/Team.py
github/Topic.py
github/UserKey.py
github/View.py
github/__init__.py
\ No newline at end of file
deprecated
pyjwt
requests>=2.14.0
[integrations]
cryptography
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
[![License](https://img.shields.io/badge/license-LGPL-blue.svg)](https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License) [![License](https://img.shields.io/badge/license-LGPL-blue.svg)](https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License)
[![Join the chat at https://gitter.im/PyGithub/PyGithub](https://badges.gitter.im/PyGithub/PyGithub.svg)](https://gitter.im/PyGithub/PyGithub?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/PyGithub/PyGithub](https://badges.gitter.im/PyGithub/PyGithub.svg)](https://gitter.im/PyGithub/PyGithub?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Open Source Helpers](https://www.codetriage.com/pygithub/pygithub/badges/users.svg)](https://www.codetriage.com/pygithub/pygithub) [![Open Source Helpers](https://www.codetriage.com/pygithub/pygithub/badges/users.svg)](https://www.codetriage.com/pygithub/pygithub)
[![codecov](https://codecov.io/gh/PyGithub/PyGithub/branch/master/graph/badge.svg)](https://codecov.io/gh/PyGithub/PyGithub)
PyGitHub is a Python (2 and 3) library to access the [GitHub API v3] and [Github Enterprise API v3]. PyGitHub is a Python (2 and 3) library to access the [GitHub API v3] and [Github Enterprise API v3].
This library enables you to manage [GitHub] resources such as repositories, user profiles, and organizations in your Python applications. This library enables you to manage [GitHub] resources such as repositories, user profiles, and organizations in your Python applications.
......
pygithub (1.43.7-1) UNRELEASED; urgency=medium
* New upstream version 1.43.7
-- Emmanuel Arias <emamnuelarias30@gmail.com> Thu, 25 Apr 2019 01:29:24 +0000
pygithub (1.43.3-1) unstable; urgency=medium pygithub (1.43.3-1) unstable; urgency=medium
[Ondřej Nový] [Ondřej Nový]
......
...@@ -55,6 +55,7 @@ import github.Issue ...@@ -55,6 +55,7 @@ import github.Issue
import github.Event import github.Event
import github.Authorization import github.Authorization
import github.Notification import github.Notification
import github.Migration
import Consts import Consts
...@@ -237,6 +238,14 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ...@@ -237,6 +238,14 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject):
self._completeIfNotSet(self._name) self._completeIfNotSet(self._name)
return self._name.value return self._name.value
@property
def node_id(self):
"""
:type: string
"""
self._completeIfNotSet(self._node_id)
return self._node_id.value
@property @property
def organizations_url(self): def organizations_url(self):
""" """
...@@ -486,7 +495,7 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ...@@ -486,7 +495,7 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject):
assert description is github.GithubObject.NotSet or isinstance(description, (str, unicode)), description assert description is github.GithubObject.NotSet or isinstance(description, (str, unicode)), description
post_parameters = { post_parameters = {
"public": public, "public": public,
"files": dict((key, value._identity) for key, value in files.iteritems()), "files": {key: value._identity for key, value in files.iteritems()},
} }
if description is not github.GithubObject.NotSet: if description is not github.GithubObject.NotSet:
post_parameters["description"] = description post_parameters["description"] = description
...@@ -835,23 +844,30 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ...@@ -835,23 +844,30 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject):
) )
return github.Notification.Notification(self._requester, headers, data, completed=True) return github.Notification.Notification(self._requester, headers, data, completed=True)
def get_notifications(self, all=github.GithubObject.NotSet, participating=github.GithubObject.NotSet): def get_notifications(self, all=github.GithubObject.NotSet, participating=github.GithubObject.NotSet, since=github.GithubObject.NotSet, before=github.GithubObject.NotSet):
""" """
:calls: `GET /notifications <http://developer.github.com/v3/activity/notifications>`_ :calls: `GET /notifications <http://developer.github.com/v3/activity/notifications>`_
:param all: bool :param all: bool
:param participating: bool :param participating: bool
:param since: datetime.datetime
:param before: datetime.datetime
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Notification.Notification` :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Notification.Notification`
""" """
assert all is github.GithubObject.NotSet or isinstance(all, bool), all assert all is github.GithubObject.NotSet or isinstance(all, bool), all
assert participating is github.GithubObject.NotSet or isinstance(participating, bool), participating assert participating is github.GithubObject.NotSet or isinstance(participating, bool), participating
assert since is github.GithubObject.NotSet or isinstance(since, datetime.datetime), since
assert before is github.GithubObject.NotSet or isinstance(before, datetime.datetime), before
params = dict() params = dict()
if all is not github.GithubObject.NotSet: if all is not github.GithubObject.NotSet:
params["all"] = all params["all"] = all
if participating is not github.GithubObject.NotSet: if participating is not github.GithubObject.NotSet:
params["participating"] = participating params["participating"] = participating
# TODO: implement parameter "since" if since is not github.GithubObject.NotSet:
params["since"] = since.strftime("%Y-%m-%dT%H:%M:%SZ")
if before is not github.GithubObject.NotSet:
params["before"] = before.strftime("%Y-%m-%dT%H:%M:%SZ")
return github.PaginatedList.PaginatedList( return github.PaginatedList.PaginatedList(
github.Notification.Notification, github.Notification.Notification,
...@@ -1139,6 +1155,50 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ...@@ -1139,6 +1155,50 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject):
input={} input={}
) )
def create_migration(self, repos, lock_repositories=github.GithubObject.NotSet, exclude_attachments=github.GithubObject.NotSet):
"""
:calls: `POST /user/migrations`_
:param repos: list or tuple of str
:param lock_repositories: bool
:param exclude_attachments: bool
:rtype: :class:`github.Migration.Migration`
"""
assert isinstance(repos, (list, tuple)), repos
assert all(isinstance(repo, (str, unicode)) for repo in repos), repos
assert lock_repositories is github.GithubObject.NotSet or isinstance(lock_repositories, bool), lock_repositories
assert exclude_attachments is github.GithubObject.NotSet or isinstance(exclude_attachments, bool), exclude_attachments
post_parameters = {
"repositories": repos
}
if lock_repositories is not github.GithubObject.NotSet:
post_parameters["lock_repositories"] = lock_repositories
if exclude_attachments is not github.GithubObject.NotSet:
post_parameters["exclude_attachments"] = exclude_attachments
headers, data = self._requester.requestJsonAndCheck(
"POST",
"/user/migrations",
input=post_parameters,
headers={
"Accept": Consts.mediaTypeMigrationPreview
}
)
return github.Migration.Migration(self._requester, headers, data, completed=True)
def get_migrations(self):
"""
:calls: `GET /user/migrations`_
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Migration.Migration`
"""
return github.PaginatedList.PaginatedList(
github.Migration.Migration,
self._requester,
"/user/migrations",
None,
headers={
"Accept": Consts.mediaTypeMigrationPreview
}
)
def _initAttributes(self): def _initAttributes(self):
self._avatar_url = github.GithubObject.NotSet self._avatar_url = github.GithubObject.NotSet
self._bio = github.GithubObject.NotSet self._bio = github.GithubObject.NotSet
...@@ -1161,6 +1221,7 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ...@@ -1161,6 +1221,7 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject):
self._location = github.GithubObject.NotSet self._location = github.GithubObject.NotSet
self._login = github.GithubObject.NotSet self._login = github.GithubObject.NotSet
self._name = github.GithubObject.NotSet self._name = github.GithubObject.NotSet
self._node_id = github.GithubObject.NotSet
self._organizations_url = github.GithubObject.NotSet self._organizations_url = github.GithubObject.NotSet
self._owned_private_repos = github.GithubObject.NotSet self._owned_private_repos = github.GithubObject.NotSet
self._plan = github.GithubObject.NotSet self._plan = github.GithubObject.NotSet
...@@ -1220,6 +1281,8 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ...@@ -1220,6 +1281,8 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject):
self._login = self._makeStringAttribute(attributes["login"]) self._login = self._makeStringAttribute(attributes["login"])
if "name" in attributes: # pragma no branch if "name" in attributes: # pragma no branch
self._name = self._makeStringAttribute(attributes["name"]) self._name = self._makeStringAttribute(attributes["name"])
if "node_id" in attributes: # pragma no branch
self._node_id = self._makeStringAttribute(attributes["node_id"])
if "organizations_url" in attributes: # pragma no branch if "organizations_url" in attributes: # pragma no branch
self._organizations_url = self._makeStringAttribute(attributes["organizations_url"]) self._organizations_url = self._makeStringAttribute(attributes["organizations_url"])
if "owned_private_repos" in attributes: # pragma no branch if "owned_private_repos" in attributes: # pragma no branch
......
...@@ -2,12 +2,11 @@ ...@@ -2,12 +2,11 @@
############################ Copyrights and license ############################ ############################ Copyrights and license ############################
# # # #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> # # Copyright 2018 Justin Kufro <jkufro@andrew.cmu.edu> #
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> # # Copyright 2018 Ivan Minno <iminno@andrew.cmu.edu> #
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> # # Copyright 2018 Zilei Gu <zileig@andrew.cmu.edu> #
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> # # Copyright 2018 Yves Zumbach <yzumbach@andrew.cmu.edu> #
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> # # Copyright 2018 Leying Chen <leyingc@andrew.cmu.edu> #
# Copyright 2018 sfdye <tsfdye@gmail.com> #
# # # #
# This file is part of PyGithub. # # This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ # # http://pygithub.readthedocs.io/ #
...@@ -30,34 +29,49 @@ ...@@ -30,34 +29,49 @@
import github.GithubObject import github.GithubObject
class Status(github.GithubObject.NonCompletableGithubObject): class Clones(github.GithubObject.NonCompletableGithubObject):
""" """
This class represents Statuses. The reference can be found here https://status.github.com/api This class represents a popular Path for a GitHub repository.
The reference can be found here https://developer.github.com/v3/repos/traffic/
""" """
def __repr__(self): def __repr__(self):
return self.get__repr__({"status": self._status.value}) return self.get__repr__({
"timestamp": self._timestamp.value,
"count": self._count.value,
"uniques": self._uniques.value
})
@property @property
def status(self): def timestamp(self):
""" """
:type: string :type: datetime.datetime
""" """
return self._status.value return self._timestamp.value
@property @property
def last_updated(self): def count(self):
""" """
:type: datetime.datetime :type: integer
"""
return self._count.value
@property
def uniques(self):
"""
:type: integer
""" """
return self._last_updated.value return self._uniques.value
def _initAttributes(self): def _initAttributes(self):
self._status = github.GithubObject.NotSet self._timestamp = github.GithubObject.NotSet
self._last_updated = github.GithubObject.NotSet self._count = github.GithubObject.NotSet
self._uniques = github.GithubObject.NotSet
def _useAttributes(self, attributes): def _useAttributes(self, attributes):
if "status" in attributes: # pragma no branch if "timestamp" in attributes: # pragma no branch
self._status = self._makeStringAttribute(attributes["status"]) self._timestamp = self._makeDatetimeAttribute(attributes["timestamp"])
if "last_updated" in attributes: # pragma no branch if "count" in attributes: # pragma no branch
self._last_updated = self._makeDatetimeAttribute(attributes["last_updated"]) self._count = self._makeIntAttribute(attributes["count"])
if "uniques" in attributes: # pragma no branch
self._uniques = self._makeIntAttribute(attributes["uniques"])
...@@ -48,6 +48,7 @@ RES_LAST_MODIFIED = "last-modified" ...@@ -48,6 +48,7 @@ RES_LAST_MODIFIED = "last-modified"
headerRateLimit = "x-ratelimit-limit" headerRateLimit = "x-ratelimit-limit"
headerRateRemaining = "x-ratelimit-remaining" headerRateRemaining = "x-ratelimit-remaining"
headerRateReset = "x-ratelimit-reset" headerRateReset = "x-ratelimit-reset"
headerOAuthScopes = "x-oauth-scopes"
headerOTP = "X-GitHub-OTP" headerOTP = "X-GitHub-OTP"
defaultMediaType = "application/octet-stream" defaultMediaType = "application/octet-stream"
...@@ -90,6 +91,9 @@ mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview ...@@ -90,6 +91,9 @@ mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview
# https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/ # https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/
mediaTypeRequireMultipleApprovingReviews = "application/vnd.github.luke-cage-preview+json" mediaTypeRequireMultipleApprovingReviews = "application/vnd.github.luke-cage-preview+json"
# https://developer.github.com/changes/2018-05-24-user-migration-api/
mediaTypeMigrationPreview = "application/vnd.github.wyandotte-preview+json"
# https://developer.github.com/v3/search/#highlighting-code-search-results-1 # https://developer.github.com/v3/search/#highlighting-code-search-results-1
highLightSearchPreview = "application/vnd.github.v3.text-match+json" highLightSearchPreview = "application/vnd.github.v3.text-match+json"
......
...@@ -253,7 +253,7 @@ class Gist(github.GithubObject.CompletableGithubObject): ...@@ -253,7 +253,7 @@ class Gist(github.GithubObject.CompletableGithubObject):
if description is not github.GithubObject.NotSet: if description is not github.GithubObject.NotSet:
post_parameters["description"] = description post_parameters["description"] = description
if files is not github.GithubObject.NotSet: if files is not github.GithubObject.NotSet:
post_parameters["files"] = dict((key, None if value is None else value._identity) for key, value in files.iteritems()) post_parameters["files"] = {key: None if value is None else value._identity for key, value in files.iteritems()}
headers, data = self._requester.requestJsonAndCheck( headers, data = self._requester.requestJsonAndCheck(
"PATCH", "PATCH",
self.url, self.url,
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
from os.path import basename from os.path import basename
import github.GithubObject import github.GithubObject
import github.GitAuthor import github.NamedUser
import github.GitReleaseAsset import github.GitReleaseAsset
...@@ -108,7 +108,7 @@ class GitRelease(github.GithubObject.CompletableGithubObject): ...@@ -108,7 +108,7 @@ class GitRelease(github.GithubObject.CompletableGithubObject):
@property @property
def author(self): def author(self):
""" """
:type: :class:`github.GitAuthor.GitAuthor` :type: :class:`github.NamedUser.NamedUser`
""" """
self._completeIfNotSet(self._author) self._completeIfNotSet(self._author)
return self._author.value return self._author.value
...@@ -285,7 +285,7 @@ class GitRelease(github.GithubObject.CompletableGithubObject): ...@@ -285,7 +285,7 @@ class GitRelease(github.GithubObject.CompletableGithubObject):
if "prerelease" in attributes: if "prerelease" in attributes:
self._prerelease = self._makeBoolAttribute(attributes["prerelease"]) self._prerelease = self._makeBoolAttribute(attributes["prerelease"])
if "author" in attributes: if "author" in attributes:
self._author = self._makeClassAttribute(github.GitAuthor.GitAuthor, attributes["author"]) self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"])
if "url" in attributes: if "url" in attributes:
self._url = self._makeStringAttribute(attributes["url"]) self._url = self._makeStringAttribute(attributes["url"])
if "upload_url" in attributes: if "upload_url" in attributes:
......
...@@ -170,7 +170,7 @@ class GithubObject(object): ...@@ -170,7 +170,7 @@ class GithubObject(object):
# The Downloads API has been removed. I'm keeping this branch because I have no mean # The Downloads API has been removed. I'm keeping this branch because I have no mean
# to check if it's really useless now. # to check if it's really useless now.
return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.000Z") # pragma no cover (This branch was used only when creating a download) return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.000Z") # pragma no cover (This branch was used only when creating a download)
elif len(s) == 25: elif len(s) >= 25:
return datetime.datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S") + (1 if s[19] == '-' else -1) * datetime.timedelta(hours=int(s[20:22]), minutes=int(s[23:25])) return datetime.datetime.strptime(s[:19], "%Y-%m-%dT%H:%M:%S") + (1 if s[19] == '-' else -1) * datetime.timedelta(hours=int(s[20:22]), minutes=int(s[23:25]))
else: else:
return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ") return datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ")
......
...@@ -53,10 +53,11 @@ import urllib ...@@ -53,10 +53,11 @@ import urllib
import pickle import pickle
import time import time
import sys import sys
from httplib import HTTPSConnection import requests
import jwt import jwt
import urllib3
from Requester import Requester, json from Requester import Requester
import AuthenticatedUser import AuthenticatedUser
import NamedUser import NamedUser
import Organization import Organization
...@@ -66,11 +67,10 @@ import Repository ...@@ -66,11 +67,10 @@ import Repository
import Installation import Installation
import Legacy import Legacy
import License import License
import Topic
import github.GithubObject import github.GithubObject
import HookDescription import HookDescription
import GitignoreTemplate import GitignoreTemplate
import Status
import StatusMessage
import RateLimit import RateLimit
import InstallationAuthorization import InstallationAuthorization
import GithubException import GithubException
...@@ -94,7 +94,7 @@ class Github(object): ...@@ -94,7 +94,7 @@ class Github(object):
This is the main class you instantiate to access the Github API v3. Optional parameters allow different authentication methods. This is the main class you instantiate to access the Github API v3. Optional parameters allow different authentication methods.
""" """
def __init__(self, login_or_token=None, password=None, jwt=None, base_url=DEFAULT_BASE_URL, timeout=DEFAULT_TIMEOUT, client_id=None, client_secret=None, user_agent='PyGithub/Python', per_page=DEFAULT_PER_PAGE, api_preview=False, verify=True): def __init__(self, login_or_token=None, password=None, jwt=None, base_url=DEFAULT_BASE_URL, timeout=DEFAULT_TIMEOUT, client_id=None, client_secret=None, user_agent='PyGithub/Python', per_page=DEFAULT_PER_PAGE, api_preview=False, verify=True, retry=None):
""" """
:param login_or_token: string :param login_or_token: string
:param password: string :param password: string
...@@ -105,6 +105,7 @@ class Github(object): ...@@ -105,6 +105,7 @@ class Github(object):
:param user_agent: string :param user_agent: string
:param per_page: int :param per_page: int
:param verify: boolean or string :param verify: boolean or string
:param retry: int or urllib3.util.retry.Retry object
""" """
assert login_or_token is None or isinstance(login_or_token, (str, unicode)), login_or_token assert login_or_token is None or isinstance(login_or_token, (str, unicode)), login_or_token
...@@ -116,7 +117,8 @@ class Github(object): ...@@ -116,7 +117,8 @@ class Github(object):
assert client_secret is None or isinstance(client_secret, (str, unicode)), client_secret assert client_secret is None or isinstance(client_secret, (str, unicode)), client_secret
assert user_agent is None or isinstance(user_agent, (str, unicode)), user_agent assert user_agent is None or isinstance(user_agent, (str, unicode)), user_agent
assert isinstance(api_preview, (bool)) assert isinstance(api_preview, (bool))
self.__requester = Requester(login_or_token, password, jwt, base_url, timeout, client_id, client_secret, user_agent, per_page, api_preview, verify) assert retry is None or isinstance(retry, (int)) or isinstance(retry, (urllib3.util.Retry))
self.__requester = Requester(login_or_token, password, jwt, base_url, timeout, client_id, client_secret, user_agent, per_page, api_preview, verify, retry)
def __get_FIX_REPO_GET_GIT_REF(self): def __get_FIX_REPO_GET_GIT_REF(self):
""" """
...@@ -542,7 +544,7 @@ class Github(object): ...@@ -542,7 +544,7 @@ class Github(object):
:calls: `GET /search/topics <http://developer.github.com/v3/search>`_ :calls: `GET /search/topics <http://developer.github.com/v3/search>`_
:param query: string :param query: string
:param qualifiers: keyword dict query qualifiers :param qualifiers: keyword dict query qualifiers
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository` :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Topic.Topic`
""" """
assert isinstance(query, (str, unicode)), query assert isinstance(query, (str, unicode)), query
url_parameters = dict() url_parameters = dict()
...@@ -558,7 +560,7 @@ class Github(object): ...@@ -558,7 +560,7 @@ class Github(object):
assert url_parameters["q"], "need at least one qualifier" assert url_parameters["q"], "need at least one qualifier"
return github.PaginatedList.PaginatedList( return github.PaginatedList.PaginatedList(
github.Repository.Repository, github.Topic.Topic,
self.__requester, self.__requester,
"/search/topics", "/search/topics",
url_parameters, url_parameters,
...@@ -680,45 +682,6 @@ class Github(object): ...@@ -680,45 +682,6 @@ class Github(object):
""" """
return self.create_from_raw_data(*pickle.load(f)) return self.create_from_raw_data(*pickle.load(f))
def get_api_status(self):
"""
This doesn't work with a Github Enterprise installation, because it always targets https://status.github.com.
:calls: `GET /api/status.json <https://status.github.com/api>`_
:rtype: :class:`github.Status.Status`
"""
headers, attributes = self.__requester.requestJsonAndCheck(
"GET",
DEFAULT_STATUS_URL + "/api/status.json"
)
return Status.Status(self.__requester, headers, attributes, completed=True)
def get_last_api_status_message(self):
"""
This doesn't work with a Github Enterprise installation, because it always targets https://status.github.com.
:calls: `GET /api/last-message.json <https://status.github.com/api>`_
:rtype: :class:`github.StatusMessage.StatusMessage`
"""
headers, attributes = self.__requester.requestJsonAndCheck(
"GET",
DEFAULT_STATUS_URL + "/api/last-message.json"
)
return StatusMessage.StatusMessage(self.__requester, headers, attributes, completed=True)
def get_api_status_messages(self):
"""
This doesn't work with a Github Enterprise installation, because it always targets https://status.github.com.
:calls: `GET /api/messages.json <https://status.github.com/api>`_
:rtype: list of :class:`github.StatusMessage.StatusMessage`
"""
headers, data = self.__requester.requestJsonAndCheck(
"GET",
DEFAULT_STATUS_URL + "/api/messages.json"
)
return [StatusMessage.StatusMessage(self.__requester, headers, attributes, completed=True) for attributes in data]
def get_installation(self, id): def get_installation(self, id):
""" """
...@@ -741,15 +704,18 @@ class GithubIntegration(object): ...@@ -741,15 +704,18 @@ class GithubIntegration(object):
self.integration_id = integration_id self.integration_id = integration_id
self.private_key = private_key self.private_key = private_key
def create_jwt(self): def create_jwt(self, expiration=60):
""" """
Creates a signed JWT, valid for 60 seconds. Creates a signed JWT, valid for 60 seconds by default.
The expiration can be extended beyond this, to a maximum of 600 seconds.
:param expiration: int
:return: :return:
""" """
now = int(time.time()) now = int(time.time())
payload = { payload = {
"iat": now, "iat": now,
"exp": now + 60, "exp": now + expiration,
"iss": self.integration_id "iss": self.integration_id
} }
encrypted = jwt.encode( encrypted = jwt.encode(
...@@ -766,51 +732,42 @@ class GithubIntegration(object): ...@@ -766,51 +732,42 @@ class GithubIntegration(object):
def get_access_token(self, installation_id, user_id=None): def get_access_token(self, installation_id, user_id=None):
""" """
Get an access token for the given installation id. Get an access token for the given installation id.
POSTs https://api.github.com/installations/<installation_id>/access_tokens POSTs https://api.github.com/app/installations/<installation_id>/access_tokens
:param user_id: int :param user_id: int
:param installation_id: int :param installation_id: int
:return: :class:`github.InstallationAuthorization.InstallationAuthorization` :return: :class:`github.InstallationAuthorization.InstallationAuthorization`
""" """
body = None body = {}
if user_id: if user_id:
body = json.dumps({"user_id": user_id}) body = {"user_id": user_id}
conn = HTTPSConnection("api.github.com") response = requests.post(
conn.request( "https://api.github.com/app/installations/{}/access_tokens".format(installation_id),
method="POST",
url="/installations/{}/access_tokens".format(installation_id),
headers={ headers={
"Authorization": "Bearer {}".format(self.create_jwt()), "Authorization": "Bearer {}".format(self.create_jwt()),
"Accept": Consts.mediaTypeIntegrationPreview, "Accept": Consts.mediaTypeIntegrationPreview,
"User-Agent": "PyGithub/Python" "User-Agent": "PyGithub/Python"
}, },
body=body json=body
) )
response = conn.getresponse()
response_text = response.read()
if atLeastPython3:
response_text = response_text.decode('utf-8')
conn.close() if response.status_code == 201:
if response.status == 201:
data = json.loads(response_text)
return InstallationAuthorization.InstallationAuthorization( return InstallationAuthorization.InstallationAuthorization(
requester=None, # not required, this is a NonCompletableGithubObject requester=None, # not required, this is a NonCompletableGithubObject
headers={}, # not required, this is a NonCompletableGithubObject headers={}, # not required, this is a NonCompletableGithubObject
attributes=data, attributes=response.json(),
completed=True completed=True
) )
elif response.status == 403: elif response.status_code == 403:
raise GithubException.BadCredentialsException( raise GithubException.BadCredentialsException(
status=response.status, status=response.status_code,
data=response_text data=response.text
) )
elif response.status == 404: elif response.status_code == 404:
raise GithubException.UnknownObjectException( raise GithubException.UnknownObjectException(
status=response.status, status=response.status_code,
data=response_text data=response.text
) )
raise GithubException.GithubException( raise GithubException.GithubException(
status=response.status, status=response.status_code,
data=response_text data=response.text
) )
# -*- coding: utf-8 -*-
############################ Copyrights and license ############################
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2014 Andy Casey <acasey@mso.anu.edu.au> #
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
# Copyright 2016 John Eskew <jeskew@edx.org> #
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
# Copyright 2018 sfdye <tsfdye@gmail.com> #
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
# #
# PyGithub is free software: you can redistribute it and/or modify it under #
# the terms of the GNU Lesser General Public License as published by the Free #
# Software Foundation, either version 3 of the License, or (at your option) #
# any later version. #
# #
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
# details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
import github.GithubObject
import github.PaginatedList
import github.NamedUser
import Consts
class Migration(github.GithubObject.CompletableGithubObject):
"""
This class represents Migrations. The reference can be found here http://developer.github.com/v3/migrations/
"""
def __repr__(self):
return self.get__repr__({"state": self._state.value, "url": self._url.value})
@property
def id(self):
"""
:type: int
"""
return self._id.value
@property
def owner(self):
"""
:type: :class:`github.NamedUser.NamedUser`
"""
self._completeIfNotSet(self._owner)
return self._owner.value
@property
def guid(self):
"""
:type: str
"""
self._completeIfNotSet(self._guid)
return self._guid.value
@property
def state(self):
"""
:type: str
"""
self._completeIfNotSet(self._guid)
return self._state.value
@property
def lock_repositories(self):
"""
:type: bool
"""
self._completeIfNotSet(self._repositories)
return self._lock_repositories.value
@property
def exclude_attachments(self):
"""
:type: bool
"""
self._completeIfNotSet(self._exclude_attachments)
return self._exclude_attachments.value
@property
def repositories(self):
"""
:type: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository`
"""
self._completeIfNotSet(self._repositories)