Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- [#3407](https://github.com/plotly/dash/pull/3407) Add `hidden` to callback arguments, hiding the callback from appearing in the devtool callback graph.
- [#3424](https://github.com/plotly/dash/pull/3424) Adds support for `Patch` on clientside callbacks class `dash_clientside.Patch`, as well as supporting side updates, eg: (Running, SetProps).
- [#3347](https://github.com/plotly/dash/pull/3347) Added 'api_endpoint' to `callback` to expose api endpoints at the provided path for use to be executed directly without dash.
- [#3452](https://github.com/plotly/dash/issues/3452) Add `CompressionManager` parameter to callback decorators enabling automatic server-side compression/decompression of dcc.Store component data. Supports Gzip, Deflate, and Brotli compression algorithms with configurable compression levels and size thresholds to reduce network payload sizes for large data transfers.

## Fixed
- [#3395](https://github.com/plotly/dash/pull/3395) Fix Components added through set_props() cannot trigger related callback functions. Fix [#3316](https://github.com/plotly/dash/issues/3316)
Expand Down
31 changes: 31 additions & 0 deletions dash/_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from .background_callback.managers import BaseBackgroundCallbackManager
from ._callback_context import context_value
from ._no_update import NoUpdate
from ._compression import get_compression_manager_from_kwargs


async def _async_invoke_callback(
Expand Down Expand Up @@ -279,6 +280,7 @@ def insert_callback(
no_output=False,
optional=False,
hidden=False,
compression_manager=None,
):
if prevent_initial_call is None:
prevent_initial_call = config_prevent_initial_callbacks
Expand Down Expand Up @@ -319,6 +321,7 @@ def insert_callback(
"manager": manager,
"allow_dynamic_callbacks": dynamic_creator,
"no_output": no_output,
"compression_manager": compression_manager,
}
callback_list.append(callback_spec)

Expand Down Expand Up @@ -653,6 +656,7 @@ def register_callback(
no_output=not has_output,
optional=_kwargs.get("optional", False),
hidden=_kwargs.get("hidden", False),
compression_manager=get_compression_manager_from_kwargs(_kwargs),
)

# pylint: disable=too-many-locals
Expand All @@ -670,6 +674,9 @@ def wrap_func(func):
callback_id,
)

# Get compression manager for this callback
compression_manager = get_compression_manager_from_kwargs(_kwargs)

@wraps(func)
def add_context(*args, **kwargs):
"""Handles synchronous callbacks with context management."""
Expand All @@ -687,6 +694,12 @@ def add_context(*args, **kwargs):
args, kwargs, inputs_state_indices, has_output, insert_output
)

# Decompress inputs if compression manager is available
if compression_manager:
func_args = compression_manager.decompress_callback_inputs(
func_args, inputs_state_indices
)

response: dict = {"multi": True}

jsonResponse = None
Expand Down Expand Up @@ -720,6 +733,12 @@ def add_context(*args, **kwargs):
else:
raise err

# Compress outputs if compression manager is available
if compression_manager:
output_value = compression_manager.compress_callback_outputs(
output_value, output_spec
)

_prepare_response(
output_value,
output_spec,
Expand Down Expand Up @@ -759,6 +778,12 @@ async def async_add_context(*args, **kwargs):
args, kwargs, inputs_state_indices, has_output, insert_output
)

# Decompress inputs if compression manager is available
if compression_manager:
func_args = compression_manager.decompress_callback_inputs(
func_args, inputs_state_indices
)

response: dict = {"multi": True}

try:
Expand Down Expand Up @@ -792,6 +817,12 @@ async def async_add_context(*args, **kwargs):
else:
raise err

# Compress outputs if compression manager is available
if compression_manager:
output_value = compression_manager.compress_callback_outputs(
output_value, output_spec
)

_prepare_response(
output_value,
output_spec,
Expand Down
Loading