Skip to content

Commit a0e0599

Browse files
author
Dario Varotto
committed
Additional documentation and reference metadata methods
1 parent 04e73a1 commit a0e0599

File tree

8 files changed

+167
-24
lines changed

8 files changed

+167
-24
lines changed

README.md

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,96 @@ RavenPack API - Python client
33

44
A Python library to consume the [RavenPack API](https://www.ravenpack.com).
55

6-
[Access the documention here.](https://www.ravenpack.com/support/)
6+
[API documention.](https://www.ravenpack.com/support/)
77

88
## Installation
99

1010
pip install ravenpackapi
1111

12-
## Basic usage
12+
## About
1313

1414
The Python client helps managing the API calls to the RavenPack dataset server
1515
in a Pythonic way, here are some examples of usage, you can find more in the tests.
1616

17-
To use the API you need to have a RavenPack API KEY.
18-
1917
This is still a work in progress: while the API is stable we are still working
2018
on this Python wrapper.
19+
20+
## Usage
21+
22+
First, you'll need an API object that will deal with the API calls.
23+
24+
You will need a RavenPack API KEY, you can set the `RP_API_KEY` environment variable
25+
or set it in your code:
26+
27+
```python
28+
from ravenpackapi import RPApi
29+
30+
api = RPApi(api_key="YOUR_API_KEY")
31+
```
32+
33+
### Getting data from the datasets
34+
35+
There are several models to deal with data, the datasets are a cut of the RavenPack data
36+
they are defined with a set of filters and a set of fields.
37+
38+
```python
39+
# Get the dataset description from the server, here we use 'us30'
40+
# one of RavenPack public datasets with the top30 companies in the US
41+
42+
ds = api.get_dataset(dataset_id='us30')
43+
```
44+
#### Downloads: json
45+
46+
```python
47+
data = ds.json(
48+
start_date='2018-01-05 18:00:00',
49+
end_date='2018-01-05 18:01:00',
50+
)
51+
52+
for record in data:
53+
print(record)
54+
```
55+
56+
The json endpoint is handy for asking data synchronously, if you need to download big
57+
data chunks you may want to use the asynchronous datafile endpoint instead.
58+
59+
Json queries are limited to
60+
* granular datasets: 10,000 records
61+
* indicator datasets: 500 entities, timerange 1Y, lookback 1Y
62+
63+
#### Downloads: datafile
64+
65+
For bigger requests the datafile endpoint can be used.
66+
67+
Requesting a datafile, will give you back a job promise, that will take some time
68+
to complete.
69+
70+
```python
71+
job = ds.request_datafile(
72+
start_date='2018-01-05 18:00:00',
73+
end_date='2018-01-05 18:01:00',
74+
)
75+
76+
with open('output.csv') as fp:
77+
job.save_to_file(filename=fp.name)
78+
```
79+
80+
### Entity reference
81+
82+
The entity reference endpoint give you all the available information over an Entity
83+
starting from the RP_ENTITY_ID
84+
85+
```python
86+
ALPHABET_RP_ENTITY_ID = '4A6F00'
87+
88+
references = api.get_entity_reference(ALPHABET_RP_ENTITY_ID)
89+
90+
# show all the names over history
91+
for name in references.names:
92+
print(name.value, name.start, name.end)
93+
94+
# print all the ticket valid today
95+
for ticker in references.tickers:
96+
if ticker.is_valid():
97+
print(ticker)
98+
```

ravenpackapi/examples/query_entity_reference.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from ravenpackapi import RPApi
2-
import logging
32

4-
logging.basicConfig(level=logging.DEBUG)
53
# initialize the API (here we use the RP_API_KEY in os.environ)
64
api = RPApi()
75

@@ -13,3 +11,7 @@
1311
print(references)
1412
for name in references.names:
1513
print(name.value, name.start, name.end)
14+
15+
for ticker in references.tickers:
16+
if ticker.is_valid():
17+
print("Ticker:", ticker)

ravenpackapi/examples/query_with_json.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
api = RPApi()
77

88
# query the json endpoint for a dataset ***
9-
# use the public dataset with id 'us500'
10-
ds = api.get_dataset(dataset_id='us500')
9+
# use the public dataset with id 'us30'
10+
ds = api.get_dataset(dataset_id='us30')
1111
# query the dataset analytics with the json endpoint
12+
print(ds)
13+
1214
data = ds.json(
1315
start_date='2018-01-05 18:00:00',
1416
end_date='2018-01-05 18:01:00',

ravenpackapi/models/reference.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,33 @@
1-
import collections
1+
import datetime
2+
3+
from ravenpackapi.utils.date_formats import as_date
4+
5+
6+
class RPEntityMetadata(object):
7+
def __init__(self, value, start=None, end=None):
8+
super(RPEntityMetadata, self).__init__()
9+
self.value = value
10+
self.start = as_date(start)
11+
self.end = as_date(end)
12+
13+
def is_valid(self, when=None):
14+
""" Check that the metadata is valid at the given time (default to now)"""
15+
if when is None:
16+
when = datetime.date.today() # default to today
17+
when = as_date(when)
18+
19+
if self.start and when < self.start:
20+
return False
21+
if self.end and when >= self.end:
22+
return False
23+
return True
24+
25+
def __str__(self):
26+
return "Value: {value} - valid from {start} to {end}".format(
27+
**self.__dict__
28+
)
29+
230

3-
RPEntityMetadata = collections.namedtuple(
4-
'RPEntityMetadata', ['value', 'start', 'end']
5-
)
631
_MAPPED_FIELDS = {
732
# the fields here are singular, we use the plural attributes
833
# for returning a list of RPEntityMetadata
@@ -48,13 +73,10 @@ def __getattr__(self, field):
4873
else:
4974
return self.__getattribute__(field)
5075

51-
@property
52-
def tickers(self):
53-
return [
54-
RPEntityMetadata(d['data_value'],
55-
d['range_start'],
56-
d['range_end'])
57-
for d in self._data['ticker']
76+
def __dir__(self):
77+
""" Help autocompleting this additional fields """
78+
return list(super(RpEntityReference, self).__dir__()) + [
79+
k for k in _MAPPED_FIELDS
5880
]
5981

6082
def __repr__(self):

ravenpackapi/tests/test_datafile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from ravenpackapi.models.job import Job
77

88

9-
class TestDatafile:
9+
class TestDatafile(object):
1010
api = RPApi()
1111

1212
@pytest.mark.slow

ravenpackapi/tests/test_entity_reference.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import datetime
2+
13
from ravenpackapi import RPApi
24
from ravenpackapi.exceptions import APIException
5+
from ravenpackapi.models.reference import RPEntityMetadata
36

47
APPLE_RP_ENTITY_ID = 'D8442A'
58

@@ -20,3 +23,35 @@ def test_failing(self):
2023
assert False, "Invalid entity should raise an Exception"
2124
except APIException:
2225
pass
26+
27+
28+
class TestMetadataValidity():
29+
def test_specific_valid_range(self):
30+
md = RPEntityMetadata('year 1990',
31+
start=datetime.date(1990, 1, 1),
32+
end=datetime.date(1991, 1, 1))
33+
assert md.is_valid(when='1990-06-01')
34+
assert not md.is_valid(when='1991-01-01')
35+
assert not md.is_valid(when='1989-12-31')
36+
37+
def test_open_end(self):
38+
md = RPEntityMetadata('since 1990',
39+
start=datetime.date(1990, 1, 1),
40+
)
41+
assert not md.is_valid(when='1989-12-31')
42+
assert md.is_valid(when='1990-06-01')
43+
assert md.is_valid(when='1991-01-01')
44+
45+
def test_open_start(self):
46+
md = RPEntityMetadata('until 1990',
47+
end=datetime.date(1991, 1, 1),
48+
)
49+
assert md.is_valid(when='1989-12-31')
50+
assert md.is_valid(when='1990-06-01')
51+
assert not md.is_valid(when='1991-01-01')
52+
53+
def test_always_valid(self):
54+
md = RPEntityMetadata('always valid')
55+
assert md.is_valid(when='1989-12-31')
56+
assert md.is_valid(when='1990-06-01')
57+
assert md.is_valid(when='1991-01-01')

ravenpackapi/utils/date_formats.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import datetime
2+
3+
4+
def as_date(s):
5+
if isinstance(s, str):
6+
return datetime.datetime.strptime(s, '%Y-%m-%d').date()
7+
return s

setup.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,8 @@
2626

2727
# Specify the Python versions you support here. In particular, ensure
2828
# that you indicate whether you support Python 2, Python 3 or both.
29-
'Programming Language :: Python :: 2',
30-
'Programming Language :: Python :: 2.6',
3129
'Programming Language :: Python :: 2.7',
32-
'Programming Language :: Python :: 3',
33-
'Programming Language :: Python :: 3.4',
30+
'Programming Language :: Python :: 3.6.4',
3431
],
3532

3633
keywords='python analytics api rest news data',

0 commit comments

Comments
 (0)