Skip to content

client

appimage_updater.github.client

GitHub API client for fetching release information.

GitHubClient(timeout=30, user_agent=None, auth=None, token=None)

Client for GitHub API operations with authentication support.

Parameters:

Name Type Description Default
timeout int

Request timeout in seconds

30
user_agent str | None

Custom user agent string

None
auth GitHubAuth | None

GitHubAuth instance for authentication

None
token str | None

Explicit GitHub token (creates auth if provided)

None
Source code in src/appimage_updater/github/client.py
def __init__(
    self,
    timeout: int = 30,
    user_agent: str | None = None,
    auth: GitHubAuth | None = None,
    token: str | None = None,
) -> None:
    """Initialize GitHub client.

    Args:
        timeout: Request timeout in seconds
        user_agent: Custom user agent string
        auth: GitHubAuth instance for authentication
        token: Explicit GitHub token (creates auth if provided)
    """
    self.timeout = timeout
    self.user_agent = user_agent or f"AppImage-Updater/{__version__}"

    # Set up authentication
    if auth:
        self.auth = auth
    elif token:
        self.auth = get_github_auth(token=token)
    else:
        self.auth = get_github_auth()

    # Log authentication status
    self.auth.log_auth_status()

auth = auth instance-attribute

timeout = timeout instance-attribute

user_agent = user_agent or f'AppImage-Updater/{__version__}' instance-attribute

get_latest_release(repo_url) async

Get the latest release for a repository.

Source code in src/appimage_updater/github/client.py
async def get_latest_release(self, repo_url: str) -> Release:
    """Get the latest release for a repository."""
    owner, repo = self._parse_repo_url(repo_url)
    api_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"

    async with httpx.AsyncClient(timeout=self.timeout) as client:
        try:
            response = await client.get(
                api_url,
                headers=self.auth.get_auth_headers(),
            )
            response.raise_for_status()
        except httpx.HTTPError as e:
            msg = f"Failed to fetch latest release for {owner}/{repo}: {e}"
            if "rate limit" in str(e).lower():
                rate_info = self.auth.get_rate_limit_info()
                msg += f" (Rate limit: {rate_info['limit']} requests/hour for {rate_info['type']} access)"
                if not self.auth.is_authenticated:
                    msg += ". Consider setting GITHUB_TOKEN environment variable for higher limits."
            raise GitHubClientError(msg) from e

    return self._parse_release(response.json())

get_latest_release_including_prerelease(repo_url) async

Get the latest release including prereleases.

Source code in src/appimage_updater/github/client.py
async def get_latest_release_including_prerelease(self, repo_url: str) -> Release:
    """Get the latest release including prereleases."""
    # Get recent releases to find the latest including prereleases
    releases = await self.get_releases(repo_url, limit=20)
    if not releases:
        msg = f"No releases found for repository: {repo_url}"
        raise GitHubClientError(msg)

    # Filter out drafts but keep prereleases, sort by published date
    valid_releases = [release for release in releases if not release.is_draft]

    if not valid_releases:
        msg = f"No non-draft releases found for repository: {repo_url}"
        raise GitHubClientError(msg)

    # Sort by published_at descending to get the most recent
    valid_releases.sort(key=lambda r: r.published_at, reverse=True)
    return valid_releases[0]

get_releases(repo_url, limit=10) async

Get recent releases for a repository.

Source code in src/appimage_updater/github/client.py
async def get_releases(self, repo_url: str, limit: int = 10) -> list[Release]:
    """Get recent releases for a repository."""
    owner, repo = self._parse_repo_url(repo_url)
    api_url = f"https://api.github.com/repos/{owner}/{repo}/releases"

    async with httpx.AsyncClient(timeout=self.timeout) as client:
        try:
            response = await client.get(
                api_url,
                headers=self.auth.get_auth_headers(),
                params={"per_page": str(limit)},
            )
            response.raise_for_status()
        except httpx.HTTPError as e:
            self._handle_releases_request_error(e, owner, repo)

    return self._validate_and_parse_releases_response(response)

GitHubClientError

Raised when GitHub API operations fail.