""" GitHub Service for WHOOSH Backend This service is responsible for all interactions with the GitHub API, specifically for creating tasks as GitHub Issues for the Bzzz network to consume. """ import os import json import logging from typing import Dict, Any import aiohttp logger = logging.getLogger(__name__) class GitHubService: """ A service to interact with the GitHub API. """ def __init__(self): self.token = os.getenv("GITHUB_TOKEN") self.owner = "anthonyrawlins" self.repo = "bzzz" self.api_url = f"https://api.github.com/repos/{self.owner}/{self.repo}/issues" if not self.token: logger.error("GITHUB_TOKEN environment variable not set. GitHubService will be disabled.") raise ValueError("GITHUB_TOKEN must be set to use the GitHubService.") self.headers = { "Authorization": f"token {self.token}", "Accept": "application/vnd.github.v3+json", } async def create_bzzz_task_issue(self, task: Dict[str, Any]) -> Dict[str, Any]: """ Creates a new issue in the Bzzz GitHub repository to represent a WHOOSH task. Args: task: A dictionary representing the task from WHOOSH. Returns: A dictionary with the response from the GitHub API. """ if not self.token: logger.warning("Cannot create GitHub issue: GITHUB_TOKEN is not configured.") return {"error": "GitHub token not configured."} title = f"WHOOSH Task: {task.get('id', 'N/A')} - {task.get('type', 'general').value}" # Format the body of the issue body = f"### WHOOSH Task Details\n\n" body += f"**Task ID:** `{task.get('id')}`\n" body += f"**Task Type:** `{task.get('type').value}`\n" body += f"**Priority:** `{task.get('priority')}`\n\n" body += f"#### Context\n" body += f"```json\n{json.dumps(task.get('context', {}), indent=2)}\n```\n\n" body += f"*This issue was automatically generated by the WHOOSH-Bzzz Bridge.*" # Define the labels for the issue labels = ["whoosh-task", f"priority-{task.get('priority', 3)}", f"type-{task.get('type').value}"] payload = { "title": title, "body": body, "labels": labels, } async with aiohttp.ClientSession(headers=self.headers) as session: try: async with session.post(self.api_url, json=payload) as response: response_data = await response.json() if response.status == 201: logger.info(f"Successfully created GitHub issue #{response_data.get('number')} for WHOOSH task {task.get('id')}") return { "success": True, "issue_number": response_data.get('number'), "url": response_data.get('html_url'), } else: logger.error(f"Failed to create GitHub issue for task {task.get('id')}. Status: {response.status}, Response: {response_data}") return { "success": False, "error": "Failed to create issue", "details": response_data, } except Exception as e: logger.error(f"An exception occurred while creating GitHub issue for task {task.get('id')}: {e}") return {"success": False, "error": str(e)}