Skip to content

Commit 91dda56

Browse files
authored
Merge branch 'master' into cln_080
2 parents edf4e73 + 127d63a commit 91dda56

File tree

12 files changed

+181
-23
lines changed

12 files changed

+181
-23
lines changed

docs/source/readers/econdb.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Econdb
2+
--------
3+
4+
.. py:module:: pandas_datareader.econdb
5+
6+
.. autoclass:: EcondbReader
7+
:members:
8+
:inherited-members:

docs/source/readers/enigma.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Engima
1+
Enigma
22
------
33

44
.. py:module:: pandas_datareader.enigma

docs/source/readers/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ Data Readers
88
fred
99
famafrench
1010
bank-of-canada
11+
econdb
1112
enigma
1213
eurostat
1314
iex
1415
moex
1516
nasdaq-trader
1617
oecd
1718
quandl
18-
robinhood
1919
stooq
2020
tiingo
2121
tsp

docs/source/remote_data.rst

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ Remote Data Access
1818
******************
1919

2020

21+
.. warning::
22+
23+
Robinhood has been immediately deprecated. Endpoints from this provider
24+
have been retired.
25+
2126
.. _remote_data.data_reader:
2227

2328
Functions from :mod:`pandas_datareader.data` and :mod:`pandas_datareader.wb`
@@ -26,7 +31,6 @@ Currently the following sources are supported:
2631

2732
- :ref:`Tiingo<remote_data.tiingo>`
2833
- :ref:`IEX<remote_data.iex>`
29-
- :ref:`Robinhood<remote_data.robinhood>`
3034
- :ref:`Alpha Vantage<remote_data.alphavantage>`
3135
- :ref:`Enigma<remote_data.enigma>`
3236
- :ref:`Quandl<remote_data.quandl>`
@@ -91,21 +95,6 @@ A third interface to the deep API is exposed through
9195
f[:10]
9296
9397
94-
.. _remote_data.robinhood:
95-
96-
Robinhood
97-
=========
98-
`Robinhood <https://www.robinhood.com>`__ is a stock trading platform with an
99-
API that provides a limited set of data. Historical daily data is limited to 1
100-
year relative to today.
101-
102-
.. ipython:: python
103-
104-
import pandas_datareader.data as web
105-
from datetime import datetime
106-
f = web.DataReader('F', 'robinhood')
107-
f.head()
108-
10998
.. _remote_data.alphavantage:
11099

111100
Alpha Vantage
@@ -208,6 +197,23 @@ performances through the top-level function ``get_sector_performance_av``.
208197
209198
.. _remote_data.enigma:
210199

200+
Econdb
201+
======
202+
203+
`Econdb <https://www.econdb.com>`__ provides economic data from 90+
204+
official statistical agencies. Free API allows access to the complete
205+
Econdb database of time series aggregated into datasets.
206+
207+
.. ipython:: python
208+
209+
import os
210+
import pandas_datareader.data as web
211+
212+
f = web.DataReader('ticker=RGDPQNO', 'econdb')
213+
f.head()
214+
215+
.. _remote_data.econdb:
216+
211217
Enigma
212218
======
213219

docs/source/whatsnew/v0.8.0.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ v0.8.0 (TBD)
55

66
Highlights include:
77

8-
8+
- A new connector for Econdb was introduced. Econdb provides
9+
aggregated economic data from 90+ official statistical agencies
10+
(:issue:`615`)
911
- Removal of Google finance and Morningstar, which were deprecated in 0.7.0.
12+
- Immediate deprecation of Robinhood for quotes and historical data. Robinhood
13+
ended support for these endpoints in 1/2019
14+
1015

1116
.. contents:: What's new in v0.8.0
1217
:local:
@@ -24,6 +29,9 @@ Enhancements
2429
Backwards incompatible API changes
2530
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2631

32+
- Immediate deprecation of Robinhood for quotes and historical data. Robinhood
33+
ended support for these endpoints in 1/2019. The Robinhood quotes and daily
34+
readers will raise an ``ImmediateDeprecationError`` when called.
2735

2836

2937
.. _whatsnew_080.bug_fixes:

pandas_datareader/av/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def __init__(self, symbols=None, start=None, end=None, retry_count=3,
2828
if not api_key or not isinstance(api_key, str):
2929
raise ValueError('The AlphaVantage API key must be provided '
3030
'either through the api_key variable or '
31-
'through the environment varaible '
31+
'through the environment variable '
3232
'ALPHAVANTAGE_API_KEY')
3333
self.api_key = api_key
3434

pandas_datareader/data.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pandas_datareader.av.sector import AVSectorPerformanceReader
1010
from pandas_datareader.av.time_series import AVTimeSeriesReader
1111
from pandas_datareader.bankofcanada import BankOfCanadaReader
12+
from pandas_datareader.econdb import EcondbReader
1213
from pandas_datareader.enigma import EnigmaReader
1314
from pandas_datareader.eurostat import EurostatReader
1415
from pandas_datareader.exceptions import DEP_ERROR_MSG, \
@@ -292,7 +293,7 @@ def DataReader(name, data_source=None, start=None, end=None,
292293
"tiingo", "yahoo-actions", "yahoo-dividends",
293294
"av-forex", "av-daily", "av-daily-adjusted",
294295
"av-weekly", "av-weekly-adjusted", "av-monthly",
295-
"av-monthly-adjusted"]
296+
"av-monthly-adjusted", "econdb"]
296297

297298
if data_source not in expected_source:
298299
msg = "data_source=%r is not implemented" % data_source
@@ -438,6 +439,11 @@ def DataReader(name, data_source=None, start=None, end=None,
438439
retry_count=retry_count, pause=pause,
439440
session=session, api_key=access_key).read()
440441

442+
elif data_source == "econdb":
443+
return EcondbReader(symbols=name, start=start, end=end,
444+
retry_count=retry_count, pause=pause,
445+
session=session).read()
446+
441447
else:
442448
msg = "data_source=%r is not implemented" % data_source
443449
raise NotImplementedError(msg)

pandas_datareader/econdb.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import requests
2+
import pandas as pd
3+
import pandas.compat as compat
4+
5+
from pandas_datareader.base import _BaseReader
6+
7+
8+
class EcondbReader(_BaseReader):
9+
"""Get data for the given name from Econdb."""
10+
11+
_URL = 'https://www.econdb.com/api/series/'
12+
_format = None
13+
_show = 'labels'
14+
15+
@property
16+
def url(self):
17+
"""API URL"""
18+
if not isinstance(self.symbols, compat.string_types):
19+
raise ValueError('data name must be string')
20+
21+
return ('{0}?{1}&format=json&page_size=500&expand=meta'
22+
.format(self._URL, self.symbols))
23+
24+
def read(self):
25+
""" read one data from specified URL """
26+
results = requests.get(self.url).json()['results']
27+
df = pd.DataFrame({'dates': []}).set_index('dates')
28+
29+
for entry in results:
30+
head = entry['additional_metadata']
31+
series = (pd.DataFrame(entry['data'])[['dates', 'values']]
32+
.set_index('dates'))
33+
if self._show == 'labels':
34+
def show_func(x): return x.split(':')[1]
35+
elif self._show == 'codes':
36+
def show_func(x): return x.split(':')[0]
37+
38+
series.columns = pd.MultiIndex.from_tuples(
39+
[[show_func(x) for x in head.values()]],
40+
names=[show_func(x) for x in head.keys()])
41+
42+
if not df.empty:
43+
df = df.join(series, how='outer')
44+
else:
45+
df = series
46+
df.index = pd.to_datetime(df.index, errors='ignore')
47+
df.index.name = 'TIME_PERIOD'
48+
df = df.truncate(self.start, self.end)
49+
return df

pandas_datareader/robinhood.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import pandas as pd
22

33
from pandas_datareader.base import _BaseReader
4+
from pandas_datareader.exceptions import (ImmediateDeprecationError,
5+
DEP_ERROR_MSG)
46

57

68
class RobinhoodQuoteReader(_BaseReader):
79
"""
810
Read quotes from Robinhood
911
12+
DEPRECATED 1/2019 - Robinhood ended support for the endpoints used by this
13+
reader
14+
1015
Parameters
1116
----------
1217
symbols : {str, List[str]}
@@ -28,6 +33,7 @@ class RobinhoodQuoteReader(_BaseReader):
2833

2934
def __init__(self, symbols, start=None, end=None, retry_count=3, pause=.1,
3035
timeout=30, session=None, freq=None):
36+
raise ImmediateDeprecationError(DEP_ERROR_MSG.format("Robinhood"))
3137
super(RobinhoodQuoteReader, self).__init__(symbols, start, end,
3238
retry_count, pause,
3339
timeout, session, freq)
@@ -72,6 +78,9 @@ class RobinhoodHistoricalReader(RobinhoodQuoteReader):
7278
"""
7379
Read historical values from Robinhood
7480
81+
DEPRECATED 1/2019 - Robinhood ended support for the endpoints used by this
82+
reader
83+
7584
Parameters
7685
----------
7786
symbols : {str, List[str]}
@@ -110,6 +119,7 @@ class RobinhoodHistoricalReader(RobinhoodQuoteReader):
110119
def __init__(self, symbols, start=None, end=None, retry_count=3, pause=.1,
111120
timeout=30, session=None, freq=None, interval='day',
112121
span='year'):
122+
raise ImmediateDeprecationError(DEP_ERROR_MSG.format("Robinhood"))
113123
super(RobinhoodHistoricalReader, self).__init__(symbols, start, end,
114124
retry_count, pause,
115125
timeout, session, freq)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import numpy as np
2+
import pandas as pd
3+
import pandas.util.testing as tm
4+
import pandas_datareader.data as web
5+
6+
7+
class TestEcondb(object):
8+
9+
def test_get_cdh_e_fos(self):
10+
# EUROSTAT
11+
# Employed doctorate holders in non managerial and non professional
12+
# occupations by fields of science (%)
13+
df = web.DataReader(
14+
'dataset=CDH_E_FOS&GEO=NO,PL,PT,RU&FOS07=FOS1&Y_GRAD=TOTAL',
15+
'econdb',
16+
start=pd.Timestamp('2005-01-01'),
17+
end=pd.Timestamp('2010-01-01'))
18+
assert isinstance(df, pd.DataFrame)
19+
assert df.shape == (2, 4)
20+
21+
df = df['Natural sciences']['Annual'][
22+
['Norway', 'Poland', 'Portugal', 'Russia']]
23+
24+
exp_col = pd.MultiIndex.from_product(
25+
[['Norway', 'Poland', 'Portugal', 'Russia'],
26+
['Percentage'], ['Total']],
27+
names=['Geopolitical entity (reporting)', 'Unit of measure',
28+
'Year of graduation'])
29+
exp_idx = pd.DatetimeIndex(['2006-01-01', '2009-01-01'],
30+
name='TIME_PERIOD')
31+
32+
values = np.array([[25.49, np.nan, 39.05, np.nan],
33+
[20.38, 25.1, 27.77, 38.1]])
34+
expected = pd.DataFrame(values, index=exp_idx, columns=exp_col)
35+
tm.assert_frame_equal(df, expected)
36+
37+
def test_get_tourism(self):
38+
# OECD
39+
# TOURISM_INBOUND
40+
41+
df = web.DataReader(
42+
'dataset=OE_TOURISM_INBOUND&COUNTRY=JPN,USA&'
43+
'VARIABLE=INB_ARRIVALS_TOTAL', 'econdb',
44+
start=pd.Timestamp('2008-01-01'), end=pd.Timestamp('2012-01-01'))
45+
df = df.astype(np.float)
46+
jp = np.array([8351000, 6790000, 8611000, 6219000,
47+
8368000], dtype=float)
48+
us = np.array([175702309, 160507417, 164079732, 167600277,
49+
171320408], dtype=float)
50+
index = pd.date_range('2008-01-01', '2012-01-01', freq='AS',
51+
name='TIME_PERIOD')
52+
for label, values in [('Japan', jp), ('United States', us)]:
53+
expected = pd.Series(values, index=index,
54+
name='Total international arrivals')
55+
tm.assert_series_equal(df[label]['Total international arrivals'],
56+
expected)
57+
58+
def test_bls(self):
59+
# BLS
60+
# CPI
61+
df = web.DataReader(
62+
'ticker=BLS_CU.CUSR0000SA0.M.US', 'econdb',
63+
start=pd.Timestamp('2010-01-01'), end=pd.Timestamp('2013-01-27'))
64+
65+
assert df.loc['2010-05-01'][0] == 217.3

0 commit comments

Comments
 (0)