Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub Users API #909

Merged
merged 2 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions pontos/github/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from pontos.github.api.secret_scanning import GitHubAsyncRESTSecretScanning
from pontos.github.api.tags import GitHubAsyncRESTTags
from pontos.github.api.teams import GitHubAsyncRESTTeams
from pontos.github.api.users import GitHubAsyncRESTUsers
from pontos.github.api.workflows import GitHubAsyncRESTWorkflows
from pontos.helper import deprecated

Expand Down Expand Up @@ -95,6 +96,13 @@ def branches(self) -> GitHubAsyncRESTBranches:
"""
return GitHubAsyncRESTBranches(self._client)

@property
def code_scanning(self) -> GitHubAsyncRESTCodeScanning:
"""
Code scanning related API
"""
return GitHubAsyncRESTCodeScanning(self._client)

@property
def contents(self) -> GitHubAsyncRESTContent:
"""
Expand Down Expand Up @@ -168,11 +176,11 @@ def secret_scanning(self) -> GitHubAsyncRESTSecretScanning:
return GitHubAsyncRESTSecretScanning(self._client)

@property
def code_scanning(self) -> GitHubAsyncRESTCodeScanning:
def search(self) -> GitHubAsyncRESTSearch:
"""
Code scanning related API
Search related API
"""
return GitHubAsyncRESTCodeScanning(self._client)
return GitHubAsyncRESTSearch(self._client)

@property
def teams(self) -> GitHubAsyncRESTTeams:
Expand All @@ -189,11 +197,11 @@ def tags(self) -> GitHubAsyncRESTTags:
return GitHubAsyncRESTTags(self._client)

@property
def search(self) -> GitHubAsyncRESTSearch:
def users(self) -> GitHubAsyncRESTUsers:
"""
Search related API
Users related API
"""
return GitHubAsyncRESTSearch(self._client)
return GitHubAsyncRESTUsers(self._client)

async def __aenter__(self) -> "GitHubAsyncRESTApi":
await self._client.__aenter__()
Expand Down
289 changes: 289 additions & 0 deletions pontos/github/api/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
# SPDX-FileCopyrightText: 2023 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later

from typing import AsyncIterator, Union

from pontos.github.api.client import GitHubAsyncREST
from pontos.github.api.helper import JSON_OBJECT
from pontos.github.models.base import User
from pontos.github.models.user import (
EmailInformation,
SSHPublicKey,
SSHPublicKeyExtended,
)


class GitHubAsyncRESTUsers(GitHubAsyncREST):
async def users(self) -> AsyncIterator[User]:
"""

https://docs.github.com/en/rest/users/users#list-users

Args:
username: The handle for the GitHub user account

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
An async iterator yielding user information

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
async for user in api.users.users():
print(user)
"""
api = "/users"
params = {"per_page": "100"}
async for response in self._client.get_all(api, params=params):
response.raise_for_status()

for user in response.json():
yield User.from_dict(user)

async def user(self, username: str) -> User:
"""
Provide publicly available information about someone with a GitHub
account

https://docs.github.com/en/rest/users/users#get-a-user

Args:
username: The handle for the GitHub user account

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
Information about the user

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
user = await api.users.user("foo")
print(user)
"""
api = f"/users/{username}"
response = await self._client.get(api)
response.raise_for_status()
return User.from_dict(response.json())

async def current_user(self) -> User:
"""
Get the current authenticated user

https://docs.github.com/en/rest/users/users#get-the-authenticated-user

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
Information about the user

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
user = await api.users.current_user()
print(user)
"""
api = "/user"
response = await self._client.get(api)
response.raise_for_status()
return User.from_dict(response.json())

async def user_keys(self, username: str) -> AsyncIterator[SSHPublicKey]:
"""
List the verified public SSH keys for a user

https://docs.github.com/en/rest/users/keys#list-public-keys-for-a-user

Args:
username: The handle for the GitHub user account

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
An async iterator yielding ssh key information

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
async for key in api.users.user_keys("foo"):
print(key)
"""
api = f"/users/{username}/keys"
params = {"per_page": "100"}
async for response in self._client.get_all(api, params=params):
response.raise_for_status()

for key in response.json():
yield SSHPublicKey.from_dict(key)

async def keys(self) -> AsyncIterator[SSHPublicKey]:
"""
List the public SSH keys for the authenticated user's GitHub account

https://docs.github.com/en/rest/users/keys#list-public-ssh-keys-for-the-authenticated-user

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
An async iterator yielding ssh key information

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
async for key in api.users.keys():
print(key)
"""
api = "/user/keys"
params = {"per_page": "100"}
async for response in self._client.get_all(api, params=params):
response.raise_for_status()

for key in response.json():
yield SSHPublicKey.from_dict(key)

async def emails(self) -> AsyncIterator[EmailInformation]:
"""
List all email addresses of the currently logged in user

https://docs.github.com/en/rest/users/emails#list-email-addresses-for-the-authenticated-user

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
An async iterator yielding email information

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
async for email in api.users.emails():
print(email)
"""
api = "/user/emails"
params = {"per_page": "100"}
async for response in self._client.get_all(api, params=params):
response.raise_for_status()

for email in response.json():
yield EmailInformation.from_dict(email)

async def key(self, key_id: Union[str, int]) -> SSHPublicKeyExtended:
"""
View extended details for a single public SSH key

https://docs.github.com/en/rest/users/keys#get-a-public-ssh-key-for-the-authenticated-user

Args:
key_id: The unique identifier of the key

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
Extended information about the SSH key

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
key = await api.users.key(123)
print(key)
"""
api = f"/user/keys/{key_id}"
response = await self._client.get(api)
response.raise_for_status()
return SSHPublicKeyExtended.from_dict(response.json())

async def delete_key(self, key_id: Union[str, int]) -> None:
"""
Removes a public SSH key from the authenticated user's GitHub account

https://docs.github.com/en/rest/users/keys#delete-a-public-ssh-key-for-the-authenticated-user

Args:
key_id: The unique identifier of the key

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
await api.users.delete_key(123)
"""
api = f"/user/keys/{key_id}"
response = await self._client.delete(api)
response.raise_for_status()

async def create_key(self, title: str, key: str) -> SSHPublicKeyExtended:
"""
Adds a public SSH key to the authenticated user's GitHub account

https://docs.github.com/en/rest/users/keys#create-a-public-ssh-key-for-the-authenticated-user

Args:
title: A descriptive name for the new key
key: The public SSH key to add to your GitHub account

Raises:
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
failed.

Returns:
Extended information about the SSH key

Example:
.. code-block:: python

from pontos.github.api import GitHubAsyncRESTApi

async with GitHubAsyncRESTApi(token) as api:
key = await api.users.create_key(
"My SSH Public Key",
"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"
)
print(key)
"""
api = "/user/keys"
data: JSON_OBJECT = {"key": key, "title": title}
response = await self._client.post(api, data=data)
response.raise_for_status()
return SSHPublicKeyExtended.from_dict(response.json())
Loading