From 74adaf3a79c307b96ff961099ae3e2ee2d0d8467 Mon Sep 17 00:00:00 2001 From: starmen1265 Date: Fri, 13 Mar 2026 17:19:42 +0800 Subject: [PATCH] feat(01-03): implement retry mechanism with tenacity - retry_on_network_error decorator for automatic retry - Max 3 attempts with exponential backoff (2s, 4s, max 10s) - Only retries on NetworkError - Logs retry attempts via before_sleep_log - Reraises original exception after max attempts Co-Authored-By: Claude Opus 4.6 --- kb_pipeline/retry.py | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 kb_pipeline/retry.py diff --git a/kb_pipeline/retry.py b/kb_pipeline/retry.py new file mode 100644 index 0000000..ecd5c67 --- /dev/null +++ b/kb_pipeline/retry.py @@ -0,0 +1,51 @@ +"""Retry mechanism for KB Pipeline + +Provides automatic retry for network errors using tenacity library. +""" + +import logging +from tenacity import ( + retry, + stop_after_attempt, + wait_exponential, + retry_if_exception_type, + before_sleep_log, +) + +from .errors import NetworkError + +logger = logging.getLogger(__name__) + +retry_on_network_error = retry( + stop=stop_after_attempt(3), + wait=wait_exponential(multiplier=1, min=2, max=10), + retry=retry_if_exception_type(NetworkError), + before_sleep=before_sleep_log(logger, logging.WARNING), + reraise=True, +) +"""Decorator for automatic retry on network errors + +Automatically retries functions that raise NetworkError up to 3 times +with exponential backoff (2s, 4s, up to max 10s). + +Example: + @retry_on_network_error + def fetch_data(url): + response = requests.get(url) + if response.status_code >= 500: + raise NetworkError( + step_name="fetch", + input_summary=f"url={url}", + status_code=response.status_code + ) + return response.json() + +Args: + func: Function to wrap with retry logic + +Returns: + Wrapped function with retry logic + +Raises: + NetworkError: After 3 failed attempts +"""