Skip to content

Commit 19819f6

Browse files
committed
0.1.9 - read config from env
1 parent 256b901 commit 19819f6

File tree

7 files changed

+423
-99
lines changed

7 files changed

+423
-99
lines changed

README.md

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
Keen IO Official Python Client Library
22
======================================
33

4-
[![Build Status](https://secure.travis-ci.org/keenlabs/KeenClient-Python.png?branch=new-keys)](http://travis-ci
5-
.org/keenlabs/KeenClient-Python)
4+
[![Build Status](https://secure.travis-ci.org/keenlabs/KeenClient-Python.png?branch=new-keys)](http://travis-ci.org/keenlabs/KeenClient-Python)
65

76
This is the official Python Client for the [Keen IO](https://keen.io/) API. The
87
Keen IO API lets developers build analytics features directly into their apps.
@@ -21,19 +20,27 @@ This client is known to work on Python 2.7.3.
2120

2221
To use this client with the Keen IO API, you have to configure your Keen IO Project ID and its access keys (if you need an account, [sign up here](https://keen.io/) - it's free).
2322

24-
##### Send Events to Keen IO
23+
Setting a write key is required for publishing events. Setting a read key is required for running queries. The recommended way to set this configuration information is via the environment. The keys you can set are `KEEN_PROJECT_ID`, `KEEN_WRITE_KEY`, and `KEEN_READ_KEY`.
24+
25+
If you don't want to use environment variables for some reason, you can directly set values as follows:
26+
27+
keen.project_id = "xxxx"
28+
keen.write_key = "yyyy"
29+
keen.read_key = "zzzz"
2530

26-
Once you have your Project ID, use the client like so:
31+
You can also configure unique client instances as follows:
2732

28-
from keen.client import KeenClient
29-
30-
project_id = "<YOUR_PROJECT_ID>"
31-
write_key = "<YOUR_WRITE_KEY>"
3233
client = KeenClient(
33-
project_id,
34-
write_key=write_key
34+
project_id="xxxx",
35+
write_key="yyyy",
36+
read_key="zzzz"
3537
)
36-
client.add_event("sign_ups", {
38+
39+
##### Send Events to Keen IO
40+
41+
Once you've set `KEEN_PROJECT_ID` and `KEEN_WRITE_KEY`, sending events is simple:
42+
43+
keen.add_event("sign_ups", {
3744
"username": "lloyd",
3845
"referred_by": "harry"
3946
})
@@ -42,7 +49,8 @@ Once you have your Project ID, use the client like so:
4249

4350
You can upload Events in a batch, like so:
4451

45-
client.add_events({
52+
# uploads 4 events total - 2 to the "sign_ups" collection and 2 to the "purchases" collection
53+
keen.add_events({
4654
"sign_ups": [
4755
{ "username": "nameuser1" },
4856
{ "username": "nameuser2" }
@@ -58,33 +66,22 @@ That's it! After running your code, check your Keen IO Project to see the event/
5866

5967
##### Do analysis with Keen IO
6068

61-
If you want to do analysis, configure you client like this:
62-
63-
from keen.client import KeenClient
64-
65-
project_id = "<YOUR_PROJECT_ID>"
66-
read_key = "<YOUR_READ_KEY>"
67-
client = KeenClient(
68-
project_id,
69-
read_key=read_key
70-
)
71-
7269
Here are some examples of querying. Let's assume you've added some events to the "purchases" collection.
7370

74-
client.count("purchases") # => 100
75-
client.sum("purchases", target_property="price") # => 10000
76-
client.minimum("purchases", target_property="price") # => 20
77-
client.maximum("purchases", target_property="price") # => 100
78-
client.average("purchases", target_property="price") # => 49.2
71+
keen.count("purchases") # => 100
72+
keen.sum("purchases", target_property="price") # => 10000
73+
keen.minimum("purchases", target_property="price") # => 20
74+
keen.maximum("purchases", target_property="price") # => 100
75+
keen.average("purchases", target_property="price") # => 49.2
7976

80-
client.sum("purchases", target_property="price", group_by="item.id") # => [{ "item.id": 123, "result": 240 }, { ... }]
77+
keen.sum("purchases", target_property="price", group_by="item.id") # => [{ "item.id": 123, "result": 240 }, { ... }]
8178

82-
client.count_unique("purchases", target_property="user.id") # => 3
83-
client.select_unique("purchases", target_property="user.email") # => ["[email protected]", "[email protected]"]
79+
keen.count_unique("purchases", target_property="user.id") # => 3
80+
keen.select_unique("purchases", target_property="user.email") # => ["[email protected]", "[email protected]"]
8481

85-
client.extraction("purchases", timeframe="today") # => [{ "price" => 20, ... }, { ... }]
82+
keen.extraction("purchases", timeframe="today") # => [{ "price" => 20, ... }, { ... }]
8683

87-
client.multi_analysis("purchases", analyses={"total":{"analysis_type":"sum", "target_property":"price"}, "average":{"analysis_type":"average", "target_property":"price"}) # => {"total":10329.03, "average":933.93}
84+
keen.multi_analysis("purchases", analyses={"total":{"analysis_type":"sum", "target_property":"price"}, "average":{"analysis_type":"average", "target_property":"price"}) # => {"total":10329.03, "average":933.93}
8885

8986
step1 = {
9087
"event_collection": "signup",
@@ -94,13 +91,15 @@ Here are some examples of querying. Let's assume you've added some events to th
9491
"event_collection": "purchase",
9592
"actor_property": "user.email"
9693
}
97-
client.funnel([step1, step2], timeframe="today") # => [2039, 201]
94+
keen.funnel([step1, step2], timeframe="today") # => [2039, 201]
9895

9996
### Changelog
10097

10198
##### 0.1.9
10299

103100
+ Added support for publishing events in batches
101+
+ Added support for configuring client automatically from environment
102+
+ Added methods on keen module directly
104103

105104
##### 0.1.8
106105

keen/__init__.py

Lines changed: 269 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,269 @@
1-
__author__ = 'dkador'
1+
import os
2+
from keen.client import KeenClient
3+
from keen.exceptions import InvalidEnvironmentError
4+
5+
__author__ = 'dkador'
6+
7+
_client = None
8+
project_id = None
9+
write_key = None
10+
read_key = None
11+
12+
13+
def _initialize_client_from_environment():
14+
global _client, project_id, write_key, read_key
15+
16+
if _client is None:
17+
# check environment for project ID and keys
18+
project_id = project_id or os.environ.get("KEEN_PROJECT_ID")
19+
write_key = write_key or os.environ.get("KEEN_WRITE_KEY")
20+
read_key = read_key or os.environ.get("KEEN_READ_KEY")
21+
22+
if not project_id:
23+
raise InvalidEnvironmentError("Please set the KEEN_PROJECT_ID environment variable or set keen.project_id!")
24+
25+
_client = KeenClient(project_id,
26+
write_key=write_key,
27+
read_key=read_key)
28+
29+
30+
def add_event(event_collection, body, timestamp=None):
31+
_initialize_client_from_environment()
32+
_client.add_event(event_collection, body, timestamp=timestamp)
33+
34+
35+
def count(event_collection, timeframe=None, timezone=None, interval=None, filters=None, group_by=None):
36+
""" Performs a count query
37+
38+
Counts the number of events that meet the given criteria.
39+
40+
:param event_collection: string, the name of the collection to query
41+
:param timeframe: string or dict, the timeframe in which the events
42+
happened example: "previous_7_days"
43+
:param timezone: int, the timezone you'd like to use for the timeframe
44+
and interval in seconds
45+
:param interval: string, the time interval used for measuring data over
46+
time example: "daily"
47+
:param filters: array of dict, contains the filters you'd like to apply to the data
48+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
49+
:param group_by: string or array of strings, the name(s) of the properties you would
50+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
51+
52+
"""
53+
_initialize_client_from_environment()
54+
return _client.count(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
55+
interval=interval, filters=filters, group_by=group_by)
56+
57+
58+
def sum(event_collection, target_property, timeframe=None, timezone=None, interval=None, filters=None,
59+
group_by=None):
60+
""" Performs a sum query
61+
62+
Adds the values of a target property for events that meet the given criteria.
63+
64+
:param event_collection: string, the name of the collection to query
65+
:param target_property: string, the name of the event property you would like use
66+
:param timeframe: string or dict, the timeframe in which the events
67+
happened example: "previous_7_days"
68+
:param timezone: int, the timezone you'd like to use for the timeframe
69+
and interval in seconds
70+
:param interval: string, the time interval used for measuring data over
71+
time example: "daily"
72+
:param filters: array of dict, contains the filters you'd like to apply to the data
73+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
74+
:param group_by: string or array of strings, the name(s) of the properties you would
75+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
76+
77+
"""
78+
_initialize_client_from_environment()
79+
return _client.sum(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
80+
interval=interval, filters=filters, group_by=group_by, target_property=target_property)
81+
82+
83+
def minimum(event_collection, target_property, timeframe=None, timezone=None, interval=None, filters=None,
84+
group_by=None):
85+
""" Performs a minimum query
86+
87+
Finds the minimum value of a target property for events that meet the given criteria.
88+
89+
:param event_collection: string, the name of the collection to query
90+
:param target_property: string, the name of the event property you would like use
91+
:param timeframe: string or dict, the timeframe in which the events
92+
happened example: "previous_7_days"
93+
:param timezone: int, the timezone you'd like to use for the timeframe
94+
and interval in seconds
95+
:param interval: string, the time interval used for measuring data over
96+
time example: "daily"
97+
:param filters: array of dict, contains the filters you'd like to apply to the data
98+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
99+
:param group_by: string or array of strings, the name(s) of the properties you would
100+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
101+
102+
"""
103+
_initialize_client_from_environment()
104+
return _client.minimum(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
105+
interval=interval, filters=filters, group_by=group_by, target_property=target_property)
106+
107+
108+
def maximum(event_collection, target_property, timeframe=None, timezone=None, interval=None, filters=None,
109+
group_by=None):
110+
""" Performs a maximum query
111+
112+
Finds the maximum value of a target property for events that meet the given criteria.
113+
114+
:param event_collection: string, the name of the collection to query
115+
:param target_property: string, the name of the event property you would like use
116+
:param timeframe: string or dict, the timeframe in which the events
117+
happened example: "previous_7_days"
118+
:param timezone: int, the timezone you'd like to use for the timeframe
119+
and interval in seconds
120+
:param interval: string, the time interval used for measuring data over
121+
time example: "daily"
122+
:param filters: array of dict, contains the filters you'd like to apply to the data
123+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
124+
:param group_by: string or array of strings, the name(s) of the properties you would
125+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
126+
127+
"""
128+
_initialize_client_from_environment()
129+
return _client.maximum(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
130+
interval=interval, filters=filters, group_by=group_by, target_property=target_property)
131+
132+
133+
def average(event_collection, target_property, timeframe=None, timezone=None, interval=None, filters=None,
134+
group_by=None):
135+
""" Performs a average query
136+
137+
Finds the average of a target property for events that meet the given criteria.
138+
139+
:param event_collection: string, the name of the collection to query
140+
:param target_property: string, the name of the event property you would like use
141+
:param timeframe: string or dict, the timeframe in which the events
142+
happened example: "previous_7_days"
143+
:param timezone: int, the timezone you'd like to use for the timeframe
144+
and interval in seconds
145+
:param interval: string, the time interval used for measuring data over
146+
time example: "daily"
147+
:param filters: array of dict, contains the filters you'd like to apply to the data
148+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
149+
:param group_by: string or array of strings, the name(s) of the properties you would
150+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
151+
152+
"""
153+
_initialize_client_from_environment()
154+
return _client.average(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
155+
interval=interval, filters=filters, group_by=group_by, target_property=target_property)
156+
157+
158+
def count_unique(event_collection, target_property, timeframe=None, timezone=None, interval=None,
159+
filters=None, group_by=None):
160+
""" Performs a count unique query
161+
162+
Counts the unique values of a target property for events that meet the given criteria.
163+
164+
:param event_collection: string, the name of the collection to query
165+
:param target_property: string, the name of the event property you would like use
166+
:param timeframe: string or dict, the timeframe in which the events
167+
happened example: "previous_7_days"
168+
:param timezone: int, the timezone you'd like to use for the timeframe
169+
and interval in seconds
170+
:param interval: string, the time interval used for measuring data over
171+
time example: "daily"
172+
:param filters: array of dict, contains the filters you'd like to apply to the data
173+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
174+
:param group_by: string or array of strings, the name(s) of the properties you would
175+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
176+
177+
"""
178+
_initialize_client_from_environment()
179+
return _client.count_unique(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
180+
interval=interval, filters=filters, group_by=group_by, target_property=target_property)
181+
182+
183+
def select_unique(event_collection, target_property, timeframe=None, timezone=None, interval=None,
184+
filters=None, group_by=None):
185+
""" Performs a select unique query
186+
187+
Returns an array of the unique values of a target property for events that meet the given criteria.
188+
189+
:param event_collection: string, the name of the collection to query
190+
:param target_property: string, the name of the event property you would like use
191+
:param timeframe: string or dict, the timeframe in which the events
192+
happened example: "previous_7_days"
193+
:param timezone: int, the timezone you'd like to use for the timeframe
194+
and interval in seconds
195+
:param interval: string, the time interval used for measuring data over
196+
time example: "daily"
197+
:param filters: array of dict, contains the filters you'd like to apply to the data
198+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
199+
:param group_by: string or array of strings, the name(s) of the properties you would
200+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
201+
202+
"""
203+
_initialize_client_from_environment()
204+
return _client.select_unique(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
205+
interval=interval, filters=filters, group_by=group_by, target_property=target_property)
206+
207+
208+
def extraction(event_collection, timeframe=None, timezone=None, filters=None, latest=None, email=None):
209+
""" Performs a data extraction
210+
211+
Returns either a JSON object of events or a response
212+
indicating an email will be sent to you with data.
213+
214+
:param event_collection: string, the name of the collection to query
215+
:param timeframe: string or dict, the timeframe in which the events
216+
happened example: "previous_7_days"
217+
:param timezone: int, the timezone you'd like to use for the timeframe
218+
and interval in seconds
219+
:param filters: array of dict, contains the filters you'd like to apply to the data
220+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
221+
:param latest: int, the number of most recent records you'd like to return
222+
:param email: string, optional string containing an email address to email results to
223+
224+
"""
225+
_initialize_client_from_environment()
226+
return _client.extraction(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
227+
filters=filters, latest=latest, email=email)
228+
229+
230+
def funnel(steps, timeframe=None, timezone=None):
231+
""" Performs a Funnel query
232+
233+
Returns an object containing the results for each step of the funnel.
234+
235+
:param steps: array of dictionaries, one for each step. example:
236+
[{"event_collection":"signup","actor_property":"user.id"},
237+
{"event_collection":"purchase","actor_property:"user.id"}]
238+
:param timeframe: string or dict, the timeframe in which the events
239+
happened example: "previous_7_days"
240+
:param timezone: int, the timezone you'd like to use for the timeframe
241+
and interval in seconds
242+
243+
"""
244+
_initialize_client_from_environment()
245+
return _client.funnel(steps=steps, timeframe=timeframe, timezone=timezone)
246+
247+
248+
def multi_analysis(event_collection, analyses, timeframe=None, timezone=None, filters=None, group_by=None):
249+
""" Performs a multi-analysis query
250+
251+
Returns a dictionary of analysis results.
252+
253+
:param event_collection: string, the name of the collection to query
254+
:param analyses: dict, the types of analyses you'd like to run. example:
255+
{"total money made":{"analysis_type":"sum","target_property":"purchase.price",
256+
"average price":{"analysis_type":"average","target_property":"purchase.price"}
257+
:param timeframe: string or dict, the timeframe in which the events
258+
happened example: "previous_7_days"
259+
:param timezone: int, the timezone you'd like to use for the timeframe
260+
and interval in seconds
261+
:param filters: array of dict, contains the filters you'd like to apply to the data
262+
example: {["property_name":"device", "operator":"eq", "property_value":"iPhone"}]
263+
:param group_by: string or array of strings, the name(s) of the properties you would
264+
like to group you results by. example: "customer.id" or ["browser","operating_system"]
265+
266+
"""
267+
_initialize_client_from_environment()
268+
return _client.multi_analysis(event_collection=event_collection, timeframe=timeframe, timezone=timezone,
269+
filters=filters, group_by=group_by, analyses=analyses)

0 commit comments

Comments
 (0)