Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def main():

t = Tracker(e, s)

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

t.track_page_view("https://www.snowplow.io", "Homepage")
t.track_page_ping("https://www.snowplow.io", "Homepage")
Expand All @@ -32,6 +32,7 @@ def main():
)
)
t.track_struct_event("shop", "add-to-basket", None, "pcs", 2)
t.flush()


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion snowplow_tracker/celery/celery_emitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(
endpoint: str,
protocol: HttpProtocol = "http",
port: Optional[int] = None,
method: Method = "get",
method: Method = "post",
buffer_size: Optional[int] = None,
byte_limit: Optional[int] = None) -> None:
super(CeleryEmitter, self).__init__(endpoint, protocol, port, method, buffer_size, None, None, byte_limit)
Expand Down
16 changes: 8 additions & 8 deletions snowplow_tracker/emitters.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(
endpoint: str,
protocol: HttpProtocol = "https",
port: Optional[int] = None,
method: Method = "get",
method: Method = "post",
Comment thread
Jack-Keene marked this conversation as resolved.
buffer_size: Optional[int] = None,
on_success: Optional[SuccessCallback] = None,
on_failure: Optional[FailureCallback] = None,
Expand All @@ -66,7 +66,7 @@ def __init__(
:type protocol: protocol
:param port: The collector port to connect to
:type port: int | None
:param method: The HTTP request method
:param method: The HTTP request method. Defaults to post.
:type method: method
:param buffer_size: The maximum number of queued events before the buffer is flushed. Default is 10.
:type buffer_size: int | None
Expand Down Expand Up @@ -118,7 +118,7 @@ def as_collector_uri(
endpoint: str,
protocol: HttpProtocol = "https",
port: Optional[int] = None,
method: Method = "get") -> str:
method: Method = "post") -> str:
"""
:param endpoint: The raw endpoint provided by the user
:type endpoint: string
Expand Down Expand Up @@ -153,7 +153,7 @@ def input(self, payload: PayloadDict) -> None:
If the maximum size has been reached, flushes the buffer.

:param payload: The name-value pairs for the event
:type payload: dict(string:\*)
:type payload: dict(string:\\*)
"""
with self.lock:
if self.bytes_queued is not None:
Expand Down Expand Up @@ -212,7 +212,7 @@ def http_post(self, data: str) -> bool:
def http_get(self, payload: PayloadDict) -> bool:
"""
:param payload: The event properties
:type payload: dict(string:\*)
:type payload: dict(string:\\*)
"""
logger.info("Sending GET request to %s..." % self.endpoint)
logger.debug("Payload: %s" % payload)
Expand Down Expand Up @@ -247,7 +247,7 @@ def is_good_status_code(status_code: int) -> bool:
def send_events(self, evts: PayloadDictList) -> None:
"""
:param evts: Array of events to be sent
:type evts: list(dict(string:\*))
:type evts: list(dict(string:\\*))
"""
if len(evts) > 0:
logger.info("Attempting to send %s events" % len(evts))
Expand Down Expand Up @@ -312,7 +312,7 @@ def attach_sent_timestamp(events: PayloadDictList) -> None:
as `stm` param

:param events: Array of events to be sent
:type events: list(dict(string:\*))
:type events: list(dict(string:\\*))
:rtype: None
"""
def update(e: PayloadDict) -> None:
Expand All @@ -332,7 +332,7 @@ def __init__(
endpoint: str,
protocol: HttpProtocol = "http",
port: Optional[int] = None,
method: Method = "get",
method: Method = "post",
buffer_size: Optional[int] = None,
Comment thread
Jack-Keene marked this conversation as resolved.
on_success: Optional[SuccessCallback] = None,
on_failure: Optional[FailureCallback] = None,
Expand Down
4 changes: 2 additions & 2 deletions snowplow_tracker/payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def add_dict(self, dict_: PayloadDict, base64: bool = False) -> None:
Add a dict of name value pairs to the Payload object

:param dict_: Dictionary to be added to the Payload
:type dict_: dict(string:\*)
:type dict_: dict(string:\\*)
"""
for f in dict_:
self.add(f, dict_[f])
Expand All @@ -70,7 +70,7 @@ def add_json(
Add an encoded or unencoded JSON to the payload

:param dict_: Custom context for the event
:type dict_: dict(string:\*) | None
:type dict_: dict(string:\\*) | None
:param encode_base64: If the payload is base64 encoded
:type encode_base64: bool
:param type_when_encoded: Name of the field when encode_base64 is set
Expand Down
48 changes: 25 additions & 23 deletions snowplow_tracker/test/integration/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@

querystrings = [""]

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

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

default_subject = subject.Subject()

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

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

def test_integration_ecommerce_transaction_item(self) -> None:
t = tracker.Tracker([default_emitter], default_subject)
t = tracker.Tracker([get_emitter], default_subject)
with HTTMock(pass_response_content):
t.track_ecommerce_transaction_item("12345", "pbz0025", 7.99, 2, "black-tarot", "tarot", currency="GBP")
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"}
for key in expected_fields:
self.assertEqual(from_querystring(key, querystrings[-1]), expected_fields[key])

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

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

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

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

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

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

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

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

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

t = tracker.Tracker([emitters.Emitter("localhost")], s, "cf", app_id="angry-birds-android")
t = tracker.Tracker([emitters.Emitter("localhost", method='get')], s, "cf", app_id="angry-birds-android")
evSubject = subject.Subject().set_domain_user_id("1111aaa11a111a11").set_lang("EN")
with HTTMock(pass_response_content):
t.track_page_view("localhost", "local host", event_subject=evSubject)
Expand Down Expand Up @@ -293,6 +293,7 @@ def test_integration_success_callback(self) -> None:
callback_failure_queue = []
callback_emitter = emitters.Emitter(
"localhost",
method='get',
on_success=lambda x: callback_success_queue.append(x),
on_failure=lambda x, y: callback_failure_queue.append(x))
t = tracker.Tracker([callback_emitter], default_subject)
Expand All @@ -312,6 +313,7 @@ def test_integration_failure_callback(self) -> None:
callback_failure_queue = []
callback_emitter = emitters.Emitter(
"localhost",
method='get',
on_success=lambda x: callback_success_queue.append(x),
on_failure=lambda x, y: callback_failure_queue.append(x))
t = tracker.Tracker([callback_emitter], default_subject)
Expand All @@ -321,7 +323,7 @@ def test_integration_failure_callback(self) -> None:
self.assertEqual(callback_failure_queue[0], 0)

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

def test_post_batched(self) -> None:
post_emitter = emitters.Emitter("localhost", protocol="http", port=80, method='post', buffer_size=2)
t = tracker.Tracker(post_emitter, default_subject)
default_emitter = emitters.Emitter("localhost", protocol="http", port=80, buffer_size=2)
t = tracker.Tracker(default_emitter, default_subject)
with HTTMock(pass_post_response_content):
t.track_struct_event("Test", "A")
t.track_struct_event("Test", "B")
Expand All @@ -341,7 +343,7 @@ def test_post_batched(self) -> None:

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

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

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

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