{"id":1027,"library":"snowplow-tracker","title":"Snowplow event tracker for Python","description":"The Snowplow Python Tracker allows you to collect and track event data from your Python applications, games, and web servers/frameworks, including Django. It provides a robust way to implement analytics by defining subjects, emitters, and trackers to send events to a Snowplow collector or custom event store. The library is actively maintained, with the current version being 1.1.0, and receives regular updates.","status":"active","version":"1.1.0","language":"python","source_language":"en","source_url":"https://github.com/snowplow/snowplow-python-tracker","tags":["analytics","tracking","snowplow","events"],"install":[{"cmd":"pip install snowplow-tracker","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"HTTP library for sending events.","package":"requests","optional":false},{"reason":"Backported type hints for Python.","package":"typing-extensions","optional":false}],"imports":[{"note":"Preferred entry point for initializing a tracker with default emitter and subject settings.","symbol":"Snowplow","correct":"from snowplow_tracker import Snowplow"},{"note":"While direct instantiation of Tracker, Emitter, and Subject is possible, Snowplow.create_tracker is recommended for most use cases as it simplifies initialization.","wrong":"tracker = Tracker('collector.example.com')","symbol":"Tracker","correct":"from snowplow_tracker import Tracker"},{"note":"See note for Tracker; direct instantiation of components is an older pattern that is often replaced by `Snowplow.create_tracker`.","wrong":"emitter = Emitter('collector.example.com')","symbol":"Emitter","correct":"from snowplow_tracker import Emitter"},{"note":"See note for Tracker; direct instantiation of components is an older pattern that is often replaced by `Snowplow.create_tracker`.","wrong":"subject = Subject()","symbol":"Subject","correct":"from snowplow_tracker import Subject"}],"quickstart":{"code":"import os\nfrom snowplow_tracker import Snowplow, SelfDescribingJson\n\n# Configure your Snowplow collector endpoint\nCOLLECTOR_ENDPOINT = os.environ.get('SNOWPLOW_COLLECTOR_ENDPOINT', 'collector.example.com')\n\n# Initialize the Snowplow tracker\n# The namespace is mandatory and helps identify events from this tracker instance.\ntracker = Snowplow.create_tracker(namespace='my-app-tracker', endpoint=COLLECTOR_ENDPOINT)\n\n# Track a page view event\ntracker.track_page_view(\n    page_url='http://www.example.com/home',\n    page_title='Homepage',\n    referrer='http://www.example.com/previous'\n)\n\n# Track a structured event\ntracker.track_struct_event(\n    category='engagement',\n    action='click',\n    label='hero-button',\n    property='primary-cta',\n    value=1.0\n)\n\n# Track an unstructured event (Self-Describing Event)\ncustom_event_schema = SelfDescribingJson(\n    'iglu:com.example/my_custom_event/jsonschema/1-0-0',\n    {'feature': 'new-feature', 'version': '1.0'}\n)\ntracker.track_self_describing_event(custom_event_schema)\n\nprint(f\"Events tracked to {COLLECTOR_ENDPOINT} (check your Snowplow pipeline). \")","lang":"python","description":"This quickstart demonstrates how to initialize the Snowplow tracker and send various event types, including page views, structured events, and custom self-describing events. Ensure `SNOWPLOW_COLLECTOR_ENDPOINT` is set in your environment or replace `'collector.example.com'` with your actual Snowplow collector URI."},"warnings":[{"fix":"Always provide a unique `namespace` argument when calling `Snowplow.create_tracker` or directly instantiating `Tracker`.","message":"When initializing the tracker, the `namespace` argument is mandatory. Failing to provide it will result in an error or default behavior that might not be desired for identifying events from specific tracker instances.","severity":"gotcha","affected_versions":"All versions 1.x.x"},{"fix":"Ensure you are using a recent version of `snowplow-tracker` (1.x.x) and that your Snowplow data pipeline is up-to-date to fully process all event types, especially custom unstructured events.","message":"The documentation mentions that `track_screen_view()` and `track_unstruct_event()` were not fully supported in the Snowplow data pipeline's enrichment, storage, or analytics stages in older versions (e.g., v0.2, v0.4), meaning events would be logged but not processed further.","severity":"gotcha","affected_versions":"Older versions (prior to 1.x.x)"},{"fix":"Always consult the official migration guides when upgrading to a new major version of `snowplow-tracker` to understand potential API changes and necessary code adjustments. For the current 1.x.x Python tracker, refer to the 'Upgrading to newer versions' section in the Python tracker SDK documentation.","message":"The Snowplow ecosystem, particularly for mobile trackers (iOS and Android), underwent significant API changes from version 1.x to 2.0, with `Snowplow.createTracker` becoming the new entry point and the old API being deprecated. While `snowplow-tracker` for Python is currently at version 1.x.x, future major releases might introduce similar breaking changes.","severity":"breaking","affected_versions":"Future major versions (e.g., 2.x.x)"},{"fix":"Review the official Snowplow Python tracker documentation for the `track_struct_event` method to ensure correct argument names and usage. Avoid using 'property' as a keyword argument, and instead use the documented parameter (e.g., 'properties').","message":"The `track_struct_event` method does not accept a keyword argument named `property`. Using an incorrect keyword argument will result in a TypeError and application crash.","severity":"breaking","affected_versions":"All versions 1.x.x"}],"env_vars":null,"last_verified":"2026-05-12T22:46:32.144Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"pip install snowplow-tracker","cause":"The 'snowplow-tracker' library is not installed in the current Python environment, or the environment is not correctly activated.","error":"ModuleNotFoundError: No module named 'snowplow_tracker'"},{"fix":"from snowplow_tracker import Emitter, Tracker\nemitter = Emitter('collector.example.com')\ntracker = Tracker([emitter])","cause":"The `emitters` argument provided to the `Tracker` constructor was not a list containing `Emitter` instances.","error":"TypeError: emitters must be a list of Emitter objects"},{"fix":"event_json = {\"schema\": \"iglu:com.example/my_event/jsonschema/1-0-0\", \"data\": {\"key\": \"value\"}}\ntracker.track_self_describing_event(event_json)","cause":"A self-describing event or custom context dictionary was provided without the required 'schema' and 'data' keys, or they were malformed.","error":"ValueError: Self-describing event payload must contain 'schema' and 'data' fields."},{"fix":"from snowplow_tracker import Emitter, Tracker\nemitter = Emitter('collector.example.com')\ntracker = Tracker([emitter], tracker_name=\"my_application\")","cause":"The `tracker_name` parameter during `Tracker` initialization was provided with a non-string value.","error":"TypeError: tracker_name must be a string"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.1.0","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.61,"mem_mb":11.2,"disk_size":"21.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.69,"mem_mb":11,"disk_size":"21.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.1,"import_time_s":0.47,"mem_mb":11.2,"disk_size":"22M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.51,"mem_mb":11,"disk_size":"22M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.79,"mem_mb":12.3,"disk_size":"24.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.95,"mem_mb":12.2,"disk_size":"23.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.2,"import_time_s":0.69,"mem_mb":12.3,"disk_size":"24M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.74,"mem_mb":12.2,"disk_size":"24M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.68,"mem_mb":12,"disk_size":"15.7M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.76,"mem_mb":11.9,"disk_size":"15.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2,"import_time_s":0.68,"mem_mb":12,"disk_size":"16M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.83,"mem_mb":11.9,"disk_size":"16M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.68,"mem_mb":12.2,"disk_size":"15.5M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.79,"mem_mb":12.1,"disk_size":"15.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2,"import_time_s":0.64,"mem_mb":12.2,"disk_size":"16M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.77,"mem_mb":12.1,"disk_size":"16M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.54,"mem_mb":10.8,"disk_size":"21.1M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.62,"mem_mb":10.8,"disk_size":"21.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.5,"import_time_s":0.52,"mem_mb":10.8,"disk_size":"22M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":10.8,"disk_size":"22M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}