from common.log.module_logger import ModuleLogger from typing import List, Dict, Optional from common.config.app_settings import app_settings import httpx import asyncio async def fetch_with_retry(url, method="GET", retries=3, backoff=1.0, **kwargs): """ A generic function for making HTTP requests with retry logic. Parameters: url (str): The endpoint URL. method (str): HTTP method ('GET', 'POST', etc.). retries (int): Number of retry attempts. backoff (float): Backoff time in seconds. kwargs: Additional arguments for the request. Returns: httpx.Response: The response object. """ for attempt in range(retries): try: async with httpx.AsyncClient(timeout=httpx.Timeout(10.0)) as client: if method.upper() == "GET": response = await client.get(url, **kwargs) elif method.upper() == "POST": response = await client.post(url, **kwargs) response.raise_for_status() # Check for HTTP errors return response except (httpx.ReadTimeout, httpx.RequestError) as exc: if attempt < retries - 1: await asyncio.sleep(backoff * (2**attempt)) # Exponential backoff continue else: raise exc class CodeDepotService: def __init__(self) -> None: self.depot_endpoint = ( app_settings.DEVSVC_WEBAPI_URL_BASE.rstrip("/") + "/depot/" ) self.module_logger = ModuleLogger(sender_id="CodeDepotService") async def check_depot_name_availabe(self, code_depot_name: str) -> bool: api_url = self.depot_endpoint + "check-depot-name-available/" + code_depot_name response = await fetch_with_retry(api_url) return response.json() async def create_code_depot(self, product_id, code_depot_name) -> Optional[str]: api_url = self.depot_endpoint + "create-code-depot" response = await fetch_with_retry( api_url, method="POST", json={"product_id": product_id, "code_depot_name": code_depot_name}, ) return response.json() async def get_depot_ssh_url(self, code_depot_name: str) -> str: api_url = self.depot_endpoint + "get-depot-ssh-url/" + code_depot_name response = await fetch_with_retry(api_url) return response.json() async def get_depot_http_url(self, code_depot_name: str) -> str: api_url = self.depot_endpoint + "get-depot-http-url/" + code_depot_name response = await fetch_with_retry(api_url) return response.json() async def get_depot_http_url_with_user_name( self, code_depot_name: str, user_name: str ) -> str: api_url = ( self.depot_endpoint + "get-depot-http-url-with-user-name/" + code_depot_name + "/" + user_name ) response = await fetch_with_retry(api_url) return response.json() async def get_depot_users(self, code_depot_name: str) -> List[str]: api_url = self.depot_endpoint + "get-depot-users/" + code_depot_name response = await fetch_with_retry(api_url) return response.json() async def update_depot_user_password(self, user_name: str, password: str) -> bool: api_url = self.depot_endpoint + "update-depot-password-for-user" response = await fetch_with_retry( api_url, method="POST", json={"user_name": user_name, "password": password}, ) return response.json() async def create_depot_user( self, user_name: str, password: str, email: str ) -> bool: api_url = self.depot_endpoint + "create-depot-user" response = await fetch_with_retry( api_url, method="POST", json={"user_name": user_name, "password": password, "email": email}, ) return response.json() async def grant_user_depot_access( self, user_name: str, code_depot_name: str ) -> bool: api_url = self.depot_endpoint + "grant-user-depot-access" response = await fetch_with_retry( api_url, method="POST", json={"user_name": user_name, "code_depot_name": code_depot_name}, ) return response.json() async def generate_statistic_result( self, code_depot_name: str ) -> Optional[Dict[str, any]]: api_url = self.depot_endpoint + "generate-statistic-result/" + code_depot_name response = await fetch_with_retry(api_url) return response.json() async def fetch_code_depot(self, code_depot_id: str) -> Optional[Dict[str, any]]: api_url = self.depot_endpoint + "fetch-code-depot/" + code_depot_id response = await fetch_with_retry(api_url) return response.json()