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
14 changes: 8 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@ name: Tests

on: [push]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.5', '3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12', 'pypy2', 'pypy3']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.9', 'pypy3.11']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install -r requirements-testing.txt
pip install -e .[test]
- name: Test with pytest
run: |
pytest test_mixpanel.py
16 changes: 8 additions & 8 deletions BUILD.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ Release process::
6. Rebuild docs and publish to GitHub Pages (if appropriate -- see below)
7. Publish to PyPI. (see below)

Install test and developer environment modules::
pip install -e .[test,dev]

Run tests::

tox
python -m tox - runs all tests against all configured environments in the pyproject.toml

Publish to PyPI::

pip install twine wheel
python setup.py sdist bdist_wheel
twine upload dist/*
python -m build
python -m twine upload dist/*

Build docs::

pip install sphinx
python setup.py build_sphinx
python -m sphinx -b html docs docs/_build/html

Publish docs to GitHub Pages::

pip install ghp-import
ghp-import -n -p build/sphinx/html
python -m ghp_import -n -p docs/_build/html
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v4.11.0
* Set minimum supported python version to 3.9, deprecating support for end-of-life versions of python
* Convert setup.py to pyproject.toml

v4.9.0
* To reduce TLS cert friction, use requests rather than directly using urllib3.
Reinstate TLS cert validation by default. (#103)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2013-2021 Mixpanel, Inc.
Copyright 2013-2025 Mixpanel, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
6 changes: 3 additions & 3 deletions demo/subprocess_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ def do_tracking(project_token, distinct_id, queue):
'''
consumer = QueueWriteConsumer(queue)
mp = Mixpanel(project_token, consumer)
for i in xrange(100):
for i in range(100):
event = 'Tick'
mp.track(distinct_id, event, {'Tick Number': i})
print 'tick {0}'.format(i)
print(f'tick {i}')

queue.put(None) # tell worker we're out of jobs

Expand All @@ -64,7 +64,7 @@ def do_sending(queue):
if __name__ == '__main__':
# replace token with your real project token
token = '0ba349286c780fe53d8b4617d90e2d01'
distinct_id = ''.join(random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for x in xrange(32))
distinct_id = ''.join(random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for x in range(32))

queue = multiprocessing.Queue()
sender = multiprocessing.Process(target=do_sending, args=(queue,))
Expand Down
9 changes: 3 additions & 6 deletions mixpanel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
Analytics updates. :class:`~.Consumer` and :class:`~.BufferedConsumer` allow
callers to customize the IO characteristics of their tracking.
"""
from __future__ import absolute_import, unicode_literals
import datetime
import json
import logging
Expand All @@ -23,11 +22,9 @@

import requests
from requests.auth import HTTPBasicAuth
import six
from six.moves import range
import urllib3

__version__ = '4.10.1'
__version__ = '4.11.0'
VERSION = __version__ # TODO: remove when bumping major version.

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -620,7 +617,7 @@ def _write_request(self, request_url, json_message, api_key=None, api_secret=Non
verify=self._verify_cert,
)
except Exception as e:
six.raise_from(MixpanelException(e), e)
raise MixpanelException(e) from e

try:
response_dict = response.json()
Expand Down Expand Up @@ -733,6 +730,6 @@ def _flush_endpoint(self, endpoint):
mp_e = MixpanelException(orig_e)
mp_e.message = batch_json
mp_e.endpoint = endpoint
six.raise_from(mp_e, orig_e)
raise mp_e from orig_e
buf = buf[self._max_size:]
self._buffers[endpoint] = buf
58 changes: 58 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "mixpanel"
dynamic = ["version"]
description = "Official Mixpanel library for Python"
readme = "README.rst"
license = "Apache-2.0"
authors = [
{name = "Mixpanel, Inc.", email = "dev@mixpanel.com"},
]
requires-python = ">=3.9"
dependencies = [
"requests>=2.32.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm 🤔 maybe it's time to try httpx? opens door for async support as well

Copy link
Contributor Author

@efahk efahk Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea that door's definitely open now. I'll trial it with the incoming feature flag code in the next PR. Native async would be great

Copy link
Contributor

@hans-lizihan hans-lizihan Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since its major version bump, prob do in the 5.0 release?

We can prob. tag a few rcs as well

]
keywords = ["mixpanel", "analytics"]
classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]

[project.urls]
Homepage = "https://github.com/mixpanel/mixpanel-python"

[project.optional-dependencies]
test = [
"pytest>=8.4.1",
"responses>=0.25.8",
]
dev = [
"tox>=4.28.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still need tox?

Copy link
Contributor Author

@efahk efahk Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep it around for now since tox's utility is just to abstract away looping over different python interpreter versions and running pytest against each

The alternative is scripting that ourselves. With UV, it'd probably look like for $py in [3.9,3.10,...]:uv run --python $py pytest

"build",
"twine",
"sphinx",
"ghp-import",
]

[tool.setuptools.dynamic]
version = {attr = "mixpanel.__version__"}

[tool.setuptools.packages.find]
exclude = ["demo"]

[tool.tox]
envlist = ["py39", "py310", "py311", "py312"]

[tool.tox.env_run_base]
extras = ["test"]
commands = [
["pytest", "{posargs}"],
]
6 changes: 0 additions & 6 deletions requirements-testing.txt

This file was deleted.

2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

50 changes: 0 additions & 50 deletions setup.py

This file was deleted.

Loading