@tmzhuang
The column data sources are not properties of the figure but rather the glyphs rendered in the figure.
I looked at the code snippet you provided, and it looks very well-written but in the interest of time, I chose to assemble a very small example of how to accomplish your goal so you can extend and integrate as it best fits into your larger application.
Here’s an illustrative example of adding hover tools that are effectively associated with the spans, and separate column data sources attached to populate with information of interest.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
"""
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, Span, HoverTool
p = figure(width=400, height=300, x_range=(0.0,1.0), y_range=(0.0,1.0))
p.line(x=[0.0,1.0], y=[0.5,0.5])
# Spans
data = dict(x=[1./3.,2./3.], ev=['Something interesting happened here...','Here too...'])
source = ColumnDataSource(data=data)
S = [Span(location=x, dimension='height', line_color='#ff0000', line_alpha=0.2) for x in data['x']]
_ = [p.add_layout(s) for s in S]
# Hover tool support for spans
r = p.circle(x='x', y=0.5, source=source, size=30, alpha=0.0)
h = HoverTool(renderers=[r], tooltips=({'x': '@x', 'Event': '@ev'}), mode='vline')
p.add_tools(h)
show(p)