mindseye-lite / streamlit_nested_expanders.py
apolinario's picture
Make it slim
4b8c314
raw history blame
No virus
2.51 kB
from typing import Optional, Iterable
import streamlit as st
from streamlit import cursor
from streamlit.report_thread import get_report_ctx as get_script_run_ctx
#from streamlit.script_run_context import get_script_run_ctx
from streamlit.errors import NoSessionContext
from streamlit.proto import Block_pb2
from streamlit.proto import ForwardMsg_pb2
from streamlit.elements.form import FormData, current_form_id
from streamlit.delta_generator import DeltaGenerator
def _block(self, block_proto=Block_pb2.Block()) -> "DeltaGenerator":
# Operate on the active DeltaGenerator, in case we're in a `with` block.
dg = self._active_dg
# Prevent nested columns & expanders by checking all parents.
block_type = block_proto.WhichOneof("type")
# Convert the generator to a list, so we can use it multiple times.
parent_block_types = frozenset(dg._parent_block_types)
# if block_type == "column" and block_type in parent_block_types:
# raise StreamlitAPIException("Columns may not be nested inside other columns.")
# if block_type == "expandable" and block_type in parent_block_types:
# raise StreamlitAPIException(
# "Expanders may not be nested inside other expanders."
# )
if dg._root_container is None or dg._cursor is None:
return dg
msg = ForwardMsg_pb2.ForwardMsg()
msg.metadata.delta_path[:] = dg._cursor.delta_path
msg.delta.add_block.CopyFrom(block_proto)
# Normally we'd return a new DeltaGenerator that uses the locked cursor
# below. But in this case we want to return a DeltaGenerator that uses
# a brand new cursor for this new block we're creating.
block_cursor = cursor.RunningCursor(
root_container=dg._root_container,
parent_path=dg._cursor.parent_path + (dg._cursor.index,),
)
block_dg = DeltaGenerator(
root_container=dg._root_container,
cursor=block_cursor,
parent=dg,
block_type=block_type,
)
# Blocks inherit their parent form ids.
# NOTE: Container form ids aren't set in proto.
block_dg._form_data = FormData(current_form_id(dg))
# Must be called to increment this cursor's index.
dg._cursor.get_locked_cursor(last_index=None)
_enqueue_message(msg)
return block_dg
def _enqueue_message(msg):
"""Enqueues a ForwardMsg proto to send to the app."""
ctx = get_script_run_ctx()
if ctx is None:
raise NoSessionContext()
ctx.enqueue(msg)
DeltaGenerator._block = _block