@@ -1220,6 +1220,7 @@ def __init__(self, root_session: Session, ns: ResolvedId) -> None:
12201220 ns = ns ,
12211221 outputs = root_session .output ._outputs ,
12221222 )
1223+ self .clientdata = ClientData (self )
12231224 self ._outbound_message_queues = root_session ._outbound_message_queues
12241225 self ._downloads = root_session ._downloads
12251226
@@ -1509,7 +1510,7 @@ class ClientData:
15091510
15101511 def __init__ (self , session : Session ) -> None :
15111512 self ._session : Session = session
1512- self ._current_renderer : Renderer [ Any ] | None = None
1513+ self ._current_output_name : ResolvedId | None = None
15131514
15141515 def url_hash (self ) -> str :
15151516 """
@@ -1559,7 +1560,7 @@ def pixelratio(self) -> float:
15591560 """
15601561 return cast (int , self ._read_input ("pixelratio" ))
15611562
1562- def output_height (self , id : Optional [str ] = None ) -> float | None :
1563+ def output_height (self , id : Optional [Id ] = None ) -> float | None :
15631564 """
15641565 Reactively read the height of an output.
15651566
@@ -1576,7 +1577,7 @@ def output_height(self, id: Optional[str] = None) -> float | None:
15761577 """
15771578 return cast (float , self ._read_output (id , "height" ))
15781579
1579- def output_width (self , id : Optional [str ] = None ) -> float | None :
1580+ def output_width (self , id : Optional [Id ] = None ) -> float | None :
15801581 """
15811582 Reactively read the width of an output.
15821583
@@ -1593,7 +1594,7 @@ def output_width(self, id: Optional[str] = None) -> float | None:
15931594 """
15941595 return cast (float , self ._read_output (id , "width" ))
15951596
1596- def output_hidden (self , id : Optional [str ] = None ) -> bool | None :
1597+ def output_hidden (self , id : Optional [Id ] = None ) -> bool | None :
15971598 """
15981599 Reactively read whether an output is hidden.
15991600
@@ -1609,7 +1610,7 @@ def output_hidden(self, id: Optional[str] = None) -> bool | None:
16091610 """
16101611 return cast (bool , self ._read_output (id , "hidden" ))
16111612
1612- def output_bg_color (self , id : Optional [str ] = None ) -> str | None :
1613+ def output_bg_color (self , id : Optional [Id ] = None ) -> str | None :
16131614 """
16141615 Reactively read the background color of an output.
16151616
@@ -1626,7 +1627,7 @@ def output_bg_color(self, id: Optional[str] = None) -> str | None:
16261627 """
16271628 return cast (str , self ._read_output (id , "bg" ))
16281629
1629- def output_fg_color (self , id : Optional [str ] = None ) -> str | None :
1630+ def output_fg_color (self , id : Optional [Id ] = None ) -> str | None :
16301631 """
16311632 Reactively read the foreground color of an output.
16321633
@@ -1643,7 +1644,7 @@ def output_fg_color(self, id: Optional[str] = None) -> str | None:
16431644 """
16441645 return cast (str , self ._read_output (id , "fg" ))
16451646
1646- def output_accent_color (self , id : Optional [str ] = None ) -> str | None :
1647+ def output_accent_color (self , id : Optional [Id ] = None ) -> str | None :
16471648 """
16481649 Reactively read the accent color of an output.
16491650
@@ -1660,7 +1661,7 @@ def output_accent_color(self, id: Optional[str] = None) -> str | None:
16601661 """
16611662 return cast (str , self ._read_output (id , "accent" ))
16621663
1663- def output_font (self , id : Optional [str ] = None ) -> str | None :
1664+ def output_font (self , id : Optional [Id ] = None ) -> str | None :
16641665 """
16651666 Reactively read the font(s) of an output.
16661667
@@ -1681,56 +1682,50 @@ def _read_input(self, key: str) -> str:
16811682 self ._check_current_context (key )
16821683
16831684 id = ResolvedId (f".clientdata_{ key } " )
1684- if id not in self ._session .input :
1685+ if id not in self ._session .root_scope (). input :
16851686 raise ValueError (
16861687 f"ClientData value '{ key } ' not found. Please report this issue."
16871688 )
16881689
1689- return self ._session .input [id ]()
1690+ return self ._session .root_scope (). input [id ]()
16901691
1691- def _read_output (self , id : str | None , key : str ) -> str | None :
1692+ def _read_output (self , id : Id | None , key : str ) -> str | None :
16921693 self ._check_current_context (f"output_{ key } " )
16931694
1694- if id is None and self ._current_renderer is not None :
1695- id = self ._current_renderer .output_id
1695+ # No `id` provided support
1696+ if id is None and self ._current_output_name is not None :
1697+ id = self ._current_output_name
16961698
16971699 if id is None :
16981700 raise ValueError (
16991701 "session.clientdata.output_*() requires an id when not called within "
17001702 "an output renderer."
17011703 )
17021704
1705+ # Module support
1706+ if not isinstance (id , ResolvedId ):
1707+ id = self ._session .ns (id )
1708+
17031709 input_id = ResolvedId (f".clientdata_output_{ id } _{ key } " )
1704- if input_id in self ._session .input :
1705- return self ._session .input [input_id ]()
1710+ if input_id in self ._session .root_scope (). input :
1711+ return self ._session .root_scope (). input [input_id ]()
17061712 else :
17071713 return None
17081714
17091715 @contextlib .contextmanager
1710- def _renderer_ctx (self , renderer : Renderer [ Any ] ) -> Generator [None , None , None ]:
1716+ def _output_name_ctx (self , output_name : ResolvedId ) -> Generator [None , None , None ]:
17111717 """
1712- Context manager to temporarily set the current renderer .
1718+ Context manager to temporarily set the output name .
17131719
17141720 This is used to allow `session.clientdata.output_*()` methods to access the
1715- current renderer's output id without needing to pass it explicitly.
1716-
1717- Parameters
1718- ----------
1719- renderer
1720- The renderer to set as the current renderer.
1721-
1722- Yields
1723- ------
1724- None
1725- The context manager does not return any value, but temporarily sets the
1726- current renderer to the provided renderer.
1721+ current output name without needing to pass it explicitly.
17271722 """
1728- old_renderer = self ._current_renderer
1723+ old_output_name = self ._current_output_name
17291724 try :
1730- self ._current_renderer = renderer
1725+ self ._current_output_name = output_name
17311726 yield
17321727 finally :
1733- self ._current_renderer = old_renderer
1728+ self ._current_output_name = old_output_name
17341729
17351730 @staticmethod
17361731 def _check_current_context (key : str ) -> None :
@@ -1836,7 +1831,7 @@ async def output_obs():
18361831 )
18371832
18381833 try :
1839- with session .clientdata ._renderer_ctx ( renderer ):
1834+ with session .clientdata ._output_name_ctx ( output_name ):
18401835 # Call the app's renderer function
18411836 value = await renderer .render ()
18421837
0 commit comments