Skip to content
This repository has been archived by the owner on Jun 15, 2024. It is now read-only.

Commit

Permalink
implement SSE streaming, add client and sse examples
Browse files Browse the repository at this point in the history
  • Loading branch information
timkpaine committed Jan 24, 2019
1 parent 62a5e03 commit aa5a432
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 19 deletions.
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,32 @@ Python interface to IEX Api (https://iextrading.com/developer/docs/)
[![Docs](https://img.shields.io/readthedocs/pyEX.svg)](https://pyEX.readthedocs.io)


### Attribution
## Attribution
If you redistribute our API data:

- Cite IEX using the following text and link: “Data provided for free by [IEX](https://iextrading.com/developer).”
- Provide a link to https://iextrading.com/api-exhibit-a in your terms of service.
- Additionally, if you display our TOPS price data, cite “IEX Real-Time Price” near the price.

### IEX Cloud attribution
## IEX Cloud attribution
[Powered by IEX Cloud](https://iexcloud.io)


### Version 2 API
[There is a new IEX API being developed](https://github.com/iexg/IEX-API/issues/557), so all development efforts will focus on that in the near term.

### Getting Started
# Getting Started

- [Read The Docs!](https://pyEX.readthedocs.io)
- [Demo Notebook](https://github.com/timkpaine/pyEX/blob/master/all.ipynb)
- [Demo Notebook - IEX](https://github.com/timkpaine/pyEX/blob/master/all.ipynb)
- [Streaming Notebook - IEX](https://github.com/timkpaine/pyEX/blob/master/ws.ipynb)
- [Demo Notebook - IEX Cloud](https://github.com/timkpaine/pyEX/blob/master/client.ipynb)
- [Streaming Notebook - IEX Cloud](https://github.com/timkpaine/pyEX/blob/master/sse.ipynb)


![](https://raw.githubusercontent.com/timkpaine/pyEX/master/docs/img/example1.gif)



### 6 Months of spy data in a dataframe in 2 lines:
## 6 Months of spy data in a dataframe in 2 lines:

```python
# fetch spy from website, clean for some bad formatted symbols
Expand All @@ -45,7 +46,3 @@ If you redistribute our API data:
# bulk fetch 6m of data
pyEX.bulkBatchDF(spy, ['chart'], _range='6m')['chart']
```


### Methods
[Notebook](https://github.com/timkpaine/pyEX/blob/master/all.ipynb)
191 changes: 191 additions & 0 deletions client.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Client\n",
"All methods from `all.ipynb` that are available on IEXcloud are available as methods on the authenticated client"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pyEX"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"c = pyEX.Client() # can pass token as argument or pick up from env"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Symbols data"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>date</th>\n",
" <th>iexId</th>\n",
" <th>isEnabled</th>\n",
" <th>name</th>\n",
" <th>type</th>\n",
" </tr>\n",
" <tr>\n",
" <th>symbol</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>A</th>\n",
" <td>2019-01-24</td>\n",
" <td>IEX_46574843354B2D52</td>\n",
" <td>True</td>\n",
" <td>Agilent Technologies, Inc.</td>\n",
" <td>cs</td>\n",
" </tr>\n",
" <tr>\n",
" <th>AA</th>\n",
" <td>2019-01-24</td>\n",
" <td>IEX_4238333734532D52</td>\n",
" <td>True</td>\n",
" <td>Alcoa Corp.</td>\n",
" <td>cs</td>\n",
" </tr>\n",
" <tr>\n",
" <th>AAAU</th>\n",
" <td>2019-01-24</td>\n",
" <td>IEX_474B433136332D52</td>\n",
" <td>True</td>\n",
" <td>Perth Mint Physical Gold ETF</td>\n",
" <td>et</td>\n",
" </tr>\n",
" <tr>\n",
" <th>AABA</th>\n",
" <td>2019-01-24</td>\n",
" <td>IEX_4E5434354A302D52</td>\n",
" <td>True</td>\n",
" <td>Altaba Inc.</td>\n",
" <td>cef</td>\n",
" </tr>\n",
" <tr>\n",
" <th>AAC</th>\n",
" <td>2019-01-24</td>\n",
" <td>IEX_4843364642592D52</td>\n",
" <td>True</td>\n",
" <td>AAC Holdings, Inc.</td>\n",
" <td>cs</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" date iexId isEnabled \\\n",
"symbol \n",
"A 2019-01-24 IEX_46574843354B2D52 True \n",
"AA 2019-01-24 IEX_4238333734532D52 True \n",
"AAAU 2019-01-24 IEX_474B433136332D52 True \n",
"AABA 2019-01-24 IEX_4E5434354A302D52 True \n",
"AAC 2019-01-24 IEX_4843364642592D52 True \n",
"\n",
" name type \n",
"symbol \n",
"A Agilent Technologies, Inc. cs \n",
"AA Alcoa Corp. cs \n",
"AAAU Perth Mint Physical Gold ETF et \n",
"AABA Altaba Inc. cef \n",
"AAC AAC Holdings, Inc. cs "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c.symbolsDF().head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['A', 'AA', 'AAAU', 'AABA', 'AAC', 'AADR', 'AAL', 'AAMC', 'AAME', 'AAN']"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pyEX.symbolsList()[:10]"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
1 change: 1 addition & 0 deletions pyEX/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
from .markets import * # noqa: F401,F403
from .marketdata.http import tops, topsDF, last, lastDF, hist, histDF, deep, deepDF, book as topsBook, bookDF as topsBookDF, trades, tradesDF, systemEvent, systemEventDF, tradingStatus, tradingStatusDF, opHaltStatus, opHaltStatusDF, ssrStatus, ssrStatusDF, securityEvent, securityEventDF, tradeBreak, tradeBreakDF, auction, auctionDF, officialPrice, officialPriceDF # noqa: F401, E501
from .marketdata.ws import * # noqa: F401,F403
from .marketdata.sse import * # noqa: F401,F403

__version__ = '0.1.7'
11 changes: 9 additions & 2 deletions pyEX/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
largestTrades, largestTradesDF, list, listDF, logo, logoPNG, logoNotebook, news, newsDF, marketNews, marketNewsDF, ohlc, ohlcDF, marketOhlc, marketOhlcDF, \
peers, peersDF, yesterday, yesterdayDF, marketYesterday, marketYesterdayDF, price, priceDF, quote, quoteDF, relevant, relevantDF, sectorPerformance, \
sectorPerformanceDF, splits, splitsDF, volumeByVenue, volumeByVenueDF
from .marketdata.sse import topsSSE, lastSSE, deepSSE, tradesSSE


_INCLUDE_FUNCTIONS = [
# Refdata
Expand Down Expand Up @@ -123,6 +125,11 @@
('splitsDF', splitsDF),
('volumeByVenue', volumeByVenue),
('volumeByVenueDF', volumeByVenueDF),
# SSE Streaming
('topsSSE', topsSSE),
('lastSSE', lastSSE),
('deepSSE', deepSSE),
('tradesSSE', tradesSSE),
]


Expand All @@ -136,8 +143,8 @@ def __init__(self, api_token=None, version='beta'):
for name, method in _INCLUDE_FUNCTIONS:
setattr(self, name, partial(self.bind, meth=method))

def bind(self, *args, meth=None):
return meth(token=self._token, version=self._version, *args)
def bind(self, *args, meth=None, **kwargs):
return meth(token=self._token, version=self._version, *args, **kwargs)

def account(self):
return _getJson('account/metadata', self._token, self._version)
Expand Down
34 changes: 29 additions & 5 deletions pyEX/common.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from __future__ import print_function
import requests
import json
try:
import ujson as json
except ImportError:
import json
import pandas as pd
from datetime import datetime
from socketIO_client_nexus import SocketIO, BaseNamespace
from sseclient import SSEClient
from six import string_types

try:
Expand All @@ -17,13 +21,15 @@
_SIO_URL_PREFIX = 'https://ws-api.iextrading.com'
_SIO_PORT = 443

_SSE_URL_PREFIX = 'https://cloud-sse.iexapis.com/{version}/{channel}?symbols={symbols}&token={token}'
_SSE_DEEP_URL_PREFIX = 'https://cloud-sse.iexapis.com/{version}/deep?symbols={symbols}&channels={channels}&token={token}'

_TIMEFRAME_CHART = ['5y', '2y', '1y', 'ytd', '6m', '3m', '1m', '1d']
_TIMEFRAME_DIVSPLIT = ['5y', '2y', '1y', 'ytd', '6m', '3m', '1m']
_LIST_OPTIONS = ['mostactive', 'gainers', 'losers', 'iexvolume', 'iexpercent']
_COLLECTION_TAGS = ['sector', 'tag', 'list']

_USAGE_TYPES = ['messages', 'rules', 'rule-records', 'alerts', 'alert-records']

_PYEX_PROXIES = None

# Limit 10
Expand Down Expand Up @@ -76,6 +82,10 @@
'lastUpdated']


class PyEXception(Exception):
pass


def _getJson(url, token='', version=''):
'''for backwards compat, accepting token and version but ignoring'''
if token:
Expand All @@ -94,7 +104,6 @@ def _getJsonOrig(url):
def _getJsonIEXCloud(url, token='', version='beta'):
'''for iex cloud'''
url = _URL_PREFIX2.format(version=version) + url
print(url)
resp = requests.get(urlparse(url).geturl(), proxies=_PYEX_PROXIES, params={'token': token})
if resp.status_code == 200:
return resp.json()
Expand All @@ -111,6 +120,11 @@ def _strToList(st):
return st


def _strCommaSeparatedString(st):
l = _strToList(st)
return ','.join(l)


def _strOrDate(st):
if isinstance(st, string_types):
return st
Expand Down Expand Up @@ -172,8 +186,18 @@ def _stream(url, sendinit=None, on_data=print):
return cl


class PyEXception(Exception):
pass
def _streamSSE(url, on_data=print, accrue=False):
messages = SSEClient(url)
if accrue:
ret = []

for msg in messages:
data = msg.data
on_data(json.loads(data))
if accrue:
ret.append(msg)

return ret


def _reindex(df, col):
Expand Down
Loading

0 comments on commit aa5a432

Please sign in to comment.