Spaces:
Sleeping
Sleeping
Download app/services/note_client.py from bichnhan2701/PhoWhisperBaseAPI: direct link, hf CLI and curl.
- Browser
- Download file 2.83 kB
-
https://huggingface.co/spaces/bichnhan2701/PhoWhisperBaseAPI/resolve/main/app/services/note_client.py
- Command line
-
hf download hf://spaces/bichnhan2701/PhoWhisperBaseAPI/app/services/note_client.py
-
curl -L -o note_client.py https://huggingface.co/spaces/bichnhan2701/PhoWhisperBaseAPI/resolve/main/app/services/note_client.py
2.83 kB
| import logging | |
| import asyncio | |
| import httpx | |
| from app.config.settings import NOTE_SERVICE_URL | |
| class NoteServiceClient: | |
| MAX_RETRIES = 3 | |
| RETRY_DELAYS = [1, 2, 4] # exponential backoff in seconds | |
| async def create_audio_note(self, payload: dict): | |
| """Call the Note Service to create an audio note. | |
| This method catches HTTP errors and logs them instead of raising, | |
| to avoid making transcription endpoints return 500 when the | |
| Note Service is unavailable or returns 4xx/5xx. | |
| Retries on 429 (rate limit) with exponential backoff. | |
| Returns parsed JSON on success or None on failure. | |
| """ | |
| url = f"{NOTE_SERVICE_URL}/internal/notes/audio" | |
| for attempt in range(self.MAX_RETRIES): | |
| try: | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| r = await client.post(url, json=payload) | |
| r.raise_for_status() | |
| return r.json() | |
| except httpx.HTTPStatusError as exc: | |
| status = getattr(exc.response, "status_code", None) | |
| # Retry on 429 Too Many Requests | |
| if status == 429 and attempt < self.MAX_RETRIES - 1: | |
| delay = self.RETRY_DELAYS[attempt] | |
| logging.warning( | |
| "NoteService rate limited (429), retrying in %ds (attempt %d/%d)", | |
| delay, attempt + 1, self.MAX_RETRIES | |
| ) | |
| await asyncio.sleep(delay) | |
| continue | |
| logging.warning( | |
| "NoteService returned HTTP %s for %s: %s", | |
| status, | |
| url, | |
| exc, | |
| ) | |
| return None | |
| except Exception as exc: # network errors, timeouts, etc. | |
| logging.exception("Failed to call NoteService: %s", exc) | |
| return None | |
| return None | |
| async def save_transcript(self, payload: dict): | |
| # alias used elsewhere in the codebase | |
| return await self.create_audio_note(payload) | |
| async def update_note(self, note_id: str, payload: dict): | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| r = await client.patch( | |
| f"{NOTE_SERVICE_URL}/notes/{note_id}", | |
| json=payload, | |
| ) | |
| r.raise_for_status() | |
| return r.json() | |
| async def update_note_internal(self, note_id: str, payload: dict): | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| r = await client.patch( | |
| f"{NOTE_SERVICE_URL}/internal/notes/{note_id}", | |
| json=payload, | |
| ) | |
| r.raise_for_status() | |
| return r.json() |