Skip to content

Commit 266387c

Browse files
authored
Merge pull request #150 from SteadBytes/cached-datasets
Cached Datasets Support
2 parents 18c0d79 + 25f839d commit 266387c

File tree

4 files changed

+585
-1
lines changed

4 files changed

+585
-1
lines changed

README.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,85 @@ You can manage your `saved queries <https://keen.io/docs/api/?shell#saved-querie
406406
# Delete a saved query (use the new resource name since we just changed it)
407407
client.saved_queries.delete("cached-query-name")
408408
409+
Cached Datasets
410+
'''''''''''''''
411+
.. code-block:: python
412+
413+
# Create your KeenClient
414+
from keen.client import KeenClient
415+
416+
client = KeenClient(
417+
project_id="xxxx", # your project ID
418+
read_key="zzzz",
419+
master_key="abcd"
420+
)
421+
422+
# Create a Cached Dataset
423+
dataset_name = "NEW_DATASET"
424+
display_name = "My new dataset"
425+
query = {
426+
"project_id": "PROJECT ID",
427+
"analysis_type": "count",
428+
"event_collection": "purchases",
429+
"filters": [
430+
{
431+
"property_name": "price",
432+
"operator": "gte",
433+
"property_value": 100
434+
}
435+
],
436+
"timeframe": "this_500_days",
437+
"timezone": None,
438+
"interval": "daily",
439+
"group_by": ["ip_geo_info.country"]
440+
}
441+
index_by = "product.id"
442+
client.cached_datasets.create(
443+
dataset_name,
444+
query,
445+
index_by,
446+
display_name
447+
)
448+
449+
# Get all Cached Datasets
450+
client.cached_datasets.all()
451+
452+
# Get one Cached Dataset
453+
client.cached_datasets.get(dataset_name)
454+
455+
# Retrieve Cached Dataset results
456+
index_by = "a_project_id"
457+
timeframe ="this_2_hours"
458+
client.cached_datasets.results(
459+
dataset_name,
460+
index_by,
461+
timeframe
462+
)
463+
464+
# Using an absolute timeframe
465+
timeframe = {
466+
"start": "2018-11-02T00:00:00.000Z",
467+
"end": "2018-11-02T02:00:00.000Z"
468+
}
469+
client.cached_datasets.results(
470+
dataset_name,
471+
index_by,
472+
timeframe
473+
)
474+
475+
# Using multiple index_by values
476+
index_by = {
477+
"project.id": "a_project_id",
478+
"project.foo": "bar"
479+
}
480+
client.cached_datasets.results(
481+
"dataset_with_multiple_indexes",
482+
index_by,
483+
timeframe
484+
)
485+
486+
# Delete a Cached Dataset
487+
client.cached_datasets.delete(dataset_name)
409488
410489
Overwriting event timestamps
411490
''''''''''''''''''''''''''''

keen/cached_datasets.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import json
2+
3+
from keen.api import HTTPMethods
4+
from keen.utilities import KeenKeys, headers, requires_key
5+
6+
7+
class CachedDatasetsInterface:
8+
9+
def __init__(self, api):
10+
self.api = api
11+
self._cached_datasets_url = "{0}/{1}/projects/{2}/datasets".format(
12+
self.api.base_url, self.api.api_version, self.api.project_id
13+
)
14+
15+
@requires_key(KeenKeys.READ)
16+
def all(self):
17+
""" Fetch all Cached Datasets for a Project. Read key must be set.
18+
"""
19+
return self._get_json(HTTPMethods.GET,
20+
self._cached_datasets_url,
21+
self._get_master_key())
22+
23+
@requires_key(KeenKeys.READ)
24+
def get(self, dataset_name):
25+
""" Fetch a single Cached Dataset for a Project. Read key must be set.
26+
27+
:param dataset_name: Name of Cached Dataset (not `display_name`)
28+
"""
29+
url = "{0}/{1}".format(self._cached_datasets_url, dataset_name)
30+
return self._get_json(HTTPMethods.GET, url, self._get_read_key())
31+
32+
@requires_key(KeenKeys.MASTER)
33+
def create(self, dataset_name, query, index_by, display_name):
34+
""" Create a Cached Dataset for a Project. Master key must be set.
35+
"""
36+
url = "{0}/{1}".format(self._cached_datasets_url, dataset_name)
37+
payload = {
38+
"query": query,
39+
"index_by": index_by,
40+
"display_name": display_name
41+
}
42+
return self._get_json(HTTPMethods.PUT, url, self._get_master_key(), json=payload)
43+
44+
@requires_key(KeenKeys.READ)
45+
def results(self, dataset_name, index_by, timeframe):
46+
""" Retrieve results from a Cached Dataset. Read key must be set.
47+
"""
48+
url = "{0}/{1}/results".format(self._cached_datasets_url, dataset_name)
49+
50+
index_by = index_by if isinstance(index_by, str) else json.dumps(index_by)
51+
timeframe = timeframe if isinstance(timeframe, str) else json.dumps(timeframe)
52+
53+
query_params = {
54+
"index_by": index_by,
55+
"timeframe": timeframe
56+
}
57+
58+
return self._get_json(
59+
HTTPMethods.GET, url, self._get_read_key(), params=query_params
60+
)
61+
62+
@requires_key(KeenKeys.MASTER)
63+
def delete(self, dataset_name):
64+
""" Delete a Cached Dataset. Master Key must be set.
65+
"""
66+
url = "{0}/{1}".format(self._cached_datasets_url, dataset_name)
67+
self._get_json(HTTPMethods.DELETE, url, self._get_master_key())
68+
return True
69+
70+
def _get_json(self, http_method, url, key, *args, **kwargs):
71+
response = self.api.fulfill(
72+
http_method,
73+
url,
74+
headers=headers(key),
75+
*args,
76+
**kwargs)
77+
78+
self.api._error_handling(response)
79+
80+
try:
81+
response = response.json()
82+
except ValueError:
83+
response = "No JSON available."
84+
85+
return response
86+
87+
def _get_read_key(self):
88+
return self.api._get_read_key()
89+
90+
def _get_master_key(self):
91+
return self.api._get_master_key()

keen/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import copy
33
import json
44
import sys
5-
from keen import persistence_strategies, exceptions, saved_queries
5+
from keen import persistence_strategies, exceptions, saved_queries, cached_datasets
66
from keen.api import KeenApi
77
from keen.persistence_strategies import BasePersistenceStrategy
88

@@ -98,6 +98,7 @@ def __init__(self, project_id, write_key=None, read_key=None,
9898
self.get_timeout = get_timeout
9999
self.post_timeout = post_timeout
100100
self.saved_queries = saved_queries.SavedQueriesInterface(self.api)
101+
self.cached_datasets = cached_datasets.CachedDatasetsInterface(self.api)
101102

102103
if sys.version_info[0] < 3:
103104
@staticmethod

0 commit comments

Comments
 (0)