Coverage for src / augint_library / core.py: 100%
17 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 20:22 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 20:22 +0000
1"""Core library functions for augint-library.
3This module demonstrates the fundamental pattern for creating library functions
4that can be used both programmatically and through a CLI. It showcases:
5- Simple, focused functions with clear purposes
6- Proper error handling with custom exceptions
7- Type hints for better IDE support
8- Comprehensive docstrings with examples
10Common Use Cases:
11 1. Direct library usage in Python scripts
12 2. Building CLIs that wrap library functions
13 3. Creating testable, reusable components
14 4. Demonstrating error simulation for testing
16Example:
17 Basic library usage:
18 >>> from augint_library import print_hi, fetch_data
19 >>>
20 >>> # Simple function call
21 >>> print_hi("World")
22 Hi World
23 >>>
24 >>> # Function with error handling
25 >>> try:
26 ... data = fetch_data("/api/users", timeout=5.0)
27 ... print(f"Success: {data['status']}")
28 ... except NetworkError as e:
29 ... print(f"Failed: {e.message}")
31 Building a CLI wrapper:
32 >>> import click
33 >>> from augint_library import print_hi
34 >>>
35 >>> @click.command()
36 >>> @click.argument('name')
37 >>> def greet(name):
38 ... '''Greet someone.'''
39 ... print_hi(name)
41Note:
42 This module uses simple examples to demonstrate patterns that scale
43 to complex production libraries. The patterns shown here (error handling,
44 type hints, documentation) should be applied consistently across all
45 library modules.
46"""
48import random
49import time
50from typing import Any
52from .constants import (
53 DEFAULT_API_TIMEOUT,
54 DEFAULT_FAILURE_RATE,
55 SIMULATION_DELAY_MIN,
56 TIMEOUT_FAILURE_MULTIPLIER,
57 TIMEOUT_SUCCESS_MULTIPLIER,
58)
59from .exceptions import NetworkError, NetworkTimeoutError
62def print_hi(name: str) -> None:
63 """Print a friendly greeting to the given name.
65 This is the main library function that can be imported and used
66 in other Python code.
68 Args:
69 name: The name of the person to greet.
71 Example:
72 >>> print_hi("Alice")
73 Hi Alice
74 """
75 print(f"Hi {name}")
78def fetch_data(
79 endpoint: str, timeout: float = DEFAULT_API_TIMEOUT, failure_rate: float = DEFAULT_FAILURE_RATE
80) -> dict[str, Any]:
81 """Fetch data from a remote endpoint (simulated).
83 This function simulates an external API call that might fail transiently.
84 It's designed to demonstrate when retry and circuit breaker patterns are useful.
86 In a real application, this would make an actual HTTP request to an external service.
87 The simulation allows us to control failure rates for testing and demonstration.
89 Args:
90 endpoint: The API endpoint to fetch from.
91 timeout: Maximum time to wait for response (seconds).
92 failure_rate: Probability of failure (0.0-1.0) for simulation.
94 Returns:
95 A dictionary containing the fetched data.
97 Raises:
98 NetworkTimeoutError: If the request times out.
99 NetworkError: If the network request fails.
101 Examples:
102 Basic usage with guaranteed success:
103 >>> data = fetch_data("/api/users", timeout=2.0, failure_rate=0.0)
104 >>> print(data["status"])
105 ok
106 >>> print(data["endpoint"])
107 /api/users
109 Handling timeout errors:
110 >>> try:
111 ... data = fetch_data("/api/slow", timeout=0.001)
112 ... except NetworkTimeoutError as e:
113 ... print(f"Timeout: {e.message}")
114 ... print(f"Service: {e.details['service']}")
115 Timeout: Timeout connecting to API endpoint /api/slow after 0.001s
116 Service: API endpoint /api/slow
118 Using with retry decorator for resilience:
119 >>> from augint_library.resilience import retry
120 >>>
121 >>> @retry(max_attempts=3, initial_delay=0.1)
122 ... def reliable_fetch(endpoint):
123 ... return fetch_data(endpoint, failure_rate=0.5)
124 >>>
125 >>> # This will retry up to 3 times on failure
126 >>> data = reliable_fetch("/api/data")
128 Testing error conditions:
129 >>> # Force a failure for testing
130 >>> try:
131 ... data = fetch_data("/api/test", failure_rate=1.0)
132 ... except NetworkError as e:
133 ... print(f"Expected failure: {e.code.value}")
134 Expected failure: NETWORK_ERROR
136 Note:
137 This function is intentionally simple to demonstrate patterns.
138 In production, you would:
139 - Use actual HTTP libraries (requests, httpx, urllib)
140 - Add authentication and headers
141 - Handle different status codes
142 - Parse response formats (JSON, XML, etc.)
143 - Add logging and metrics
144 """
145 # Simulate network delay
146 if failure_rate > 0:
147 # Allow delays that might exceed timeout when failures are possible
148 delay = random.uniform(SIMULATION_DELAY_MIN, timeout * TIMEOUT_FAILURE_MULTIPLIER) # noqa: S311 - simulation only
149 else:
150 # When failure_rate is 0, ensure we never timeout
151 delay = random.uniform(SIMULATION_DELAY_MIN, timeout * TIMEOUT_SUCCESS_MULTIPLIER) # noqa: S311 - simulation only
153 if delay > timeout:
154 raise NetworkTimeoutError(
155 service=f"API endpoint {endpoint}", timeout=timeout, attempted_duration=delay
156 )
158 time.sleep(delay)
160 # Simulate random failures (but not when failure_rate is 0)
161 if failure_rate > 0 and random.random() < failure_rate: # noqa: S311 - simulation only
162 raise NetworkError(
163 f"Failed to connect to {endpoint}", service=f"API endpoint {endpoint}", status_code=503
164 )
166 # Return simulated successful response
167 return {
168 "status": "ok",
169 "endpoint": endpoint,
170 "data": {"users": ["Alice", "Bob", "Charlie"]},
171 "timestamp": time.time(),
172 }