def create_commit_comment(self, owner, repo, commit_sha, body, path, position, line=None): url = "/repos/{owner}/{repo}/commits/{commit_sha}/comments".format( owner=owner, repo=repo, commit_sha=commit_sha) params = { "body": body, "path": path, "position": position, "line": line } self.response = Response(self.post(url, params=params), "Comment") return self.response.transform()
def app_installations(self): if self.app_token is None: raise ValueError( f"You need to supply app_token to {self.__class__.__name__}()." f"In order to obtain app_token see the documentation on how to generate JWT" ) url = f"/app/installations" self.response = Response( self.get( url, **{ "Authorization": f"Bearer {self.app_token}", "Accept": _app_mime_type, }, ), "App", ) return self.response.transform()
def starred( self, sort=Sort.CREATED, direction=Direction.DESC, starred_at=False, **kwargs ): if sort not in Sort: raise ValueError("'sort' must be of type Sort") if direction not in Direction: raise ValueError("'direction' must be of type Direction") url = "/user/starred" params = [("sort", sort.value), ("direction", direction.value)] if starred_at: kwargs.update( { "Accept": f"application/vnd.github.v{config.api_version}.star+{config.api_mime_type}" } ) self.response = Response(self.get(url, params, **kwargs), "StarRepos") return self.response.transform()
def starred( self, sort=StarringSort.CREATED, direction=StarringDirection.DESC, starred_at=False, **kwargs, ): if sort not in StarringSort: raise ValueError("'sort' must be of type Sort") if direction not in StarringDirection: raise ValueError("'direction' must be of type Direction") url = "/user/starred" params = [("sort", sort.value), ("direction", direction.value)] if starred_at: kwargs.update({"Accept": _mime_option}) self.response = Response(self.get(url, params, **kwargs), "StarRepos") return self.response.transform()
def create_repo_hook(self, owner, repo, config, events, name="web", active=True): url = f"/repos/{owner}/{repo}/hooks" assert isinstance(config, dict) assert isinstance(events, (list, tuple)) params = { "name": name, "active": active, "events": events, "config": config } self.response = Response(self.post(url, params=params), "Hook") return self.response.transform()
def blocked_from_org(self, org, username): """ Check whether a user is blocked from an organization :param org: :param username: :return: """ url = f"/orgs/{org}/blocks/{username}" self.response = Response(self.get(url, **{"Accept": _mime_type}), "User") if self.response.status_code == 204: return True elif self.response.status_code == 404: return False else: raise ValueError( f"blocked_from_org(....) returned status code : {self.response.status_code}, it should either be 204 or 404" )
def user_installation(self, username): if self.app_token is None: raise ValueError( f"You need to supply app_token to {self.__class__.__name__}()." f"In order to obtain app_token, invoke the method `create_app_access_token(....)` " ) url = f"/users/{username}/installation" self.response = Response( self.get( url, **{ "Authorization": f"Bearer {self.app_token}", "Accept": _app_mime_type, }, ), "UserInstallation", ) return self.response.transform()
def update_required_status_checks_of_protected_branch( self, owner, repo, branch, strict, contexts): """ Protected branches are not available for Free plans. Use Pro plan or Github Enterprise. :param owner: :param repo: :param branch: :param strict: :param contexts: :return: """ url = "/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks".format( owner=owner, repo=repo, branch=branch) params = {"strict": strict, "contexts": contexts} self.response = Response(self.patch(url, params=params), "RequiredChecks") return self.response.transform()
def edit_issue( self, owner, repo, issue_number, title, body, state, milestone, labels, assignees, ): """ :param owner: repo owner :param repo : repo name :param issue_number: Issue number :param title: The title of the issue. :param body: The contents of the issue. :param state: State of the issue. Either open or closed. :param milestone: The number of the milestone to associate this issue with or null to remove current. NOTE: Only users with push access can set the milestone for issues. :param labels: Pass one or more Labels to replace the set of Labels on this Issue. Send an empty array ([]) to clear all Labels from the Issue. :param assignees: Pass one or more user logins to replace the set of assignees on this Issue. Send an empty array ([]) to clear all assignees from the Issue. :return: """ url = f"/repos/{owner}/{repo}/issues/{issue_number}" self.response = Response( self.patch( url, json=[ ("title", title), ("body", body), ("assignees", list(assignees)), ("milestone", milestone), ("state", state), ("labels", list(labels)), ], **{"Accept": "application/vnd.github.symmetra-preview+json"}, ), "Issue", ) return self.response.transform()
def delete_file( self, owner, repo, path, message, sha, committer=None, author=None, branch="master", ): url = f"/repos/{owner}/{repo}/contents/{path}" params = {"message": message, "sha": sha, "branch": branch} if committer: params["committer"] = committer if author: params["author"] = author self.response = Response(self.delete(url, params=params), "File") return self.response.transform()
def blocked_from_org(self, org, username): """ Check whether a user is blocked from an organization :param org: :param username: :return: """ url = "/orgs/{org}/blocks/{username}".format(org=org, username=username) self.response = Response(self.get(url, **_accept_header), "User") if self.response.status_code == 204: return True elif self.response.status_code == 404: return False else: raise ValueError( "blocked_from_org(....) returned status code : {status_code} it should either be 204 or 404".format( status_code=self.response.status_code ) )
def delete_app_installtion(self, installation_id): """Uninstalls a GitHub App on a user, organization, or business account.""" if self.app_token is None: raise ValueError( f"You need to supply app_token to {self.__class__.__name__}(.....)." f"In order to obtain app_token, invoke the method `create_app_access_token(....)` " ) url = f"/app/installations/{installation_id}" self.response = Response( self.delete( url, **{ "Authorization": f"Bearer {self.app_token}", "Accept": _app_mime_type, }, ), "App", ) return self.response.transform()
def edit_comment_on_pull_request(self, owner, repo, pull_number, comment_id, body): url = "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}".format( owner=owner, repo=repo, pull_number=pull_number, comment_id=comment_id) self.response = Response( self.patch( url, params={"body": body}, **{ "Accept": "application/vnd.github.comfort-fade-preview+json" }, ), "PRComment", ) return self.response.transform()
def notifications(self, all=False, participating=False, since=None, before=None, **kwargs): """ List all notifications for the current user, sorted by most recently updated. """ url = "/notifications" params = { "all": all, "participating": participating, "since": since, "before": before, } self.response = Response(self.get(url, params=params, **kwargs), "Notifications") return self.response.transform()
def update_project(self, project_id, name, body, state, organization_permission, private): assert state in ("open", "closed") assert isinstance(private, bool) assert organization_permission in ("read", "write", "admin", "none") url = f"/projects/{project_id}" params = [ ("name", name), ("body", body), ("state", state), ("organization_permission", organization_permission), ("private", private), ] self.response = Response( self.patch(url, params=params, **{"Accept": _project_accept_header}), "Project", ) return self.response.transform()
def user_is_following(self, username, target_user): url = f"/users/{username}/following/{target_user}" self.response = Response( self.get( url, **{ "Accept": "application/vnd.github.giant-sentry-fist-preview+json" }, ), "", ) if self.response.status_code == 204: return True elif self.response.status_code == 404: return False else: raise ErrorAPICode( f"API has returned an Unexpected response code - {self.response.status_code}." f"It should either be 204 or 404.")
def commits(self, owner, repo, sha=None, path=None, author=None, since=None, until=None): url = f"/repos/{owner}/{repo}/commits" params = {} if sha: params["sha"] = sha if path: params["path"] = path if author: params["author"] = author if since: params["until"] = until self.response = Response(self.get(url), "Commits") return self.response.transform()
def deployments(self, owner, repo, sha=None, ref=None, task=None, environment=None): url = f"/repos/{owner}/{repo}/deployments" params = {} if sha: params["sha"] = sha if ref: params["ref"] = ref if task: params["task"] = task if environment: params["environment"] = environment self.response = Response( self.get(url, params=params, **{"Accept": _mime}), "Deployments") return self.response.transform()
def github_app_installations_for_user(self, **kwargs): """ Lists installations of your GitHub App that the authenticated user has explicit permission (:read, :write, or :admin) to access. :return: """ self._check_app_token() _mime = "application/vnd.github.machine-man-preview+json" url = "/user/installations" self.response = Response( self.get( url, **{ "Authorization": "Bearer {app_token}".format(app_token=self.app_token), "Accept": _mime, }, **kwargs), "Apps", ) return self.response.transform()
def lock_issue(self, owner, repo, issue_number, lock_reason=None): if lock_reason and not isinstance(lock_reason, LockReason): raise ValueError( "You should use LockReason instance for lock_reason variable.") url = f"/repos/{owner}/{repo}/issues/{issue_number}/lock" custom_headers = {} if lock_reason is None: custom_headers["Content-Length"] = "0" custom_headers.update( {"Accept": "application/vnd.github.sailor-v-preview+json"}) self.response = Response( self.put( url, json=[("locked", True), ("active_lock_reason", lock_reason.value) ]**custom_headers, ), "", ) return self.response.status_code == 204
def repo_issues( self, owner, repo, milestone="*", state=IssueState.OPEN, assignee="*", creator=None, mentioned=None, labels=None, sort=IssueSort.CREATED, direction=IssueDirection.DESCENDING, since=None, **kwargs, ): url = "/repos/{owner}/{repo}/issues".format(owner=owner, repo=repo) params = [ ("milestone", milestone), ("state", state.value), ("assignee", assignee), ("sort", sort.value), ("direction", direction.value), ] if creator: params.append(("creator", creator)) if mentioned: params.append(("mentioned", mentioned)) if labels: params.append(("labels", labels)) if since: params.append(("since", since)) self.response = Response( self.get( url, params=params, **{"Accept": "application/vnd.github.symmetra-preview+json"}, **kwargs, ), "Issues", ) return self.response.transform()
def follow(self, username): url = f"/user/following/{username}" self.response = Response( self.put( url, **{ "Accept": "application/vnd.github.giant-sentry-fist-preview+json", "Content-Length": "0", }, ), "", ) if self.response.status_code == 204: return True elif self.response.status_code == 404: return False else: raise ErrorAPICode( f"API has returned an Unexpected response code - {self.response.status_code}." f"It should either be 204 or 404.")
def is_following(self, username): url = "/users/following/{username}".format(username=username) self.response = Response( self.get( url, **{ "Accept": "application/vnd.github.giant-sentry-fist-preview+json" }, ), "", ) if self.response.status_code == 204: return True elif self.response.status_code == 404: return False else: raise ErrorAPICode( "API has returned an Unexpected response code - {status_code}." "It should either be 204 or 404.".format( status_code=self.response.status_code))
def unblock(self, username): """ Unblock a user """ url = f"/user/blocks/{username}" self.response = Response( self.delete( url, **{"Accept": "application/vnd.github.giant-sentry-fist-preview+json"}, ), "", ) if self.response.status_code == 204: return True elif self.response.status_code == 404: return False else: raise ErrorAPICode( f"API has returned an Unexpected response code - {self.response.status_code}." f"It should either be 204 or 404." )
def comments_on_pull_request( self, owner, repo, pull_number, sort=PRCommentsSort.CREATED, direction=None, since=None, ): params = {"sort": sort.value} if direction: params["direction"] = direction if since: params["since"] = since url = "/repos/{owner}/{repo}/pulls/{pull_number}/comments".format( owner=owner, repo=repo, pull_number=pull_number) self.response = Response( self.get(url, params=params, **{"Accept": _mime}), "PRComments") return self.response.transform()
def create_project_card( self, column_id, note=None, content_id=None, content_type=None ): if note: if content_id is not None or content_type is not None: raise ValueError( "When you specify note, you should not specify content_id and content_type." ) params = [("note", note)] else: if content_id is None or content_type is None: raise ValueError( "When you do not specify note, you should specify both content_id and content_type." ) params = {"content_id": int(content_id), "content_type": content_type} url = "/projects/columns/{column_id}/cards".format(column_id=column_id) self.response = Response( self.post(url, params=params, **_accept_header), "ProjectCard" ) return self.response.transform()
def user_issues( self, filter=Filter.Assigned, state=State.Open, labels="", sort=Sort.Created, direction=Direction.Descending, since="", ): url = "/user/issues" params = [ ("filter", filter.value), ("state", state.value), ("labels", labels), ("sort", sort.value), ("direction", direction.value), ("since", since), ] self.response = Response( self.get(url, params=params, **{"Accept": IssueCustomMediaType}), "Issues") return self.response.transform()
def create_release( self, owner, repo, tag_name, target_commitish, name, body, draft=False, prerelease=False, ): params = { "tag_name": tag_name, "target_commitish": target_commitish, "name": name, "body": body, "draft": draft, "prerelease": prerelease, } url = f"/repos/{owner}/{repo}/releases" self.response = Response(self.post(url, params=params), "Release") return self.response.transform()
def update_branch_protection( self, owner, repo, branch, required_status_checks, enforce_admins, required_pull_request_reviews, restrictions, ): mime = "application/vnd.github.luke-cage-preview+json" url = f"/repos/{owner}/{repo}/branches/{branch}/protection" params = { "required_status_checks": required_status_checks, "enforce_admins": enforce_admins, "required_pull_request_reviews": required_pull_request_reviews, "restrictions": restrictions, } self.response = Response( self.put(url, params=params, **{"Accept": mime}), "UpdateBranchProtection") return self.response.transform()
def start_source_import( self, owner, repo, vcs_url, vcs_username, vcs_password, tfvc_project=None, vcs=SourceControlType.NONE, ): url = f"/repos/{owner}/{repo}/import" params = { "vcs": vcs.value, "vcs_url": vcs_url, "vcs_username": vcs_username, "vcs_password": vcs_password, } if vcs == SourceControlType.TFVC: params.update({"tfvc_project": tfvc_project}) self.response = Response( self.put(url, params=params, **{"Accept": _mime}), "Import") return self.response.transform()