from typing import TypedDict from urllib.parse import quote from nyekiapi.lib import settings, project, cache from nyekiapi.lib.requests import httpx from nyekiapi.lib.integrations import Profile CACHE_BY_ID_KEY = "github:profile:id:%s" CACHE_BY_NAME_KEY = "github:profile:name:%s" class GithubProfile(TypedDict): login: str name: str | None avatar_url: str html_url: str async def get_profile_by_id(id: str) -> Profile: profile = await cache.get(CACHE_BY_ID_KEY % id) if profile is not None: return Profile.from_json(profile) response = await httpx.get( f"https://api.github.com/user/{quote(id)}", headers={ "Authorization": f"Bearer {settings.GITHUB_TOKEN}", "User-Agent": f"NyekiAPI/{project.PROJECT_VERSION}", }, ) response.raise_for_status() data: GithubProfile = response.json() profile = Profile( id=id, url=data["html_url"], name=data.get("name") or data["login"], username=data["login"], avatar_url=data["avatar_url"], banner_url=None, ) await cache.set(CACHE_BY_ID_KEY % profile.id, profile, expires_in=10 * 60) await cache.set(CACHE_BY_NAME_KEY % profile.username, profile, expires_in=10 * 60) return profile async def get_profile_by_name(username: str) -> Profile: profile = await cache.get(CACHE_BY_NAME_KEY % username) if profile is not None: return Profile.from_json(profile) response = await httpx.get( f"https://api.github.com/users/{quote(username)}", headers={ "Authorization": f"Bearer {settings.GITHUB_TOKEN}", "User-Agent": f"NyekiAPI/{project.PROJECT_VERSION}", }, ) response.raise_for_status() data: GithubProfile = response.json() profile = Profile( id=str(data["id"]), url=data["html_url"], name=data.get("name") or data["login"], username=data["login"], avatar_url=data["avatar_url"], banner_url=None, ) await cache.set(CACHE_BY_ID_KEY % profile.id, profile, expires_in=10 * 60) await cache.set(CACHE_BY_NAME_KEY % profile.username, profile, expires_in=10 * 60) return profile