Simple API clients for mkStats
Project description
mkStats Python Client
Production-oriented Python clients for mkStats API.
Package contents
mkstats_client: client based onrequestsmkstats_embed: client based on Python stdlib (urllib)
Both clients support the same behavior:
device_fingerprintpayload support- PoW challenge flow for
/handshake - automatic re-auth on
401 invalid_install_token - backoff on
429withRetry-After - buffered events with
queue_event()andflush_events()
Requirements
- Python
>= 3.10 - mkStats backend API (
/apior/api/v1)
Installation
From PyPI:
pip install mkstats-client
Local development from this repository:
python -m venv .venv
.\.venv\Scripts\activate
pip install -e .\client
Quick start (requests client)
from mkstats_client import MkStatsClient, generate_user_hash, generate_device_fingerprint
api_url = "https://mkstats.mk69.su/api/v1" # /api or /api/v1 both work
plugin_id = "my_plugin"
plugin_version = "1.0.0"
device_id = "stable-device-id"
user_hash = generate_user_hash(device_id, plugin_id)
device_fingerprint = generate_device_fingerprint(device_id)
client = MkStatsClient(
api_url=api_url,
plugin_id=plugin_id,
plugin_version=plugin_version,
user_hash=user_hash,
device_fingerprint=device_fingerprint,
client_name="exteraGram",
client_version="12.3.1",
)
client.handshake()
client.send_ping()
client.track_event("feature_clicked")
Quick start (embed client)
from mkstats_embed import MkStatsCoreClient, generate_user_hash, generate_device_fingerprint
api_url = "https://mkstats.mk69.su/api/v1"
plugin_id = "my_plugin"
plugin_version = "1.0.0"
device_id = "stable-device-id"
user_hash = generate_user_hash(device_id, plugin_id)
device_fingerprint = generate_device_fingerprint(device_id)
client = MkStatsCoreClient(
api_url=api_url,
plugin_id=plugin_id,
plugin_version=plugin_version,
user_hash=user_hash,
device_fingerprint=device_fingerprint,
client_name="exteraGram",
client_version="12.3.1",
)
client.handshake()
client.send_ping()
client.track_event("feature_clicked")
API overview
Main methods available in both clients:
handshake() -> dict: obtainsinstall_token, solves PoW automatically if requiredsend_ping(install_token: str | None = None, timestamp: int | None = None) -> dictsend_event(install_token: str | None, event: str, count: int = 1, timestamp: int | None = None) -> dicttrack_event(event: str, count: int = 1, timestamp: int | None = None) -> dictqueue_event(event: str, count: int = 1) -> Noneflush_events(force: bool = False) -> boolheartbeat(interval_seconds: int = 1500, iterations: int | None = None, flush_buffered_events: bool = True) -> None
Helpers:
generate_user_hash(device_id: str, plugin_id: str) -> strgenerate_device_fingerprint(device_id: str) -> strget_client_name() -> strget_exteragram_version() -> str
Failure behavior
- On
401, clients reset token, runhandshake(), and retry request once. - On
409 metric_not_initializedfrom/event, callsend_ping()first. - On
429, clients enter backoff mode. - While in backoff, network methods return empty dicts instead of raising.
- Event names are normalized to backend-safe format: first char
[A-Za-z_], then[A-Za-z0-9_.:-], max 100 chars.
Buffered events example
client.queue_event("feature_opened")
client.queue_event("feature_opened")
client.queue_event("button_clicked")
ok = client.flush_events()
if not ok:
# network/backoff issue: unsent events stay in internal queue
pass
Build and publish
From repository root:
python -m pip install -U build twine
python -m build .\client
python -m twine check .\client\dist\*
Upload to TestPyPI:
python -m twine upload --repository testpypi .\client\dist\*
Before each release, bump version in client/pyproject.toml.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mkstats_client-0.2.1.tar.gz.
File metadata
- Download URL: mkstats_client-0.2.1.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b110d4a221b89f1f7c61bdfdfeab999f9436f2d8290e11876569b1bb9a535c49
|
|
| MD5 |
0722f03a1b21cb888991d9529de71e00
|
|
| BLAKE2b-256 |
d2056843bbf67bda95457d83b220768bfc5e20d2df32cdcbdc70e047c8d80f27
|
File details
Details for the file mkstats_client-0.2.1-py3-none-any.whl.
File metadata
- Download URL: mkstats_client-0.2.1-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5851bb13533856be0360403ef463419d61f42662d6e9a5a223078ea60e0db89
|
|
| MD5 |
5cdee90618640b4b01058375eadf4f24
|
|
| BLAKE2b-256 |
21ca4170b1d35e850f89ddc38aa9bace557868d1e438088ae9cd62ed01b74385
|