Skip to content

Commit 2cd6abb

Browse files
authored
Change default method to POST in emitter (close #289)
PR #290 * Set default method to post * Fix invalid escape sequence in doc strings * Update integration tests * Update unit tests * Update example app
1 parent fed98f8 commit 2cd6abb

7 files changed

Lines changed: 62 additions & 59 deletions

File tree

examples/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def main():
1919

2020
t = Tracker(e, s)
2121

22-
print("Sending events to " + collector_url)
22+
print("Sending events to " + e.endpoint)
2323

2424
t.track_page_view("https://www.snowplow.io", "Homepage")
2525
t.track_page_ping("https://www.snowplow.io", "Homepage")
@@ -32,6 +32,7 @@ def main():
3232
)
3333
)
3434
t.track_struct_event("shop", "add-to-basket", None, "pcs", 2)
35+
t.flush()
3536

3637

3738
if __name__ == "__main__":

snowplow_tracker/celery/celery_emitter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(
5252
endpoint: str,
5353
protocol: HttpProtocol = "http",
5454
port: Optional[int] = None,
55-
method: Method = "get",
55+
method: Method = "post",
5656
buffer_size: Optional[int] = None,
5757
byte_limit: Optional[int] = None) -> None:
5858
super(CeleryEmitter, self).__init__(endpoint, protocol, port, method, buffer_size, None, None, byte_limit)

snowplow_tracker/emitters.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def __init__(
5353
endpoint: str,
5454
protocol: HttpProtocol = "https",
5555
port: Optional[int] = None,
56-
method: Method = "get",
56+
method: Method = "post",
5757
buffer_size: Optional[int] = None,
5858
on_success: Optional[SuccessCallback] = None,
5959
on_failure: Optional[FailureCallback] = None,
@@ -66,7 +66,7 @@ def __init__(
6666
:type protocol: protocol
6767
:param port: The collector port to connect to
6868
:type port: int | None
69-
:param method: The HTTP request method
69+
:param method: The HTTP request method. Defaults to post.
7070
:type method: method
7171
:param buffer_size: The maximum number of queued events before the buffer is flushed. Default is 10.
7272
:type buffer_size: int | None
@@ -118,7 +118,7 @@ def as_collector_uri(
118118
endpoint: str,
119119
protocol: HttpProtocol = "https",
120120
port: Optional[int] = None,
121-
method: Method = "get") -> str:
121+
method: Method = "post") -> str:
122122
"""
123123
:param endpoint: The raw endpoint provided by the user
124124
:type endpoint: string
@@ -153,7 +153,7 @@ def input(self, payload: PayloadDict) -> None:
153153
If the maximum size has been reached, flushes the buffer.
154154
155155
:param payload: The name-value pairs for the event
156-
:type payload: dict(string:\*)
156+
:type payload: dict(string:\\*)
157157
"""
158158
with self.lock:
159159
if self.bytes_queued is not None:
@@ -212,7 +212,7 @@ def http_post(self, data: str) -> bool:
212212
def http_get(self, payload: PayloadDict) -> bool:
213213
"""
214214
:param payload: The event properties
215-
:type payload: dict(string:\*)
215+
:type payload: dict(string:\\*)
216216
"""
217217
logger.info("Sending GET request to %s..." % self.endpoint)
218218
logger.debug("Payload: %s" % payload)
@@ -247,7 +247,7 @@ def is_good_status_code(status_code: int) -> bool:
247247
def send_events(self, evts: PayloadDictList) -> None:
248248
"""
249249
:param evts: Array of events to be sent
250-
:type evts: list(dict(string:\*))
250+
:type evts: list(dict(string:\\*))
251251
"""
252252
if len(evts) > 0:
253253
logger.info("Attempting to send %s events" % len(evts))
@@ -312,7 +312,7 @@ def attach_sent_timestamp(events: PayloadDictList) -> None:
312312
as `stm` param
313313
314314
:param events: Array of events to be sent
315-
:type events: list(dict(string:\*))
315+
:type events: list(dict(string:\\*))
316316
:rtype: None
317317
"""
318318
def update(e: PayloadDict) -> None:
@@ -332,7 +332,7 @@ def __init__(
332332
endpoint: str,
333333
protocol: HttpProtocol = "http",
334334
port: Optional[int] = None,
335-
method: Method = "get",
335+
method: Method = "post",
336336
buffer_size: Optional[int] = None,
337337
on_success: Optional[SuccessCallback] = None,
338338
on_failure: Optional[FailureCallback] = None,

snowplow_tracker/payload.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def add_dict(self, dict_: PayloadDict, base64: bool = False) -> None:
5454
Add a dict of name value pairs to the Payload object
5555
5656
:param dict_: Dictionary to be added to the Payload
57-
:type dict_: dict(string:\*)
57+
:type dict_: dict(string:\\*)
5858
"""
5959
for f in dict_:
6060
self.add(f, dict_[f])
@@ -70,7 +70,7 @@ def add_json(
7070
Add an encoded or unencoded JSON to the payload
7171
7272
:param dict_: Custom context for the event
73-
:type dict_: dict(string:\*) | None
73+
:type dict_: dict(string:\\*) | None
7474
:param encode_base64: If the payload is base64 encoded
7575
:type encode_base64: bool
7676
:param type_when_encoded: Name of the field when encode_base64 is set

snowplow_tracker/test/integration/test_integration.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636

3737
querystrings = [""]
3838

39-
default_emitter = emitters.Emitter("localhost", protocol="http", port=80)
39+
default_emitter = emitters.Emitter("localhost", protocol="http", port=80, buffer_size=1)
4040

41-
post_emitter = emitters.Emitter("localhost", protocol="http", port=80, method='post', buffer_size=1)
41+
get_emitter = emitters.Emitter("localhost", protocol="http", port=80, method='get')
4242

4343
default_subject = subject.Subject()
4444

@@ -79,23 +79,23 @@ def fail_response_content(url: str, request: Any) -> Dict[str, Any]:
7979
class IntegrationTest(unittest.TestCase):
8080

8181
def test_integration_page_view(self) -> None:
82-
t = tracker.Tracker([default_emitter], default_subject)
82+
t = tracker.Tracker([get_emitter], default_subject)
8383
with HTTMock(pass_response_content):
8484
t.track_page_view("http://savethearctic.org", "Save The Arctic", "http://referrer.com")
8585
expected_fields = {"e": "pv", "page": "Save+The+Arctic", "url": "http%3A%2F%2Fsavethearctic.org", "refr": "http%3A%2F%2Freferrer.com"}
8686
for key in expected_fields:
8787
self.assertEqual(from_querystring(key, querystrings[-1]), expected_fields[key])
8888

8989
def test_integration_ecommerce_transaction_item(self) -> None:
90-
t = tracker.Tracker([default_emitter], default_subject)
90+
t = tracker.Tracker([get_emitter], default_subject)
9191
with HTTMock(pass_response_content):
9292
t.track_ecommerce_transaction_item("12345", "pbz0025", 7.99, 2, "black-tarot", "tarot", currency="GBP")
9393
expected_fields = {"ti_ca": "tarot", "ti_id": "12345", "ti_qu": "2", "ti_sk": "pbz0025", "e": "ti", "ti_nm": "black-tarot", "ti_pr": "7.99", "ti_cu": "GBP"}
9494
for key in expected_fields:
9595
self.assertEqual(from_querystring(key, querystrings[-1]), expected_fields[key])
9696

9797
def test_integration_ecommerce_transaction(self) -> None:
98-
t = tracker.Tracker([default_emitter], default_subject)
98+
t = tracker.Tracker([get_emitter], default_subject)
9999
with HTTMock(pass_response_content):
100100
t.track_ecommerce_transaction(
101101
"6a8078be", 35, city="London", currency="GBP",
@@ -126,7 +126,7 @@ def test_integration_ecommerce_transaction(self) -> None:
126126
self.assertEqual(from_querystring("ttm", querystrings[-3]), from_querystring("ttm", querystrings[-2]))
127127

128128
def test_integration_screen_view(self) -> None:
129-
t = tracker.Tracker([default_emitter], default_subject, encode_base64=False)
129+
t = tracker.Tracker([get_emitter], default_subject, encode_base64=False)
130130
with HTTMock(pass_response_content):
131131
t.track_screen_view("Game HUD 2", id_="534")
132132
expected_fields = {"e": "ue"}
@@ -146,15 +146,15 @@ def test_integration_screen_view(self) -> None:
146146
})
147147

148148
def test_integration_struct_event(self) -> None:
149-
t = tracker.Tracker([default_emitter], default_subject)
149+
t = tracker.Tracker([get_emitter], default_subject)
150150
with HTTMock(pass_response_content):
151151
t.track_struct_event("Ecomm", "add-to-basket", "dog-skateboarding-video", "hd", 13.99)
152152
expected_fields = {"se_ca": "Ecomm", "se_pr": "hd", "se_la": "dog-skateboarding-video", "se_va": "13.99", "se_ac": "add-to-basket", "e": "se"}
153153
for key in expected_fields:
154154
self.assertEqual(from_querystring(key, querystrings[-1]), expected_fields[key])
155155

156156
def test_integration_unstruct_event_non_base64(self) -> None:
157-
t = tracker.Tracker([default_emitter], default_subject, encode_base64=False)
157+
t = tracker.Tracker([get_emitter], default_subject, encode_base64=False)
158158
with HTTMock(pass_response_content):
159159
t.track_unstruct_event(SelfDescribingJson("iglu:com.acme/viewed_product/jsonschema/2-0-2", {"product_id": "ASO01043", "price$flt": 49.95, "walrus$tms": 1000}))
160160
expected_fields = {"e": "ue"}
@@ -168,7 +168,7 @@ def test_integration_unstruct_event_non_base64(self) -> None:
168168
})
169169

170170
def test_integration_unstruct_event_base64(self) -> None:
171-
t = tracker.Tracker([default_emitter], default_subject, encode_base64=True)
171+
t = tracker.Tracker([get_emitter], default_subject, encode_base64=True)
172172
with HTTMock(pass_response_content):
173173
t.track_unstruct_event(SelfDescribingJson("iglu:com.acme/viewed_product/jsonschema/2-0-2", {"product_id": "ASO01043", "price$flt": 49.95, "walrus$tms": 1000}))
174174
expected_fields = {"e": "ue"}
@@ -182,7 +182,7 @@ def test_integration_unstruct_event_base64(self) -> None:
182182
})
183183

184184
def test_integration_context_non_base64(self) -> None:
185-
t = tracker.Tracker([default_emitter], default_subject, encode_base64=False)
185+
t = tracker.Tracker([get_emitter], default_subject, encode_base64=False)
186186
with HTTMock(pass_response_content):
187187
t.track_page_view("localhost", "local host", None, [SelfDescribingJson("iglu:com.example/user/jsonschema/2-0-3", {"user_type": "tester"})])
188188
envelope_string = from_querystring("co", querystrings[-1])
@@ -193,7 +193,7 @@ def test_integration_context_non_base64(self) -> None:
193193
})
194194

195195
def test_integration_context_base64(self) -> None:
196-
t = tracker.Tracker([default_emitter], default_subject, encode_base64=True)
196+
t = tracker.Tracker([get_emitter], default_subject, encode_base64=True)
197197
with HTTMock(pass_response_content):
198198
t.track_page_view("localhost", "local host", None, [SelfDescribingJson("iglu:com.example/user/jsonschema/2-0-3", {"user_type": "tester"})])
199199
envelope_string = unquote_plus(from_querystring("cx", querystrings[-1]))
@@ -212,7 +212,7 @@ def test_integration_standard_nv_pairs(self) -> None:
212212
s.set_timezone("Europe London")
213213
s.set_lang("en")
214214

215-
t = tracker.Tracker([emitters.Emitter("localhost")], s, "cf", app_id="angry-birds-android")
215+
t = tracker.Tracker([emitters.Emitter("localhost", method='get')], s, "cf", app_id="angry-birds-android")
216216
with HTTMock(pass_response_content):
217217
t.track_page_view("localhost", "local host")
218218
expected_fields = {"tna": "cf", "res": "100x200",
@@ -232,7 +232,7 @@ def test_integration_identification_methods(self) -> None:
232232
s.set_useragent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)")
233233
s.set_network_user_id("fbc6c76c-bce5-43ce-8d5a-31c5")
234234

235-
t = tracker.Tracker([emitters.Emitter("localhost")], s, "cf", app_id="angry-birds-android")
235+
t = tracker.Tracker([emitters.Emitter("localhost", method='get')], s, "cf", app_id="angry-birds-android")
236236
with HTTMock(pass_response_content):
237237
t.track_page_view("localhost", "local host")
238238
expected_fields = {
@@ -251,7 +251,7 @@ def test_integration_event_subject(self) -> None:
251251
s.set_domain_user_id("4616bfb38f872d16")
252252
s.set_lang("ES")
253253

254-
t = tracker.Tracker([emitters.Emitter("localhost")], s, "cf", app_id="angry-birds-android")
254+
t = tracker.Tracker([emitters.Emitter("localhost", method='get')], s, "cf", app_id="angry-birds-android")
255255
evSubject = subject.Subject().set_domain_user_id("1111aaa11a111a11").set_lang("EN")
256256
with HTTMock(pass_response_content):
257257
t.track_page_view("localhost", "local host", event_subject=evSubject)
@@ -293,6 +293,7 @@ def test_integration_success_callback(self) -> None:
293293
callback_failure_queue = []
294294
callback_emitter = emitters.Emitter(
295295
"localhost",
296+
method='get',
296297
on_success=lambda x: callback_success_queue.append(x),
297298
on_failure=lambda x, y: callback_failure_queue.append(x))
298299
t = tracker.Tracker([callback_emitter], default_subject)
@@ -312,6 +313,7 @@ def test_integration_failure_callback(self) -> None:
312313
callback_failure_queue = []
313314
callback_emitter = emitters.Emitter(
314315
"localhost",
316+
method='get',
315317
on_success=lambda x: callback_success_queue.append(x),
316318
on_failure=lambda x, y: callback_failure_queue.append(x))
317319
t = tracker.Tracker([callback_emitter], default_subject)
@@ -321,7 +323,7 @@ def test_integration_failure_callback(self) -> None:
321323
self.assertEqual(callback_failure_queue[0], 0)
322324

323325
def test_post_page_view(self) -> None:
324-
t = tracker.Tracker([post_emitter], default_subject)
326+
t = tracker.Tracker([default_emitter], default_subject)
325327
with HTTMock(pass_post_response_content):
326328
t.track_page_view("localhost", "local host", None)
327329
expected_fields = {"e": "pv", "page": "local host", "url": "localhost"}
@@ -331,8 +333,8 @@ def test_post_page_view(self) -> None:
331333
self.assertEqual(request["data"][0][key], expected_fields[key])
332334

333335
def test_post_batched(self) -> None:
334-
post_emitter = emitters.Emitter("localhost", protocol="http", port=80, method='post', buffer_size=2)
335-
t = tracker.Tracker(post_emitter, default_subject)
336+
default_emitter = emitters.Emitter("localhost", protocol="http", port=80, buffer_size=2)
337+
t = tracker.Tracker(default_emitter, default_subject)
336338
with HTTMock(pass_post_response_content):
337339
t.track_struct_event("Test", "A")
338340
t.track_struct_event("Test", "B")
@@ -341,7 +343,7 @@ def test_post_batched(self) -> None:
341343

342344
@freeze_time("2021-04-19 00:00:01") # unix: 1618790401000
343345
def test_timestamps(self) -> None:
344-
emitter = emitters.Emitter("localhost", protocol="http", port=80, method='post', buffer_size=3)
346+
emitter = emitters.Emitter("localhost", protocol="http", port=80, buffer_size=3)
345347
t = tracker.Tracker([emitter], default_subject)
346348
with HTTMock(pass_post_response_content):
347349
t.track_page_view("localhost", "stamp0", None, tstamp=None)
@@ -361,18 +363,18 @@ def test_timestamps(self) -> None:
361363
self.assertEqual(request["data"][i].get("stm"), expected_timestamps[i]["stm"])
362364

363365
def test_bytelimit(self) -> None:
364-
post_emitter = emitters.Emitter("localhost", protocol="http", port=80, method='post', buffer_size=5, byte_limit=420)
365-
t = tracker.Tracker(post_emitter, default_subject)
366+
default_emitter = emitters.Emitter("localhost", protocol="http", port=80, buffer_size=5, byte_limit=420)
367+
t = tracker.Tracker(default_emitter, default_subject)
366368
with HTTMock(pass_post_response_content):
367369
t.track_struct_event("Test", "A") # 140 bytes
368370
t.track_struct_event("Test", "A") # 280 bytes
369371
t.track_struct_event("Test", "A") # 420 bytes. Send
370372
t.track_struct_event("Test", "AA") # 141
371373
self.assertEqual(len(querystrings[-1]["data"]), 3)
372-
self.assertEqual(post_emitter.bytes_queued, 136 + len(_version.__version__))
374+
self.assertEqual(default_emitter.bytes_queued, 136 + len(_version.__version__))
373375

374376
def test_unicode_get(self) -> None:
375-
t = tracker.Tracker([default_emitter], default_subject, encode_base64=False)
377+
t = tracker.Tracker([get_emitter], default_subject, encode_base64=False)
376378
unicode_a = u'\u0107'
377379
unicode_b = u'test.\u0107om'
378380
test_ctx = SelfDescribingJson('iglu:a.b/c/jsonschema/1-0-0', {'test': unicode_a})
@@ -396,7 +398,7 @@ def test_unicode_get(self) -> None:
396398
self.assertEqual(actual_b, unicode_b)
397399

398400
def test_unicode_post(self) -> None:
399-
t = tracker.Tracker([post_emitter], default_subject, encode_base64=False)
401+
t = tracker.Tracker([default_emitter], default_subject, encode_base64=False)
400402
unicode_a = u'\u0107'
401403
unicode_b = u'test.\u0107om'
402404
test_ctx = SelfDescribingJson('iglu:a.b/c/jsonschema/1-0-0', {'test': unicode_a})

0 commit comments

Comments
 (0)