With some modifications I got the sizing to work with @acw1668's suggestion
input_container = Frame( master = container_canvas )
window_id = container_canvas.create_window( ( 0, 0 ), window = input_container, anchor = 'nw' )
I then destroy any widget in _create_input_widgets, to rebuild when running this again
for child in input_container.winfo_children():
child.destroy()
With this addition to have the frame sized to its content:
canvas = self._input_widgets[ 'container_canvas' ]
max_height = int( canvas.cget( 'height' ) )
required_height = input_container.winfo_reqheight()
canvas.configure( height = min( required_height, 150 ) )