Skip to content

Commit

Permalink
Initial SSEClient implementation and files
Browse files Browse the repository at this point in the history
Signed-off-by: Maxime Petazzoni <maxime.petazzoni@bulix.org>
  • Loading branch information
mpetazzoni committed Mar 11, 2016
1 parent 5d38271 commit e435477
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bdist_wheel]
universal = 1
27 changes: 27 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python

# Copyright (C) 2016 SignalFx, Inc. All rights reserved.

from setuptools import setup, find_packages

from sseclient.version import name, version

with open('README.md') as readme:
long_description = readme.read()

setup(
name=name,
version=version,
author='Maxime Petazzoni',
author_email='maxime.petazzoni@bulix.org',
description='SSE client for Python',
license='Apache Software License v2',
long_description=long_description,
zip_safe=True,
packages=find_packages(),
classifiers=[
'Operating System :: OS Independent',
'Programming Language :: Python',
],
url='https://github.com/mpetazzoni/sseclient',
)
17 changes: 17 additions & 0 deletions sseclient/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Server Side Events (SSE) client for Python.
Provides a generator of SSE received through an existing HTTP response.
"""

# Copyright (C) 2016 SignalFx, Inc. All rights reserved.

import client


__author__ = 'Maxime Petazzoni <maxime.petazzoni@bulix.org>'
__email__ = 'maxime.petazzoni@bulix.org'
__copyright__ = 'Copyright (C) 2016 SignalFx, Inc. All rights reserved.'
__all__ = ['SSEClient']

SSEClient = client.SSEClient
75 changes: 75 additions & 0 deletions sseclient/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright (C) 2016 SignalFx, Inc. All rights reserved.

_FIELD_SEPARATOR = ':'


class SSEClient(object):
"""Implementation of a SSE client.
See http://www.w3.org/TR/2009/WD-eventsource-20091029/ for the
specification.
"""

def __init__(self, stream):
"""Initialize the SSE client over an existing, ready to consume
response stream."""
self._stream = stream

def events(self):
for chunk in self._stream:
event = {}
for line in chunk.splitlines():
# Lines starting with a separator are to be ignored.
if line.startswith(_FIELD_SEPARATOR):
continue

data = line.split(_FIELD_SEPARATOR, 1)
field = data[0]

# Spaces may occur before the value; strip them. If no value is
# present after the separator, assume an empty value.
value = data[1].lstrip() if len(data) > 1 else ''

# The data field may come over multiple lines and their values
# are concatenated with each other.
if field == 'data' and field in event:
event[field] += value
else:
event[field] = value

# Events with no data are not dispatched.
if 'data' not in event or not event['data']:
continue

# If the data field ends with a newline, remove it.
if event['data'].endswith('\n'):
event['data'] = event['data'][0:-1]

# Dispatch the event
yield Event(**event)


class Event(object):
"""Representation of an event from the event stream."""

def __init__(self, id=None, event='message', data='', retry=None):
self._id = id
self._event = event
self._data = data
self._retry = retry

@property
def id(self):
return self._id

@property
def event(self):
return self._event

@property
def data(self):
return self._data

@property
def retry(self):
return self._data
2 changes: 2 additions & 0 deletions sseclient/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = 'sseclient'
version = '1.0'

0 comments on commit e435477

Please sign in to comment.