duck.views¶
Duck view system.
This module defines the base View class, which serves as the foundation
for handling HTTP requests in the Duck web framework. Views process incoming
HttpRequest objects and return HttpResponse objects.
Developers can subclass View to define custom request handling logic by
overriding the run() method. This abstraction allows separation of business
logic from routing and middleware.
Module Contents¶
Classes¶
Base class for Duck views. |
Functions¶
Decorator for caching view outputs based on selected request attributes or computed callable results. |
|
Decorator that marks a view as exempt from CSRF middleware checks. |
Data¶
API¶
- duck.views.DEFAULT_VIEW_CACHE¶
‘InMemoryCache(…)’
- exception duck.views.SkipViewCaching[source]¶
Bases:
ExceptionThis is not an error as such but it’s just an interrupt for telling us that caching cannot proceed. This is usually when some data cannot be satisfied or some data is unavailable or broken.
Example:
Lets say user wants to cache views based on
USER IDbut the USER ID is unknown or invalid, user can just raiseSkipViewCachingexception to tell the system that caching is nolonger possible.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- class duck.views.View(request: duck.http.request.HttpRequest, **kwargs)[source]¶
Base class for Duck views.
Subclasses override run(self, request, **kwargs) to handle the request. The signature is fixed so views compose cleanly with decorators like
login_required.Initialization
Initialize the view.
- Parameters:
request – The incoming HTTP request.
**kwargs – Parameters extracted from the matched route.
- async async_dispatch() Any[source]¶
Asynchronously dispatch the view using its current request and route parameters.
- Returns:
The value returned by run().
- Return type:
Any
- dispatch() Any[source]¶
Dispatch the view using its current request and route parameters.
- Returns:
The value returned by run().
- Return type:
Any
- abstractmethod run(request: duck.http.request.HttpRequest, **kwargs) Optional[duck.http.response.HttpResponse][source]¶
Handle the request.
Subclasses must override this method.
- Parameters:
request – The incoming HTTP request.
**kwargs – Parameters extracted from the matched route.
- Returns:
The response generated by the view.
- Return type:
Optional[HttpResponse]
- exception duck.views.ViewCachingError[source]¶
Bases:
ExceptionRaised when the cached_view decorator fails.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- exception duck.views.ViewCachingWarning[source]¶
Bases:
UserWarningWarning that will be logged if user tries to cache a view which might cause issues.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- duck.views.cached_view(targets: Union[Dict[Union[str, Callable], Dict[str, Any]], List[str]], expiry: Optional[float] = None, cache_backend: Optional = None, namespace: Optional[Union[str, Callable]] = None, skip_cache_attr: str = 'skip_cache', on_cache_result: Optional[Callable] = None, returns_static_response: bool = False, freeze_if_component_response: bool = True)[source]¶
Decorator for caching view outputs based on selected request attributes or computed callable results.
This decorator supports:
Direct request attribute extraction.
Callable attributes on the request (with dynamic args/kwargs).
External Python callables used as cache-key producers.
Sync and async view handlers, including View.run methods.
Sync/async cache backends with automatic compatibility conversion.
The caching system guarantees stable, deterministic cache keys by converting all target values into a normalized (and hashable) structure.
- Parameters:
targets –
Defines which request attributes or computed callable results should contribute to the cache key.
List[str]: Direct request attribute lookups. Example: [“path”, “method”]
Dict[str or Callable, Dict[str, Any]]: Complex targets supporting: { “<request_attr_or_callable>”: {“args”: (…), “kwargs”: {…}} } { my_function: {“args”: (…), “kwargs”: {…}} }
Dynamic formatting is supported: “{request.path}” ➝ replaced at runtime.
expiry – TTL/expiry in seconds. If None, backend default TTL is used.
cache_backend – A cache backend implementing: get(key) set(key, value, ttl) Async backends or sync backends are both supported.
namespace –
Optional string or callable returning a namespace prefix for keys. Use
namespacefor grouping and easy bulk cache invalidation.Example:
@cached_view(targets=['path'], namespace=lambda request: request.COOKIES.get('user_id')) def handler(request): # Caches based on USER ID instead of global caching. return HttpResponse("OK")skip_cache_attr – Optional request attribute to skip caching (for debugging). Defaults to
skip_cache, meaning ifrequest.skip_cache=Truethen caching is skipped for that request.on_cache_result – Callable executed upon receiving a result from cache. Use this if some data needs to be reinitialized.
returns_static_response – By default, caching a view that returns a component or component response while
LivelyComponentSystemis active and not disabled on the target component may raiseViewCachingWarning. Setting this to True tells the system the component is static and safe from direct user-specific alteration, avoiding the warning.freeze_if_component_response – Whether to freeze the target component if the result is a component/component response. Boosts performance by >=50%, and only applies if
returns_static_response=True.
- Returns:
Wrapped view function with caching behavior.
- Return type:
Callable
- Raises:
ViewCachingError – Malformed target configuration, formatting errors, missing attributes, or errors inside computed callables.
Example:
from duck.views import View from duck.utils.performance import exec_time @cached_view(targets=["path"]) def handler(request): # View that will be cached based on request's path only. return HttpResponse("OK") class MyView(View): @cached_view(targets=["fullpath", "method"]) async def run(self, request, **kwargs): # View that will be cached based on request's path plus method. return HttpResponse("OK") exec(handler)() # Slow for the first time, prints more time exec_time(handler)() # Fast, prints less time. # Complex caching @cached_view(targets={"callable_request_attribute": {'args': "{request.path}"}) def handler_2(request): # View is cached based on request callable attribute. return HttpResponse("OK") @cached_view(targets={my_custom_function: {'args': "{request.path}"}) def handler_3(request): # View cached based on custom external function. return HttpResponse("OK")Notes:
Dynamic formatting (“{request.path}”) is supported everywhere.
Cache keys use stable frozenset+tuple structures for high hashing performance.
Custom callables receive: (request, *view_args, *resolved_args, **view_kwargs, **resolved_kwargs)
Works transparently on both synchronous and asynchronous views, and on View.run methods.
Sync cache backends are auto-wrapped for async views; async backends are auto-wrapped for sync views.
Callable targets may raise errors at runtime; these are wrapped into ViewCachingError.
When Lively Component System is active, caching Component or ComponentResponse will issue a safety warning to avoid state leakage across users.
targets=[] is not allowed ➝ caching requires at least one dimension of variation.
Namespace allows per-user, per-tenant, or per-feature cache isolation.
Setting
request.skip_cache = Truewill bypass caching.For callable targets, if caching can no longer proceed, e.g. some data is unavailable, raise
SkipViewCachingto tell the caching system that caching is not possible for this request.