ghnova 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. ghnova/__init__.py +8 -0
  2. ghnova/__main__.py +8 -0
  3. ghnova/cli/__init__.py +1 -0
  4. ghnova/cli/config/__init__.py +1 -0
  5. ghnova/cli/config/add.py +48 -0
  6. ghnova/cli/config/delete.py +50 -0
  7. ghnova/cli/config/list.py +40 -0
  8. ghnova/cli/config/main.py +27 -0
  9. ghnova/cli/config/update.py +59 -0
  10. ghnova/cli/issue/__init__.py +7 -0
  11. ghnova/cli/issue/create.py +155 -0
  12. ghnova/cli/issue/get.py +119 -0
  13. ghnova/cli/issue/list.py +267 -0
  14. ghnova/cli/issue/lock.py +110 -0
  15. ghnova/cli/issue/main.py +31 -0
  16. ghnova/cli/issue/unlock.py +101 -0
  17. ghnova/cli/issue/update.py +164 -0
  18. ghnova/cli/main.py +117 -0
  19. ghnova/cli/repository/__init__.py +1 -0
  20. ghnova/cli/repository/list.py +201 -0
  21. ghnova/cli/repository/main.py +21 -0
  22. ghnova/cli/user/__init__.py +1 -0
  23. ghnova/cli/user/ctx_info.py +105 -0
  24. ghnova/cli/user/get.py +98 -0
  25. ghnova/cli/user/list.py +78 -0
  26. ghnova/cli/user/main.py +27 -0
  27. ghnova/cli/user/update.py +164 -0
  28. ghnova/cli/utils/__init__.py +7 -0
  29. ghnova/cli/utils/auth.py +67 -0
  30. ghnova/client/__init__.py +8 -0
  31. ghnova/client/async_github.py +121 -0
  32. ghnova/client/base.py +78 -0
  33. ghnova/client/github.py +107 -0
  34. ghnova/config/__init__.py +8 -0
  35. ghnova/config/manager.py +209 -0
  36. ghnova/config/model.py +58 -0
  37. ghnova/issue/__init__.py +8 -0
  38. ghnova/issue/async_issue.py +554 -0
  39. ghnova/issue/base.py +469 -0
  40. ghnova/issue/issue.py +584 -0
  41. ghnova/repository/__init__.py +8 -0
  42. ghnova/repository/async_repository.py +134 -0
  43. ghnova/repository/base.py +124 -0
  44. ghnova/repository/repository.py +134 -0
  45. ghnova/resource/__init__.py +8 -0
  46. ghnova/resource/async_resource.py +88 -0
  47. ghnova/resource/resource.py +88 -0
  48. ghnova/user/__init__.py +8 -0
  49. ghnova/user/async_user.py +285 -0
  50. ghnova/user/base.py +214 -0
  51. ghnova/user/user.py +285 -0
  52. ghnova/utils/__init__.py +16 -0
  53. ghnova/utils/log.py +70 -0
  54. ghnova/utils/response.py +67 -0
  55. ghnova/version.py +11 -0
  56. ghnova-0.3.0.dist-info/METADATA +194 -0
  57. ghnova-0.3.0.dist-info/RECORD +60 -0
  58. ghnova-0.3.0.dist-info/WHEEL +4 -0
  59. ghnova-0.3.0.dist-info/entry_points.txt +2 -0
  60. ghnova-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,134 @@
1
+ """Asynchronous GitHub Repository resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Literal, cast
7
+
8
+ from aiohttp import ClientResponse
9
+
10
+ from ghnova.repository.base import BaseRepository
11
+ from ghnova.resource.async_resource import AsyncResource
12
+ from ghnova.utils.response import process_async_response_with_last_modified
13
+
14
+
15
+ class AsyncRepository(BaseRepository, AsyncResource):
16
+ """GitHub Repository resource."""
17
+
18
+ async def _list_repositories( # noqa: PLR0913
19
+ self,
20
+ owner: str | None = None,
21
+ organization: str | None = None,
22
+ visibility: Literal["all", "public", "private"] | None = None,
23
+ affiliation: list[Literal["owner", "collaborator", "organization_member"]] | None = None,
24
+ repository_type: Literal["all", "owner", "public", "private", "member"] | None = None,
25
+ sort: Literal["created", "updated", "pushed", "full_name"] | None = None,
26
+ direction: Literal["asc", "desc"] | None = None,
27
+ per_page: int = 30,
28
+ page: int = 1,
29
+ since: datetime | None = None,
30
+ before: datetime | None = None,
31
+ etag: str | None = None,
32
+ last_modified: str | None = None,
33
+ **kwargs: Any,
34
+ ) -> ClientResponse:
35
+ """List repositories information.
36
+
37
+ Args:
38
+ owner: The owner of the repositories to retrieve. If None, retrieves the authenticated user's repositories.
39
+ organization: The organization of the repositories to retrieve. If None, retrieves by owner.
40
+ visibility: The visibility of the repositories. Can be one of "all", "public", or "private".
41
+ affiliation: A list of affiliations for the repositories. Can include "owner", "collaborator", and/or "organization_member".
42
+ repository_type: The type of repositories to retrieve. Can be one of "all", "owner", "public", "private", or "member".
43
+ sort: The field to sort the repositories by. Can be one of "created", "updated", "pushed", or "full_name".
44
+ direction: The direction to sort the repositories. Can be either "asc" or "desc".
45
+ per_page: The number of results per page (max 100).
46
+ page: The page number of the results to fetch.
47
+ since: Only show repositories updated after this time.
48
+ before: Only show repositories updated before this time.
49
+ etag: The ETag header value for conditional requests.
50
+ last_modified: The Last-Modified header value for conditional requests.
51
+ **kwargs: Additional arguments for the request.
52
+
53
+ Returns:
54
+ The ClientResponse object containing the list of repositories.
55
+
56
+ """
57
+ endpoint, params, kwargs = self._list_repositories_helper(
58
+ owner=owner,
59
+ organization=organization,
60
+ visibility=visibility,
61
+ affiliation=affiliation,
62
+ repository_type=repository_type,
63
+ sort=sort,
64
+ direction=direction,
65
+ per_page=per_page,
66
+ page=page,
67
+ since=since,
68
+ before=before,
69
+ **kwargs,
70
+ )
71
+ return await self._get(endpoint, params=params, etag=etag, last_modified=last_modified, **kwargs)
72
+
73
+ async def list_repositories( # noqa: PLR0913
74
+ self,
75
+ owner: str | None = None,
76
+ organization: str | None = None,
77
+ visibility: Literal["all", "public", "private"] | None = None,
78
+ affiliation: list[Literal["owner", "collaborator", "organization_member"]] | None = None,
79
+ repository_type: Literal["all", "owner", "public", "private", "member"] | None = None,
80
+ sort: Literal["created", "updated", "pushed", "full_name"] | None = None,
81
+ direction: Literal["asc", "desc"] | None = None,
82
+ per_page: int = 30,
83
+ page: int = 1,
84
+ since: datetime | None = None,
85
+ before: datetime | None = None,
86
+ etag: str | None = None,
87
+ last_modified: str | None = None,
88
+ **kwargs: Any,
89
+ ) -> tuple[list[dict[str, Any]], int, str | None, str | None]:
90
+ """List repositories information.
91
+
92
+ Args:
93
+ owner: The owner of the repositories to retrieve. If None, retrieves the authenticated user's repositories.
94
+ organization: The organization of the repositories to retrieve. If None, retrieves by owner.
95
+ visibility: The visibility of the repositories. Can be one of "all", "public", or "private".
96
+ affiliation: A list of affiliations for the repositories. Can include "owner", "collaborator", and/or "organization_member".
97
+ repository_type: The type of repositories to retrieve. Can be one of "all", "owner", "public", "private", or "member".
98
+ sort: The field to sort the repositories by. Can be one of "created", "updated", "pushed", or "full_name".
99
+ direction: The direction to sort the repositories. Can be either "asc" or "desc".
100
+ per_page: The number of results per page (max 100).
101
+ page: The page number of the results to fetch.
102
+ since: Only show repositories updated after this time.
103
+ before: Only show repositories updated before this time.
104
+ etag: The ETag header value for conditional requests.
105
+ last_modified: The Last-Modified header value for conditional requests.
106
+ **kwargs: Additional arguments for the request.
107
+
108
+ Returns:
109
+ A tuple containing:
110
+
111
+ - A list of dictionaries representing the repositories.
112
+ - The HTTP status code of the response.
113
+ - The ETag header value from the response, if available.
114
+ - The Last-Modified header value from the response, if available.
115
+
116
+ """
117
+ response = await self._list_repositories(
118
+ owner=owner,
119
+ organization=organization,
120
+ visibility=visibility,
121
+ affiliation=affiliation,
122
+ repository_type=repository_type,
123
+ sort=sort,
124
+ direction=direction,
125
+ per_page=per_page,
126
+ page=page,
127
+ since=since,
128
+ before=before,
129
+ etag=etag,
130
+ last_modified=last_modified,
131
+ **kwargs,
132
+ )
133
+ data, status_code, etag_value, last_modified_value = await process_async_response_with_last_modified(response)
134
+ return cast(list[dict[str, Any]], data), status_code, etag_value, last_modified_value
@@ -0,0 +1,124 @@
1
+ """Base class for GitHub Repository resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from datetime import datetime
7
+ from typing import Any, Literal
8
+
9
+ logger = logging.getLogger("ghnova")
10
+
11
+
12
+ class BaseRepository:
13
+ """Base class for GitHub Repository resource."""
14
+
15
+ def _list_repositories_endpoint(self, owner: str | None = None, organization: str | None = None) -> tuple[str, str]:
16
+ """Determine the repositories endpoint based on owner or organization.
17
+
18
+ If both owner and organization are None, returns the authenticated user's repositories.
19
+ If owner is provided, returns that user's repositories.
20
+ If organization is provided, returns that organization's repositories.
21
+
22
+ Args:
23
+ owner: The owner of the repositories.
24
+ organization: The organization of the repositories.
25
+
26
+ Returns:
27
+ The API endpoint for the repositories and a description.
28
+
29
+ """
30
+ if owner is None and organization is None:
31
+ return "/user/repos", "authenticated user's repositories"
32
+ if owner is not None and organization is None:
33
+ return f"/users/{owner}/repos", "user's repositories"
34
+ if owner is None and organization is not None:
35
+ return f"/orgs/{organization}/repos", "organization's repositories"
36
+ raise ValueError("Specify either owner or organization, not both.")
37
+
38
+ def _list_repositories_helper( # noqa: PLR0912, PLR0913
39
+ self,
40
+ owner: str | None = None,
41
+ organization: str | None = None,
42
+ visibility: Literal["all", "public", "private"] | None = None,
43
+ affiliation: list[Literal["owner", "collaborator", "organization_member"]] | None = None,
44
+ repository_type: Literal["all", "owner", "public", "private", "member"] | None = None,
45
+ sort: Literal["created", "updated", "pushed", "full_name"] | None = None,
46
+ direction: Literal["asc", "desc"] | None = None,
47
+ per_page: int = 30,
48
+ page: int = 1,
49
+ since: datetime | None = None,
50
+ before: datetime | None = None,
51
+ **kwargs: Any,
52
+ ) -> tuple[str, dict[str, Any], dict[str, Any]]:
53
+ """List repositories information.
54
+
55
+ Args:
56
+ owner: The owner of the repositories to retrieve. If None, retrieves the authenticated user's repositories.
57
+ organization: The organization of the repositories to retrieve. If None, retrieves by owner.
58
+ visibility: The visibility of the repositories. Can be one of "all", "public", or "private".
59
+ affiliation: A list of affiliations for the repositories. Can include "owner", "collaborator", and/or "organization_member".
60
+ repository_type: The type of repositories to retrieve. Can be one of "all", "owner", "public", "private", or "member".
61
+ sort: The field to sort the repositories by. Can be one of "created", "updated", "pushed", or "full_name".
62
+ direction: The direction to sort the repositories. Can be either "asc" or "desc".
63
+ per_page: The number of repositories to return per page.
64
+ page: The page number to retrieve.
65
+ since: A datetime to filter repositories updated after this time.
66
+ before: A datetime to filter repositories updated before this time.
67
+ **kwargs: Additional arguments for the request.
68
+
69
+ Returns:
70
+ A tuple containing the endpoint and the request arguments.
71
+
72
+ - The API endpoint for the repositories.
73
+ - The query parameters for the request.
74
+ - A dictionary of request arguments.
75
+
76
+ """
77
+ endpoint, description = self._list_repositories_endpoint(owner=owner, organization=organization)
78
+ default_headers = {
79
+ "Accept": "application/vnd.github+json",
80
+ "X-GitHub-Api-Version": "2022-11-28",
81
+ }
82
+ headers = kwargs.get("headers") or {}
83
+ headers = {**default_headers, **headers}
84
+ kwargs["headers"] = headers
85
+
86
+ params = {}
87
+ if visibility is not None:
88
+ if description != "authenticated user's repositories":
89
+ logger.warning(
90
+ "The 'visibility' parameter is not applicable when listing an organization's repositories."
91
+ )
92
+ else:
93
+ params["visibility"] = visibility
94
+ if affiliation is not None:
95
+ if description != "authenticated user's repositories":
96
+ logger.warning(
97
+ "The 'affiliation' parameter is only applicable when listing the authenticated user's repositories."
98
+ )
99
+ else:
100
+ params["affiliation"] = ",".join(affiliation)
101
+ if repository_type is not None:
102
+ params["type"] = repository_type
103
+ if sort is not None:
104
+ params["sort"] = sort
105
+ if direction is not None:
106
+ params["direction"] = direction
107
+ params["per_page"] = per_page
108
+ params["page"] = page
109
+
110
+ extra_params = kwargs.pop("params", {})
111
+ params = {**params, **extra_params}
112
+
113
+ if since is not None:
114
+ if description != "authenticated user's repositories":
115
+ logger.warning("The 'since' parameter is not applicable when listing an organization's repositories.")
116
+ else:
117
+ params["since"] = since.isoformat()
118
+ if before is not None:
119
+ if description != "authenticated user's repositories":
120
+ logger.warning("The 'before' parameter is not applicable when listing an organization's repositories.")
121
+ else:
122
+ params["before"] = before.isoformat()
123
+
124
+ return endpoint, params, kwargs
@@ -0,0 +1,134 @@
1
+ """GitHub Repository resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Literal, cast
7
+
8
+ from requests import Response
9
+
10
+ from ghnova.repository.base import BaseRepository
11
+ from ghnova.resource.resource import Resource
12
+ from ghnova.utils.response import process_response_with_last_modified
13
+
14
+
15
+ class Repository(BaseRepository, Resource):
16
+ """GitHub Repository resource."""
17
+
18
+ def _list_repositories( # noqa: PLR0913
19
+ self,
20
+ owner: str | None = None,
21
+ organization: str | None = None,
22
+ visibility: Literal["all", "public", "private"] | None = None,
23
+ affiliation: list[Literal["owner", "collaborator", "organization_member"]] | None = None,
24
+ repository_type: Literal["all", "owner", "public", "private", "member"] | None = None,
25
+ sort: Literal["created", "updated", "pushed", "full_name"] | None = None,
26
+ direction: Literal["asc", "desc"] | None = None,
27
+ per_page: int = 30,
28
+ page: int = 1,
29
+ since: datetime | None = None,
30
+ before: datetime | None = None,
31
+ etag: str | None = None,
32
+ last_modified: str | None = None,
33
+ **kwargs: Any,
34
+ ) -> Response:
35
+ """List repositories information.
36
+
37
+ Args:
38
+ owner: The owner of the repositories to retrieve. If None, retrieves the authenticated user's repositories.
39
+ organization: The organization of the repositories to retrieve. If None, retrieves by owner.
40
+ visibility: The visibility of the repositories. Can be one of "all", "public", or "private".
41
+ affiliation: A list of affiliations for the repositories. Can include "owner", "collaborator", and/or "organization_member".
42
+ repository_type: The type of repositories to retrieve. Can be one of "all", "owner", "public", "private", or "member".
43
+ sort: The field to sort the repositories by. Can be one of "created", "updated", "pushed", or "full_name".
44
+ direction: The direction to sort the repositories. Can be either "asc" or "desc".
45
+ per_page: The number of results per page (max 100).
46
+ page: The page number of the results to fetch.
47
+ since: Only show repositories updated after this time.
48
+ before: Only show repositories updated before this time.
49
+ etag: The ETag header value for conditional requests.
50
+ last_modified: The Last-Modified header value for conditional requests.
51
+ **kwargs: Additional arguments for the request.
52
+
53
+ Returns:
54
+ The Response object containing the list of repositories.
55
+
56
+ """
57
+ endpoint, params, kwargs = self._list_repositories_helper(
58
+ owner=owner,
59
+ organization=organization,
60
+ visibility=visibility,
61
+ affiliation=affiliation,
62
+ repository_type=repository_type,
63
+ sort=sort,
64
+ direction=direction,
65
+ per_page=per_page,
66
+ page=page,
67
+ since=since,
68
+ before=before,
69
+ **kwargs,
70
+ )
71
+ return self._get(endpoint, params=params, etag=etag, last_modified=last_modified, **kwargs)
72
+
73
+ def list_repositories( # noqa: PLR0913
74
+ self,
75
+ owner: str | None = None,
76
+ organization: str | None = None,
77
+ visibility: Literal["all", "public", "private"] | None = None,
78
+ affiliation: list[Literal["owner", "collaborator", "organization_member"]] | None = None,
79
+ repository_type: Literal["all", "owner", "public", "private", "member"] | None = None,
80
+ sort: Literal["created", "updated", "pushed", "full_name"] | None = None,
81
+ direction: Literal["asc", "desc"] | None = None,
82
+ per_page: int = 30,
83
+ page: int = 1,
84
+ since: datetime | None = None,
85
+ before: datetime | None = None,
86
+ etag: str | None = None,
87
+ last_modified: str | None = None,
88
+ **kwargs: Any,
89
+ ) -> tuple[list[dict[str, Any]], int, str | None, str | None]:
90
+ """List repositories information.
91
+
92
+ Args:
93
+ owner: The owner of the repositories to retrieve. If None, retrieves the authenticated user's repositories.
94
+ organization: The organization of the repositories to retrieve. If None, retrieves by owner.
95
+ visibility: The visibility of the repositories. Can be one of "all", "public", or "private".
96
+ affiliation: A list of affiliations for the repositories. Can include "owner", "collaborator", and/or "organization_member".
97
+ repository_type: The type of repositories to retrieve. Can be one of "all", "owner", "public", "private", or "member".
98
+ sort: The field to sort the repositories by. Can be one of "created", "updated", "pushed", or "full_name".
99
+ direction: The direction to sort the repositories. Can be either "asc" or "desc".
100
+ per_page: The number of results per page (max 100).
101
+ page: The page number of the results to fetch.
102
+ since: Only show repositories updated after this time.
103
+ before: Only show repositories updated before this time.
104
+ etag: The ETag header value for conditional requests.
105
+ last_modified: The Last-Modified header value for conditional requests.
106
+ **kwargs: Additional arguments for the request.
107
+
108
+ Returns:
109
+ A tuple containing:
110
+
111
+ - A list of dictionaries representing the repositories.
112
+ - The HTTP status code of the response.
113
+ - The ETag header value from the response, if available.
114
+ - The Last-Modified header value from the response, if available.
115
+
116
+ """
117
+ response = self._list_repositories(
118
+ owner=owner,
119
+ organization=organization,
120
+ visibility=visibility,
121
+ affiliation=affiliation,
122
+ repository_type=repository_type,
123
+ sort=sort,
124
+ direction=direction,
125
+ per_page=per_page,
126
+ page=page,
127
+ since=since,
128
+ before=before,
129
+ etag=etag,
130
+ last_modified=last_modified,
131
+ **kwargs,
132
+ )
133
+ data, status_code, etag_value, last_modified_value = process_response_with_last_modified(response)
134
+ return cast(list[dict[str, Any]], data), status_code, etag_value, last_modified_value
@@ -0,0 +1,8 @@
1
+ """Resource package initialization."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ghnova.resource.async_resource import AsyncResource
6
+ from ghnova.resource.resource import Resource
7
+
8
+ __all__ = ["AsyncResource", "Resource"]
@@ -0,0 +1,88 @@
1
+ """Asynchronous Resource Base Class for GitHub API interactions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from aiohttp import ClientResponse
8
+
9
+ if TYPE_CHECKING:
10
+ from ghnova.client.async_github import AsyncGitHub
11
+
12
+
13
+ class AsyncResource:
14
+ """Base class for asynchronous GitHub API resources."""
15
+
16
+ def __init__(self, client: AsyncGitHub) -> None:
17
+ """Initialize the Resource with a AsyncGitHub client.
18
+
19
+ Args:
20
+ client: An instance of the AsyncGitHub client.
21
+
22
+ """
23
+ self.client = client
24
+
25
+ async def _get(self, endpoint: str, **kwargs: Any) -> ClientResponse:
26
+ """Perform a GET request.
27
+
28
+ Args:
29
+ endpoint: The API endpoint.
30
+ **kwargs: Additional arguments for the request.
31
+
32
+ Returns:
33
+ The ClientResponse object.
34
+
35
+ """
36
+ return await self.client._request(method="GET", endpoint=endpoint, **kwargs)
37
+
38
+ async def _post(self, endpoint: str, **kwargs: Any) -> ClientResponse:
39
+ """Perform a POST request.
40
+
41
+ Args:
42
+ endpoint: The API endpoint.
43
+ **kwargs: Additional arguments for the request.
44
+
45
+ Returns:
46
+ The ClientResponse object.
47
+
48
+ """
49
+ return await self.client._request(method="POST", endpoint=endpoint, **kwargs)
50
+
51
+ async def _put(self, endpoint: str, **kwargs: Any) -> ClientResponse:
52
+ """Perform a PUT request.
53
+
54
+ Args:
55
+ endpoint: The API endpoint.
56
+ **kwargs: Additional arguments for the request.
57
+
58
+ Returns:
59
+ The ClientResponse object.
60
+
61
+ """
62
+ return await self.client._request(method="PUT", endpoint=endpoint, **kwargs)
63
+
64
+ async def _delete(self, endpoint: str, **kwargs: Any) -> ClientResponse:
65
+ """Perform a DELETE request.
66
+
67
+ Args:
68
+ endpoint: The API endpoint.
69
+ **kwargs: Additional arguments for the request.
70
+
71
+ Returns:
72
+ The ClientResponse object.
73
+
74
+ """
75
+ return await self.client._request(method="DELETE", endpoint=endpoint, **kwargs)
76
+
77
+ async def _patch(self, endpoint: str, **kwargs: Any) -> ClientResponse:
78
+ """Perform a PATCH request.
79
+
80
+ Args:
81
+ endpoint: The API endpoint.
82
+ **kwargs: Additional arguments for the request.
83
+
84
+ Returns:
85
+ The ClientResponse object.
86
+
87
+ """
88
+ return await self.client._request(method="PATCH", endpoint=endpoint, **kwargs)
@@ -0,0 +1,88 @@
1
+ """Base class for GitHub API resources."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from requests import Response
8
+
9
+ if TYPE_CHECKING:
10
+ from ghnova.client.github import GitHub
11
+
12
+
13
+ class Resource:
14
+ """Base class for GitHub API resources."""
15
+
16
+ def __init__(self, client: GitHub) -> None:
17
+ """Initialize the Resource with a GitHub client.
18
+
19
+ Args:
20
+ client: An instance of the GitHub client.
21
+
22
+ """
23
+ self.client = client
24
+
25
+ def _get(self, endpoint: str, **kwargs: Any) -> Response:
26
+ """Perform a GET request.
27
+
28
+ Args:
29
+ endpoint: The API endpoint.
30
+ **kwargs: Additional arguments for the request.
31
+
32
+ Returns:
33
+ The response object.
34
+
35
+ """
36
+ return self.client._request(method="GET", endpoint=endpoint, **kwargs)
37
+
38
+ def _post(self, endpoint: str, **kwargs: Any) -> Response:
39
+ """Perform a POST request.
40
+
41
+ Args:
42
+ endpoint: The API endpoint.
43
+ **kwargs: Additional arguments for the request.
44
+
45
+ Returns:
46
+ The response object.
47
+
48
+ """
49
+ return self.client._request(method="POST", endpoint=endpoint, **kwargs)
50
+
51
+ def _put(self, endpoint: str, **kwargs: Any) -> Response:
52
+ """Perform a PUT request.
53
+
54
+ Args:
55
+ endpoint: The API endpoint.
56
+ **kwargs: Additional arguments for the request.
57
+
58
+ Returns:
59
+ The response object.
60
+
61
+ """
62
+ return self.client._request(method="PUT", endpoint=endpoint, **kwargs)
63
+
64
+ def _delete(self, endpoint: str, **kwargs: Any) -> Response:
65
+ """Perform a DELETE request.
66
+
67
+ Args:
68
+ endpoint: The API endpoint.
69
+ **kwargs: Additional arguments for the request.
70
+
71
+ Returns:
72
+ The response object.
73
+
74
+ """
75
+ return self.client._request(method="DELETE", endpoint=endpoint, **kwargs)
76
+
77
+ def _patch(self, endpoint: str, **kwargs: Any) -> Response:
78
+ """Perform a PATCH request.
79
+
80
+ Args:
81
+ endpoint: The API endpoint.
82
+ **kwargs: Additional arguments for the request.
83
+
84
+ Returns:
85
+ The response object.
86
+
87
+ """
88
+ return self.client._request(method="PATCH", endpoint=endpoint, **kwargs)
@@ -0,0 +1,8 @@
1
+ """GitHub user module."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ghnova.user.async_user import AsyncUser
6
+ from ghnova.user.user import User
7
+
8
+ __all__ = ["AsyncUser", "User"]