Decorators¶
The helpers/decorators subpackage provides function and class decorators for cross-cutting concerns including caching,
retry logic, deprecation, timing, tracing, and transaction management.
Cache¶
Decorator for caching function return values to avoid redundant computation or I/O.
archipy.helpers.decorators.cache.CachedFunction ¶
Wrapper class for a cached function with a clear_cache method.
This class wraps a function to provide TTL-based caching. The cache is shared across all instances when used as an instance method decorator.
Example
@ttl_cache_decorator(ttl_seconds=60, maxsize=100)
def expensive_function(x: int) -> int:
return x * 2
# First call executes the function
result = expensive_function(5) # Returns 10
# Second call returns cached result
result = expensive_function(5) # Returns 10 (from cache)
# Clear cache manually
expensive_function.clear_cache()
Source code in archipy/helpers/decorators/cache.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |
archipy.helpers.decorators.cache.CachedFunction.clear_cache ¶
Clear the cache.
This clears all cached values for this function. When used with instance methods, this clears the shared cache for all instances.
archipy.helpers.decorators.cache.ttl_cache_decorator ¶
ttl_cache_decorator(
ttl_seconds: int = 300, maxsize: int = 100
) -> Callable[[Callable[P, R]], CachedFunction[P, R]]
Decorator that provides a TTL cache for functions and methods.
The cache is shared across all instances when decorating instance methods. This is by design to allow efficient caching of expensive operations that depend only on the method arguments, not the instance state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ttl_seconds
|
int
|
Time to live in seconds (default: 5 minutes). After this time, cached entries expire and the function is re-executed. |
300
|
maxsize
|
int
|
Maximum size of the cache (default: 100). When the cache is full, the least recently used entry is evicted. |
100
|
Returns:
| Type | Description |
|---|---|
Callable[[Callable[P, R]], CachedFunction[P, R]]
|
Decorated function with TTL caching and a clear_cache() method. |
Example
class DataService:
@ttl_cache_decorator(ttl_seconds=60, maxsize=50)
def fetch_data(self, key: str) -> dict:
# Expensive operation
return {"data": key}
service1 = DataService()
service2 = DataService()
# First call executes the function
result1 = service1.fetch_data("key1")
# Second call from different instance returns cached result
result2 = service2.fetch_data("key1") # From cache
# Clear cache manually
service1.fetch_data.clear_cache()
Note
- Exceptions are not cached; the function will be re-executed on the next call
- None values are cached like any other value
- Cache is shared across all instances of a class (not per-instance)
Source code in archipy/helpers/decorators/cache.py
options: show_root_toc_entry: false heading_level: 3
Retry¶
Decorator that automatically retries a failing function call with configurable backoff strategies.
archipy.helpers.decorators.retry.retry_decorator ¶
retry_decorator(
max_retries: int = 3,
delay: float = 1,
retry_on: tuple[type[Exception], ...] | None = None,
ignore: tuple[type[Exception], ...] | None = None,
resource_type: str | None = None,
) -> Callable[[Callable[P, R]], Callable[P, R]]
A decorator that retries a function when it raises an exception.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_retries
|
int
|
The maximum number of retry attempts. Defaults to 3. |
3
|
delay
|
float
|
The delay (in seconds) between retries. Defaults to 1. |
1
|
retry_on
|
Optional[Tuple[Type[Exception], ...]]
|
A tuple of errors to retry on. If None, retries on all errors. Defaults to None. |
None
|
ignore
|
Optional[Tuple[Type[Exception], ...]]
|
A tuple of errors to ignore (not retry on). If None, no errors are ignored. Defaults to None. |
None
|
resource_type
|
Optional[str]
|
The type of resource being exhausted. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[Callable[P, R]], Callable[P, R]]
|
The decorated function with retry logic. |
Example
To use this decorator, apply it to a function:
@retry_decorator(max_retries=3, delay=1, retry_on=(ValueError,), ignore=(TypeError,), resource_type="API")
def unreliable_function():
if random.random() < 0.5:
raise ValueError("Temporary failure")
return "Success"
result = unreliable_function()
Output:
Source code in archipy/helpers/decorators/retry.py
options: show_root_toc_entry: false heading_level: 3
Timeout¶
Decorator that enforces a maximum execution time on a function call.
archipy.helpers.decorators.timeout.timeout_decorator ¶
A decorator that adds a timeout to a function.
If the function takes longer than the specified number of seconds to execute, a DeadlineExceededException is raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
int
|
The maximum number of seconds the function is allowed to run. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[Callable[P, R]], Callable[P, R]]
|
The decorated function with a timeout. |
Example
To use this decorator, apply it to any function and specify the timeout in seconds:
@timeout_decorator(3) # Set a timeout of 3 seconds
def long_running_function():
time.sleep(5) # This will take longer than the timeout
return "Finished"
try:
result = long_running_function()
except DeadlineExceededException as e:
print(e) # Output: "Function long_running_function timed out after 3 seconds."
Output:
Source code in archipy/helpers/decorators/timeout.py
options: show_root_toc_entry: false heading_level: 3
Timing¶
Decorator that measures and records the execution time of a function.
archipy.helpers.decorators.timing.timing_decorator ¶
A decorator that measures the execution time of a function and logs it if the logging level is DEBUG.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
The function to be decorated. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[P, R]
|
The wrapped function which logs the execution time if the logging level is DEBUG. |
Example
To use this decorator, simply apply it to any function. For example:
@timing_decorator
def example_function(n: int) -> str:
time.sleep(n)
return f"Slept for {n} seconds"
result = example_function(2)
Output (if logging level is DEBUG):
Source code in archipy/helpers/decorators/timing.py
options: show_root_toc_entry: false heading_level: 3
Tracing¶
Decorator that adds distributed tracing instrumentation to a function.
Tracing decorators for capturing transactions and spans in pure Python applications.
This module provides decorators to instrument code with APM tracing when not using gRPC or FastAPI frameworks. Supports both Sentry and Elastic APM based on configuration.
archipy.helpers.decorators.tracing.capture_transaction ¶
capture_transaction(
name: str | None = None,
*,
op: str = "function",
description: str | None = None,
) -> Callable[[F], Callable[..., Any]]
Decorator to capture a transaction for the decorated function.
This decorator creates a transaction span around the execution of the decorated function. It integrates with both Sentry and Elastic APM based on the application configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Name of the transaction. If None, uses the function name. |
None
|
op
|
str
|
Operation type/category for the transaction. Defaults to "function". |
'function'
|
description
|
str | None
|
Optional description of the transaction. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[F], Callable[..., Any]]
|
The decorated function with transaction tracing capabilities. |
Example
Source code in archipy/helpers/decorators/tracing.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
archipy.helpers.decorators.tracing.capture_span ¶
capture_span(
name: str | None = None,
*,
op: str = "function",
description: str | None = None,
) -> Callable[[F], Callable[..., Any]]
Decorator to capture a span for the decorated function.
This decorator creates a span around the execution of the decorated function. Spans are child operations within a transaction and help provide detailed performance insights. Works with both Sentry and Elastic APM.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Name of the span. If None, uses the function name. |
None
|
op
|
str
|
Operation type/category for the span. Defaults to "function". |
'function'
|
description
|
str | None
|
Optional description of the span. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[F], Callable[..., Any]]
|
The decorated function with span tracing capabilities. |
Example
@capture_transaction(name="user_processing")
def process_user_data(user_id: int) -> dict[str, Any]:
user = get_user(user_id)
processed_data = transform_data(user)
save_result(processed_data)
return processed_data
@capture_span(name="database_query", op="db")
def get_user(user_id: int) -> dict[str, Any]:
# Database query logic here
return {"id": user_id, "name": "John"}
@capture_span(name="data_transformation", op="processing")
def transform_data(user: dict[str, Any]) -> dict[str, Any]:
# Data transformation logic
return {"processed": True, **user}
@capture_span(name="save_operation", op="db")
def save_result(data: dict[str, Any]) -> None:
# Save logic here
pass
Source code in archipy/helpers/decorators/tracing.py
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
options: show_root_toc_entry: false heading_level: 3
Singleton¶
Decorator that ensures a class is instantiated only once throughout the application lifecycle.
archipy.helpers.decorators.singleton.singleton_decorator ¶
A decorator to create thread-safe Singleton classes.
This decorator ensures that only one instance of a class is created. It supports an optional
thread_safe parameter to control whether thread-safety mechanisms (e.g., locks) should be used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thread_safe
|
bool
|
If True, enables thread-safety for instance creation. Defaults to True. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
function |
Callable[[type[Any]], Callable[..., Any]]
|
A decorator function that can be applied to a class. |
Example
To create a Singleton class, apply the singleton decorator and optionally specify
whether thread-safety should be enabled:
@singleton(thread_safe=True)
class MySingletonClass:
def __init__(self, value):
self.value = value
# Create instances of MySingletonClass
instance1 = MySingletonClass(10)
instance2 = MySingletonClass(20)
# Verify that both instances are the same
print(instance1.value) # Output: 10
print(instance2.value) # Output: 10
print(instance1 is instance2) # Output: True
Source code in archipy/helpers/decorators/singleton.py
options: show_root_toc_entry: false heading_level: 3
SQLAlchemy Atomic¶
Decorator that wraps a function in a SQLAlchemy database transaction, rolling back on failure.
SQLAlchemy atomic transaction decorators.
This module provides decorators for managing SQLAlchemy transactions with automatic commit/rollback and support for different database types (PostgreSQL, SQLite, StarRocks).
archipy.helpers.decorators.sqlalchemy_atomic.ATOMIC_BLOCK_CONFIGS
module-attribute
¶
ATOMIC_BLOCK_CONFIGS = {
"postgres": {
"flag": "in_postgres_sqlalchemy_atomic_block",
"registry": "archipy.adapters.postgres.sqlalchemy.session_manager_registry.PostgresSessionManagerRegistry",
},
"sqlite": {
"flag": "in_sqlite_sqlalchemy_atomic_block",
"registry": "archipy.adapters.sqlite.sqlalchemy.session_manager_registry.SQLiteSessionManagerRegistry",
},
"starrocks": {
"flag": "in_starrocks_sqlalchemy_atomic_block",
"registry": "archipy.adapters.starrocks.sqlalchemy.session_manager_registry.StarRocksSessionManagerRegistry",
},
}
archipy.helpers.decorators.sqlalchemy_atomic.sqlalchemy_atomic_decorator ¶
sqlalchemy_atomic_decorator(
db_type: str,
is_async: bool = False,
function: Callable[..., R] | None = None,
) -> Callable[..., R] | partial[Callable[..., Any]]
Factory for creating SQLAlchemy atomic transaction decorators.
This decorator ensures that a function runs within a database transaction for the specified database type. If the function succeeds, the transaction is committed; otherwise, it is rolled back. Supports both synchronous and asynchronous functions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db_type
|
str
|
The database type ("postgres", "sqlite", or "starrocks"). |
required |
is_async
|
bool
|
Whether the function is asynchronous. Defaults to False. |
False
|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., R] | partial[Callable[..., Any]]
|
Callable | partial: The wrapped function or a partial function for later use. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If an invalid db_type is provided. |
DatabaseSerializationError
|
If a serialization failure is detected. |
DatabaseDeadlockError
|
If an operational error occurs due to a deadlock. |
DatabaseTransactionError
|
If a transaction-related error occurs. |
DatabaseQueryError
|
If a query-related error occurs. |
DatabaseConnectionError
|
If a connection-related error occurs. |
DatabaseConstraintError
|
If a constraint violation is detected. |
DatabaseIntegrityError
|
If an integrity violation is detected. |
DatabaseTimeoutError
|
If a database operation times out. |
DatabaseConfigurationError
|
If there's an error in the database configuration. |
Example
Synchronous PostgreSQL example¶
@sqlalchemy_atomic_decorator(db_type="postgres") def update_user(id: int, name: str) -> None: # Database operations pass
Asynchronous SQLite example¶
@sqlalchemy_atomic_decorator(db_type="sqlite", is_async=True) async def update_record(id: int, data: str) -> None: # Async database operations pass
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | |
archipy.helpers.decorators.sqlalchemy_atomic.postgres_sqlalchemy_atomic_decorator ¶
postgres_sqlalchemy_atomic_decorator(
function: Callable[..., Any] | None = None,
) -> Callable[..., Any] | partial
Decorator for PostgreSQL atomic transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | partial
|
Callable | partial: The wrapped function or a partial function for later use. |
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
archipy.helpers.decorators.sqlalchemy_atomic.async_postgres_sqlalchemy_atomic_decorator ¶
async_postgres_sqlalchemy_atomic_decorator(
function: Callable[..., Any] | None = None,
) -> Callable[..., Any] | partial
Decorator for asynchronous PostgreSQL atomic transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | partial
|
Callable | partial: The wrapped function or a partial function for later use. |
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
archipy.helpers.decorators.sqlalchemy_atomic.sqlite_sqlalchemy_atomic_decorator ¶
sqlite_sqlalchemy_atomic_decorator(
function: Callable[..., Any] | None = None,
) -> Callable[..., Any] | partial
Decorator for SQLite atomic transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | partial
|
Callable | partial: The wrapped function or a partial function for later use. |
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
archipy.helpers.decorators.sqlalchemy_atomic.async_sqlite_sqlalchemy_atomic_decorator ¶
async_sqlite_sqlalchemy_atomic_decorator(
function: Callable[..., Any] | None = None,
) -> Callable[..., Any] | partial
Decorator for asynchronous SQLite atomic transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | partial
|
Callable | partial: The wrapped function or a partial function for later use. |
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
archipy.helpers.decorators.sqlalchemy_atomic.starrocks_sqlalchemy_atomic_decorator ¶
starrocks_sqlalchemy_atomic_decorator(
function: Callable[..., Any] | None = None,
) -> Callable[..., Any] | partial
Decorator for StarRocks atomic transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | partial
|
Callable | partial: The wrapped function or a partial function for later use. |
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
archipy.helpers.decorators.sqlalchemy_atomic.async_starrocks_sqlalchemy_atomic_decorator ¶
async_starrocks_sqlalchemy_atomic_decorator(
function: Callable[..., Any] | None = None,
) -> Callable[..., Any] | partial
Decorator for asynchronous StarRocks atomic transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
Callable | None
|
The function to wrap. If None, returns a partial function. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | partial
|
Callable | partial: The wrapped function or a partial function for later use. |
Source code in archipy/helpers/decorators/sqlalchemy_atomic.py
options: show_root_toc_entry: false heading_level: 3
Deprecation Warnings¶
Decorator that emits a deprecation warning when a decorated function or class is used.
archipy.helpers.decorators.deprecation_warnings.T
module-attribute
¶
archipy.helpers.decorators.deprecation_warnings.method_deprecation_warning ¶
method_deprecation_warning(
message: str | None = None,
) -> Callable[[Callable[P, R]], Callable[P, R]]
A decorator that issues a deprecation warning when the decorated method is called.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
The deprecation message to display when the method is called. Defaults to "This method is deprecated and will be removed in a future version." |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[Callable[P, R]], Callable[P, R]]
|
The decorated method that issues a deprecation warning. |
Example
To use this decorator, apply it to a method:
class MyClass:
@method_deprecation_warning("This method is deprecated and will be removed in a future version.")
def old_method(self):
return "This is the old method."
# Calling the method will issue a deprecation warning
obj = MyClass()
result = obj.old_method()
Output:
Source code in archipy/helpers/decorators/deprecation_warnings.py
archipy.helpers.decorators.deprecation_warnings.class_deprecation_warning ¶
A decorator that issues a deprecation warning when the decorated class is instantiated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
The deprecation message to display when the class is instantiated. Defaults to "This class is deprecated and will be removed in a future version." |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[T], T]
|
The decorated class that issues a deprecation warning. |
Example
To use this decorator, apply it to a class:
@class_deprecation_warning("This class is deprecated and will be removed in a future version.")
class OldClass:
def __init__(self):
pass
# Instantiating the class will issue a deprecation warning
obj = OldClass()
Output:
Source code in archipy/helpers/decorators/deprecation_warnings.py
options: show_root_toc_entry: false heading_level: 3
Deprecation Exception¶
Decorator that raises an exception when a deprecated function or class is called.
archipy.helpers.decorators.deprecation_exception.T
module-attribute
¶
archipy.helpers.decorators.deprecation_exception.method_deprecation_error ¶
method_deprecation_error(
operation: str | None = None,
lang: LanguageType = LanguageType.EN,
) -> Callable[[Callable[P, R]], Callable[P, R]]
Decorator that raises a DeprecationError when the decorated method is called.
This decorator is used to mark methods as deprecated and immediately prevent their use by raising a DeprecationError when they are called. This is stricter than a warning and ensures deprecated methods cannot be used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation
|
str
|
The name of the operation that is deprecated. Defaults to the name of the decorated method. |
None
|
lang
|
LanguageType
|
The language for the error message (default: "en"). |
EN
|
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[Callable[P, R]], Callable[P, R]]
|
The decorated method that raises a DeprecationException. |
Example
To use this decorator, apply it to a method:
class MyClass:
@method_deprecation_error(operation="old_method", lang=LanguageType.EN)
def old_method(self):
return "This is the old method."
# Calling the method will raise a DeprecationException
obj = MyClass()
result = obj.old_method()
Output:
Source code in archipy/helpers/decorators/deprecation_exception.py
archipy.helpers.decorators.deprecation_exception.class_deprecation_error ¶
class_deprecation_error(
operation: str | None = None,
lang: LanguageType = LanguageType.FA,
) -> Callable[[T], T]
A decorator that raises a DeprecationException when the decorated class is instantiated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation
|
str
|
The name of the operation that is deprecated. Defaults to the name of the decorated class. |
None
|
lang
|
str
|
The language for the error message (default: "fa"). |
FA
|
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[T], T]
|
The decorated class that raises a DeprecationException. |
Example
To use this decorator, apply it to a class:
@class_deprecation_error(operation="OldClass", lang="en")
class OldClass:
def __init__(self):
pass
# Instantiating the class will raise a DeprecationException
obj = OldClass()
Output:
Source code in archipy/helpers/decorators/deprecation_exception.py
options: show_root_toc_entry: false heading_level: 3