"""Gitea REST API v1 client. Phase 2 implementation.""" import os import httpx class GiteaClient: def __init__(self, base_url: str, token: str): self.base_url = base_url.rstrip("/") self.token = token self._client = httpx.AsyncClient( base_url=f"{self.base_url}/api/v1", headers={"Authorization": f"token {self.token}"}, ) async def create_pull_request(self, owner, repo, title, head, base, body) -> dict: """Create a pull request. Args: owner: Repository owner repo: Repository name title: PR title head: Head branch name base: Base branch name body: PR body/description Returns: dict: Created PR data (number, html_url, etc.) """ resp = await self._client.post( f"/repos/{owner}/{repo}/pulls", json={"title": title, "head": head, "base": base, "body": body}, ) resp.raise_for_status() return resp.json() async def merge_pull_request(self, owner, repo, pr_number, merge_type="merge") -> dict: """Merge a pull request. Args: owner: Repository owner repo: Repository name pr_number: PR number merge_type: Merge type ("merge", "rebase", "squash") Returns: dict: Merge result """ resp = await self._client.post( f"/repos/{owner}/{repo}/pulls/{pr_number}/merge", json={"Do": merge_type}, ) resp.raise_for_status() return resp.json() async def create_issue_comment(self, owner, repo, issue_number, body) -> dict: """Create a comment on an issue or PR. Args: owner: Repository owner repo: Repository name issue_number: Issue or PR number body: Comment body Returns: dict: Created comment data (id, body, etc.) """ resp = await self._client.post( f"/repos/{owner}/{repo}/issues/{issue_number}/comments", json={"body": body}, ) resp.raise_for_status() return resp.json() async def get_issue(self, owner, repo, issue_number) -> dict: """Get issue or PR details. Args: owner: Repository owner repo: Repository name issue_number: Issue or PR number Returns: dict: Issue/PR data (number, title, body, etc.) """ resp = await self._client.get(f"/repos/{owner}/{repo}/issues/{issue_number}") resp.raise_for_status() return resp.json() async def get_issue_comments(self, owner, repo, issue_number) -> list: """Get all comments on an issue or PR. Args: owner: Repository owner repo: Repository name issue_number: Issue or PR number Returns: list: List of comment dicts """ resp = await self._client.get( f"/repos/{owner}/{repo}/issues/{issue_number}/comments" ) resp.raise_for_status() return resp.json() async def create_branch(self, owner, repo, branch_name, old_branch) -> dict: """Create a new branch. Args: owner: Repository owner repo: Repository name branch_name: New branch name old_branch: Source branch name Returns: dict: Created branch data """ resp = await self._client.post( f"/repos/{owner}/{repo}/branches", json={"new_branch_name": branch_name, "old_branch_name": old_branch}, ) resp.raise_for_status() return resp.json() async def close(self): await self._client.aclose() # Lazy singleton _client: GiteaClient | None = None def get_gitea_client() -> GiteaClient: """Get or create the singleton GiteaClient instance. Returns: GiteaClient: The singleton instance """ global _client if _client is None: _client = GiteaClient( base_url=os.environ.get("GITEA_URL", "http://gitea:3000"), token=os.environ.get("GITEA_TOKEN", ""), ) return _client