from sseclient import SSEClient as EventSource
import json
from collections import defaultdict
import threading

from ipywidgets import interact

from bokeh.io import push_notebook, show, output_notebook
from bokeh.plotting import figure
output_notebook()



def events(url):
    return (json.loads(event.data) for event in EventSource(url) 
            if event.event == 'message' and event.data)

wikis = {'enwiki': 0, 'dewiki': 1, 'eswiki': 2, 'ruwiki': 3}
wikiWhitelist = wikis.keys()

url = 'https://stream.wikimedia.org/v2/stream/recentchange'
eventsByWiki = defaultdict(int)

p = figure(plot_height=300, plot_width=800)
r = p.vbar(x=[1,2,3,4], width=0.5, bottom=0, top=[0,0,0,0], legend="Edits per wiki (enwiki, dewiki, eswiki, ruwiki)")
show(p, notebook_handle=True)


def updateData(wiki, value):
    r.data_source.data['top'][wikis[wiki]] = value

s = sched.scheduler(time.time, time.sleep)
def updatePlot():
    push_notebook()
    threading.Timer(1, updatePlot).start()

updatePlot()

edits = (e for e in events(url) if e['type'] == 'edit')
#edits = events(url)
for edit in edits:
    wiki = edit['wiki']
    if wiki in wikiWhitelist:
        eventsByWiki[wiki] += 1
        updateData(wiki, eventsByWiki[wiki])
Loading BokehJS ...
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-67-bb809eec846e> in <module>()
     39 edits = (e for e in events(url) if e['type'] == 'edit')
     40 #edits = events(url)
---> 41 for edit in edits:
     42     wiki = edit['wiki']
     43     if wiki in wikiWhitelist:

<ipython-input-67-bb809eec846e> in <genexpr>(.0)
     37 updatePlot()
     38 
---> 39 edits = (e for e in events(url) if e['type'] == 'edit')
     40 #edits = events(url)
     41 for edit in edits:

<ipython-input-67-bb809eec846e> in <genexpr>(.0)
     13 
     14 def events(url):
---> 15     return (json.loads(event.data) for event in EventSource(url) 
     16             if event.event == 'message' and event.data)
     17 

/srv/paws/lib/python3.4/site-packages/sseclient.py in __next__(self)
     62         while not self._event_complete():
     63             try:
---> 64                 nextline = self.resp_file.readline()
     65                 if not nextline:
     66                     raise EOFError()

/srv/paws/lib/python3.4/site-packages/requests/packages/urllib3/response.py in read(self, amt, decode_content, cache_content)
    378             else:
    379                 cache_content = False
--> 380                 data = self._fp.read(amt)
    381                 if amt != 0 and not data:  # Platform-specific: Buggy versions of Python.
    382                     # Close the connection when no data is returned

/usr/lib/python3.4/http/client.py in read(self, amt)
    498             # Amount is given, so call base class version
    499             # (which is implemented in terms of self.readinto)
--> 500             return super(HTTPResponse, self).read(amt)
    501         else:
    502             # Amount is not given (unbounded read) so we must check self.length

/usr/lib/python3.4/http/client.py in readinto(self, b)
    527 
    528         if self.chunked:
--> 529             return self._readinto_chunked(b)
    530 
    531         if self.length is not None:

/usr/lib/python3.4/http/client.py in _readinto_chunked(self, b)
    612             if chunk_left is None:
    613                 try:
--> 614                     chunk_left = self._read_next_chunk_size()
    615                     if chunk_left == 0:
    616                         break

/usr/lib/python3.4/http/client.py in _read_next_chunk_size(self)
    550     def _read_next_chunk_size(self):
    551         # Read the next chunk size from the file
--> 552         line = self.fp.readline(_MAXLINE + 1)
    553         if len(line) > _MAXLINE:
    554             raise LineTooLong("chunk size")

/usr/lib/python3.4/socket.py in readinto(self, b)
    369         while True:
    370             try:
--> 371                 return self._sock.recv_into(b)
    372             except timeout:
    373                 self._timeout_occurred = True

/usr/lib/python3.4/ssl.py in recv_into(self, buffer, nbytes, flags)
    743                   "non-zero flags not allowed in calls to recv_into() on %s" %
    744                   self.__class__)
--> 745             return self.read(nbytes, buffer)
    746         else:
    747             return socket.recv_into(self, buffer, nbytes, flags)

/usr/lib/python3.4/ssl.py in read(self, len, buffer)
    615         try:
    616             if buffer is not None:
--> 617                 v = self._sslobj.read(len, buffer)
    618             else:
    619                 v = self._sslobj.read(len or 1024)

KeyboardInterrupt: