mirror of
https://github.com/Horizontal42/netsleuth.git
synced 2026-11-11 02:12:04 +03:00
docs: add comprehensive docstrings to orchestration module
- Add docstring to utc_now_iso() explaining return format - Add docstring to classify_exception() with args, returns, and examples - Add docstring to run_module() detailing timeout and error handling behavior - Add docstring to gather_modules() describing concurrent execution semantics
This commit is contained in:
parent
e6cbe1b4ab
commit
310404bceb
1 changed files with 59 additions and 0 deletions
|
|
@ -14,10 +14,34 @@ _RETRYABLE_STATUS_FLOOR = 500
|
|||
|
||||
|
||||
def utc_now_iso() -> str:
|
||||
"""Return the current UTC timestamp in ISO 8601 format.
|
||||
|
||||
Returns:
|
||||
A string like '2025-01-15T14:30:00Z' representing the current UTC time.
|
||||
"""
|
||||
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
|
||||
def classify_exception(exc: BaseException) -> tuple[str, bool]:
|
||||
"""Classify an exception into a probe error kind and retryability.
|
||||
|
||||
Maps exceptions to one of the standard error kinds defined in models.py
|
||||
and determines whether the operation should be retried.
|
||||
|
||||
Args:
|
||||
exc: The exception to classify.
|
||||
|
||||
Returns:
|
||||
A tuple of (kind, retryable) where kind is one of the ERROR_KINDS
|
||||
values and retryable indicates whether the operation might succeed
|
||||
if retried.
|
||||
|
||||
Examples:
|
||||
>>> classify_exception(asyncio.TimeoutError())
|
||||
('timeout', True)
|
||||
>>> classify_exception(PermissionError())
|
||||
('no_privilege', False)
|
||||
"""
|
||||
if isinstance(exc, (asyncio.TimeoutError, TimeoutError, httpx.TimeoutException)):
|
||||
return "timeout", True
|
||||
if isinstance(exc, httpx.HTTPStatusError):
|
||||
|
|
@ -45,6 +69,25 @@ async def run_module(
|
|||
timeout: float,
|
||||
source: str | None = None,
|
||||
) -> ModuleResult:
|
||||
"""Execute a probe module with timeout and error handling.
|
||||
|
||||
Runs the given coroutine with a timeout, catching any exceptions and
|
||||
converting them into structured ProbeError objects. Tracks execution
|
||||
timing and ensures the result has consistent metadata.
|
||||
|
||||
Args:
|
||||
name: The module name for identification in results.
|
||||
coro: The coroutine to execute (typically an async probe function).
|
||||
timeout: Maximum time in seconds to wait for the coroutine.
|
||||
source: Optional source identifier for errors; defaults to name.
|
||||
|
||||
Returns:
|
||||
A ModuleResult with status 'ok', 'partial', or 'failed', containing
|
||||
either the probe data or structured error information.
|
||||
|
||||
Raises:
|
||||
asyncio.CancelledError: Propagated without modification.
|
||||
"""
|
||||
started_at = utc_now_iso()
|
||||
began = time.perf_counter()
|
||||
try:
|
||||
|
|
@ -71,6 +114,22 @@ async def run_module(
|
|||
|
||||
|
||||
async def gather_modules(*results: Awaitable[ModuleResult]) -> list[ModuleResult]:
|
||||
"""Run multiple modules concurrently and collect their results.
|
||||
|
||||
Executes all provided coroutines in parallel using asyncio.gather,
|
||||
converting any exceptions into failed ModuleResult objects so that
|
||||
one failing module doesn't prevent others from completing.
|
||||
|
||||
Args:
|
||||
*results: Variable number of awaitable ModuleResult coroutines.
|
||||
|
||||
Returns:
|
||||
A list of ModuleResult objects, one for each input coroutine.
|
||||
Failed coroutines are represented as ModuleResult with status 'failed'.
|
||||
|
||||
Raises:
|
||||
asyncio.CancelledError: Propagated without modification.
|
||||
"""
|
||||
gathered = await asyncio.gather(*results, return_exceptions=True)
|
||||
out: list[ModuleResult] = []
|
||||
for item in gathered:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue