Changelog
This changelog is generated automatically from GitHub Releases.
v1.0.0
2026-06-11 · GitHub
[1.0.0]
First stable release. The package is now marked Development Status :: 5 - Production/Stable (it has been used in production at Talk Python Training for some time) and follows SemVer from here forward.
Changed
- Promoted the trove classifier from
4 - Betato5 - Production/Stable, and added theTyping :: Typedclassifier to advertise the bundledpy.typedmarker. - Expanded the PyPI keyword set (added web-analytics, privacy, tracking, metrics, events, page-views, telemetry, statistics, self-hosted, async, httpx, pydantic, sdk, api-client) for better discoverability.
Added
pydantic.Field(description=...)metadata on every response-model field, plus agriffe-pydanticdev dependency, enriching the response models for IDEs, JSON schema, and future API-reference rendering. Note: the current Great Docs version (0.13.0) does not load griffe extensions, so the rendered field docs still come from the docstringAttributes:sections; the Field descriptions will surface on the docs site once the generator loads the extension.
Changed
- Synchronous send functions now return the Umami API’s JSON response as a dict (and
{}when tracking is disabled), matching their async twins. Previously new_event(), new_revenue_event(), and new_page_view() returnedNone; new_page_view_async() also now returns the response dict instead ofNone. - Missing or blank required event fields (hostname, website_id, event_name) now raise umami.errors.ValidationError instead of a bare
Exception, so they can be caught alongside the SDK’s other validation errors. Website.shareId,Website.resetAt, andWebsite.deletedAtare now optional (defaultNone), so a websites response that omits those keys no longer raisespydantic.ValidationError.- README now points to the new documentation site at https://mkennedy.codes/docs/umami-python/ (added status badges, a documentation pointer near the top, and a “Documentation” section linking the full API reference). Docs-only change — no code or packaging changes.
- Docstrings across the public API were expanded and corrected for the generated documentation site (Great Docs renders them verbatim, and they feed
llms.txt). AddedRaises:sections to every raising function; fixed website_stats() / website_stats_async() to document their real return type (models.WebsiteStats, not the nonexistentWebsiteStatsResponse); removed unprofessional/inaccurate prose from verify_token (the “minutes, hours, or years” hedge) and new_event (the “not sure how this is different” aside); corrected new_page_view wording (visitor; theuauser-agent string); clarified that disable() still validates before skipping the HTTP request and that both affect only the send functions; documented all response models and exception classes; added a package module docstring; and added runnable usage examples. Docstring-only — no code or behavior changes.
Fixed
validate_event_datano longer lets a whitespace-onlyevent_namethrough (the check usedand, so whitespace bypassed it; it now usesor).
v0.6.25
2026-06-07 · GitHub
[0.6.25] - 2026-06-07
Added
distinct_idsupport in new_event, new_page_view, and new_revenue_event payloads (sync and async), sent to Umami as payload fieldid- Umami Cloud API-key authentication via
set_cloud_api_key(key, region=None)and clear_cloud_api_key(). In Cloud mode, data/management calls route tohttps://api.umami.is/v1[/region]with anx-umami-api-keyheader, and events are sent tohttps://cloud.umami.is/api/send— no set_url_base() or login() required. Existing self-hosted (login() + token) usage is byte-for-byte unchanged. Addedurls.mefor Cloud key validation in verify_token/verify_token_async. In Cloud mode, heartbeat() / heartbeat_async() check liveness via the authenticated/meendpoint (Cloud has no/api/heartbeat), and login() / login_async() raise OperationNotAllowedError to fail fast (the API key is the credential — there is no username/password login on Cloud).
Changed
validate_stateerror messages now mention set_cloud_api_key() alongside set_url_base() / login(). Same exception type (OperationNotAllowedError) and trigger conditions; text only.- Response models are more tolerant of variant/partial responses:
WebsiteStats.comparisonandWebsite.userare now optional, and Website acceptscreateUser(returned by team-website listings, whereuserIdis null). Successful responses today are unaffected. - Internal: expanded the unit test suite (now 128 tests) following a suite review — added behavioral coverage for set_url_base validation, the
validate_stateguards, the login/login_async happy path and response-model deserialization (LoginResponse, WebsitesResponse), websites/websites_async, the disable() no-op (asserting no HTTP request is made),ip_addresspayload inclusion/omission, explicit-arg-overrides-defaults precedence, heartbeat_async self-hosted, and the verify_token/heartbeat failure branches. Added a sync/async parity harness and consolidated the per-file HTTP mock builders into a sharedtests/_mocks.py(net ~210 fewer lines). No production behavior changed.
Fixed
- website_stats_async() sent its date range as snake_case
start_at/end_atquery params, which the Umami API ignores — it silently returned all-time stats regardless of the requested window. Now sends camelCasestartAt/endAt, matching the sync website_stats(). (#18) - active_users() and active_users_async() read the active-visitor count from a non-existent
xkey, so they always returned0. They now read Umami’s currentvisitorskey (falling back to the legacyxkey for compatibility). (#19) - website_stats() / website_stats_async() sent their
urlandhostfilters under the old query-param names, which Umami renamed on 2025-10-07 (url→path,host→hostname) — so filtering stats by URL or hostname was a silent no-op. The publicurl/hostkeyword arguments are unchanged; they now map to the currentpath/hostnamewire names. (#20) - heartbeat() / heartbeat_async() issued a
POSTto/api/heartbeat, which current Umami answers with405 Method Not Allowed; the broad exception handler swallowed the error so the call always returnedFalseeven against a healthy server. They now issue aGET(the endpoint returns{"ok": true}). - new_event() and new_revenue_event() (sync) defaulted
urlto'/event-api-endpoint'while their async twins used'/'. All four now default to'/', so the sync/async twins agree and no placeholder path appears in dashboards.
v0.5.24
2026-06-04 · GitHub
[0.5.24] - 2026-06-04
Changed
- Migrated HTTP backend from
httpxtohttpx2, imported asimport httpx2 as httpxso all call sites remain unchanged - Files:
umami/umami/impl/__init__.py,umami/requirements.txt,umami/pyproject.toml,pyrefly.toml,README.md,umami/README.md
v0.4.23
2026-03-13 · GitHub
[0.4.23]
Added
- new_revenue_event() and new_revenue_event_async() for tracking revenue with Umami’s new revenue feature
- Revenue events automatically inject
revenue(float) andcurrency(ISO 4217 string) into event custom data - Input validation: revenue must be a number >= 0, currency must be a non-empty string
- Defaults to
event_name='revenue'andcurrency='USD'for simple usage - 15 new tests covering sync/async revenue events, validation, and edge cases
v0.3.22
2026-02-03 · GitHub
[0.3.22] - 2026-02-02
Fixed
- new_event_async crashed with
binascii.Errordue to erroneousbase64.b64decode/json.loadscalls on the plain-JSON API response; now returnsresp.json()directly, matching the other event and page-view methods
v0.3.21
2025-12-12 · GitHub
Added
- Change-log preservation section for tracking historical release details
- Pyrefly configuration file treating
umami/umamipackage as type-resolution root
Changed
- Centralized all version information into a single location for easier maintenance
- Updated Python requirement to 3.10+ (dropped support for Python 3.8 and 3.9)
- Refactored WebsiteStats to use plain integers instead of custom
Metrictype - Thanks @rubitcat (#15) - Updated
ruff.tomlto enforce consistent import ordering
Fixed
- Suppressed and cleaned up unnecessary type-checking warnings
v0.2.20
2025-05-31 · GitHub
Umami-Python Release Notes
Since 5fa35183 (7 commits)
🚀 New Features
- Development and Testing Tracking: Added options to disable tracking for development and testing environments. This allows users to control data collection based on their needs.
When tracking is disabled:
- ✅ No HTTP requests are made to your Umami server
- ✅ API calls still validate parameters (helps catch configuration issues)
- ✅ All other functions work normally (login, websites, stats, etc.)
- ✅ Functions return appropriate values for compatibility
📚 Documentation
- Documented the heartbeat check feature for monitoring system health.
- Added documentation for new methods in the Umami API:
get_heartbeatandenabled/disable.
🧹 Maintenance
- Sorted some imports in various files to improve code organization and readability.
- Fixed a minor typo in the documentation, ensuring consistency across the project.
v0.2.19
2025-05-31 · GitHub
Umami-Python Release Notes
Since 1d17c014 (16 commits)
🚀 New Features
- Heartbeat Functions: Added asynchronous (heartbeat_async) and synchronous (heartbeat) versions of the existing heartbeat function for improved import flexibility.
- Added website stats and active users functions (website_stats, active_users) Thanks @orangethewell
🐛 Bug Fixes
- Login Fix: Corrected the API data handling from
datatojsonin the login process. Originally, this was not a problem with the server, but it has started failing. If you have encountered login errors, this may fix it.
⚡ Performance
- Heartbeat Function Optimization: Improved the performance of the heartbeat function by optimizing its execution flow.
v0.2.18
2025-05-31 · GitHub
Umami-Python Release Notes
Since 3a08f77a (2 commits)
🚀 New Features
- Python Version Update: Upgraded to Python 3.13 and 3.14, providing better support for modern applications.
🐛 Bug Fixes
- API Call Method Fix: Corrected the use of
datainstead ofjsonin login API calls, ensuring proper data transmission.
Originally, this was not a problem with the server, but it has started failing. If you have encountered login errors, this may fix it.
v0.2.17
2024-04-19 · GitHub
Adds is_logged_in() -> bool method to check whether login has been called and was successful.
v0.2.15
2024-03-01 · GitHub
- Fixes schema change from Umami 2.9 to 2.10 on websites response
- Includes new heartbeat function from 0.1.14 release
v0.1.14
2024-03-01 · GitHub
Add heartbeat API endpoint.
v0.1.13
2024-02-13 · GitHub
Support IP address in new_event and new_page_view payloads, see issue #2.
It looks like Umami added the IP data field in the payload (see https://github.com/umami-software/umami/pull/2479 ). It’s not clear when the feature will be released in a new build ( https://github.com/umami-software/umami/releases ). But in preparation, I added the id_address parameter to both new_event and new_page_view as well as their async twins.
This is out in version 0.1.13 and on PyPI at https://pypi.org/project/umami-analytics/0.1.13/ Thanks for the idea @ddxv
v0.1.12
2024-01-27 · GitHub
Add ability to pass alternative user agent to events (but be careful, umami blocks what it perceives as bots).
v0.1.11
2024-01-24 · GitHub
- Added method: new_page_view() and new_page_view_async().
- Dropped auth requirement for new event, it’s not needed (see #1 )
v0.1.10
2024-01-22 · GitHub
- Added platform type (e.g. Windows) to user agent.
- Added doc strings to most methods.
- Bump the version for next release.
- Added better validation for some functions.
- Added custom error types for validation.
v0.1.9
2024-01-21 · GitHub
First real release outside our own apps. Enjoy!