Source code for Ligare.GitHub.api

from typing import Any, Literal, cast

from github import Auth
from github import Github as pygithub
from github.AuthenticatedUser import AuthenticatedUser
from github.GithubObject import NotSet, Opt
from github.NamedUser import NamedUser
from github.Organization import Organization
from github.Repository import Repository

GITHUB_API_BASE_URL = "https://api.github.com"


[docs] class GitHub: """ Extends PyGithub with better organization API handling. """ _client: pygithub
[docs] def __init__( self, auth_token: str, default_api_url: str = GITHUB_API_BASE_URL ) -> None: auth = Auth.Token(auth_token) self._client = pygithub(base_url=default_api_url, auth=auth) super().__init__()
[docs] def get_team(self, organization: Organization, team_name: str): """ Get a team for an organization. """ team = organization.get_team_by_slug(team_name) return team
[docs] def add_collaborator( self, repository: Repository, collaborator: str | NamedUser, permission: Opt[str] = NotSet, ): """ Add a user as a collaborator to a repository. """ invitation = repository.add_to_collaborators( collaborator, permission=permission ) return invitation
[docs] def get_repository( self, repository_name: str, organization_name: str | None = None ): """ Get a repository. If `organization_name` is supplied, this will get the repository `repository_name` from that organization's repositories. """ if organization_name is None: return self._get_repository_for_user(repository_name) return self._get_repository_for_organization(repository_name, organization_name)
def _get_repository_for_user(self, repository_name: str): user = self._client.get_user() return self._client.get_repo(f"{user.login}/{repository_name}") def _get_repository_for_organization( self, repository_name: str, organization_name: str ): ## repo = organization.get_repo(repository_name) ## can't use repo.organization because of this ## https://github.com/PyGithub/PyGithub/issues/1598 repository = self._client.get_repo(f"{organization_name}/{repository_name}") organization: Organization = self._client.get_organization(organization_name) # fixes the PyGithub API URLs for working with the organiztion owning the repository cast(Any, repository._organization)._value = organization # pyright: ignore[reportPrivateUsage] return repository
[docs] def create_repository( self, name: str, description: str, organization_name: str | None = None, template_name: str | None = None, private: bool = True, visibility: Literal["private", "internal", "public"] | None = None, ): """ Create a new repository. """ if organization_name is None: return self._create_repository_for_user( name, description=description, template_name=template_name, private=private, ) return self._create_repository_for_organization( name, description=description, organization_name=organization_name, template_name=template_name, private=private, visibility=visibility, )
def _create_repository_for_user( self, name: str, description: str, template_name: str | None = None, private: bool = True, ): user = cast(AuthenticatedUser, self._client.get_user()) repository: Repository if template_name is None: repository = user.create_repo(name) else: template_repo = user.get_repo(template_name) repository = user.create_repo_from_template( name, repo=template_repo, description=description, private=private ) return repository def _create_repository_for_organization( self, name: str, description: str, organization_name: str, template_name: str | None = None, private: bool = True, visibility: Literal["private", "internal", "public"] | None = None, ): organization = self._client.get_organization(organization_name) repository: Repository if template_name is None: repository = organization.create_repo( name, description=description, private=private ) else: template_repo = organization.get_repo(template_name) repository = organization.create_repo_from_template( name, repo=template_repo, description=description, private=private ) if visibility is not None: self._set_repository_visibility(repository, visibility) return repository def _set_repository_visibility( self, repository: Repository, visibility: Literal["private", "internal", "public"], ): # PyGitHub code does not allow "internal," # so we do the same thing repository.edit does # to avoid the incorrect assertions. ( _, data, ) = repository._requester.requestJsonAndCheck( # pyright: ignore[reportPrivateUsage] "PATCH", repository.url, input={"visibility": visibility} ) repository._useAttributes(data) # pyright: ignore[reportPrivateUsage]