diff --git a/Github/exceptions.py b/Github/exceptions.py index a239d7e..c9e0ce7 100644 --- a/Github/exceptions.py +++ b/Github/exceptions.py @@ -54,6 +54,11 @@ class ObjectNotFound(APIError): msg = 'The requested object was not found, ensure spelling is correct before proceeding.' super().__init__(msg) +class IssueNotFound(APIError): + def __init__(self): + msg = 'The requested issue was not found, ensure spelling is correct before proceeding.' + super().__init__(msg) + class NoAuthProvided(APIError): """Raised when no proper authorization or invalid authorization is given to the client""" def __init__(self): diff --git a/Github/http.py b/Github/http.py index 2c65860..d99f28d 100644 --- a/Github/http.py +++ b/Github/http.py @@ -8,6 +8,7 @@ from types import SimpleNamespace import re from .exceptions import * +from .exceptions import IssueNotFound from .objects import * from .urls import * @@ -130,6 +131,13 @@ async def get_repo_from_name(session: aiohttp.ClientSession, owner: str, repo_na return await result.json() raise RepositoryNotFound +async def get_repo_issue(session: aiohttp.ClientSession, owner: str, repo_name: str, issue_number: int) -> dict[str, str]: + """Returns a single issue from the given owner and repo name.""" + result = await session.get(REPO_ISSUE_URL.format(owner, repo_name, issue_number)) + if result.status == 200: + return await result.json() + raise IssueNotFound + # org-related functions / utils async def get_org(session: aiohttp.ClientSession, org_name: str): diff --git a/Github/main.py b/Github/main.py index 0af4470..1f5b6ae 100644 --- a/Github/main.py +++ b/Github/main.py @@ -10,7 +10,7 @@ import asyncio from . import http from . import exceptions -from .objects import User, Repository, Organization +from .objects import * class GHClient: _auth = None @@ -83,6 +83,10 @@ class GHClient: """Fetch a Github repository from it's name.""" return Repository(await http.get_repo_from_name(self.session, owner, repo_name), self.session) + async def get_repo_issue(self, owner: str, repo_name: str, issue_number: int) -> Repository: + """Fetch a Github repository from it's name.""" + return repo.Issue(await http.get_repo_issue(self.session, owner, repo_name, issue_number), self.session) + async def get_org(self, org_name: str) -> Organization: """Fetch a Github organization from it's name""" return Organization(await http.get_org(self.session, org_name), self.session) diff --git a/Github/objects/repo.py b/Github/objects/repo.py index f7ed397..6dc21f4 100644 --- a/Github/objects/repo.py +++ b/Github/objects/repo.py @@ -67,3 +67,38 @@ class Repository(APIOBJECT): """Fetch a repository from its name.""" response = await http.get_repo_from_name(session, owner, repo_name) return Repository(response, session) + + +class Issue(APIOBJECT): + __slots__ = ( + 'id', + 'title', + 'user', + 'labels', + 'state', + 'created_at', + 'closed_by', + ) + + def __init__(self, response: dict, session: aiohttp.ClientSession) -> None: + tmp = self.__slots__ + APIOBJECT.__slots__ + keys = {key: value for key,value in response.items() if key in tmp} + for key, value in keys.items(): + if key == 'user': + setattr(self, key, PartialUser(value, session)) + continue + + if key == 'labels': + setattr(self, key, [label['name'] for label in value]) + continue + + if key == 'closed_by': + setattr(self, key, User(value, session)) + continue + + else: + setattr(self, key, value) + continue + + def __repr__(self) -> str: + return f'' \ No newline at end of file diff --git a/Github/urls.py b/Github/urls.py index a52d03e..c3fa2d1 100644 --- a/Github/urls.py +++ b/Github/urls.py @@ -26,6 +26,8 @@ REPOS_URL = BASE_URL + '/repos/{0}' # repos of a user REPO_URL = BASE_URL + '/repos/{0}/{1}' # a specific repo +REPO_ISSUE_URL = REPO_URL + '/issues/{2}' # a specific issue + #== org urls ==# ORG_URL = BASE_URL + '/orgs/{0}' \ No newline at end of file