{"id":13625120,"url":"https://github.com/mikeckennedy/umami-python","last_synced_at":"2026-02-03T07:03:20.019Z","repository":{"id":217720694,"uuid":"744631158","full_name":"mikeckennedy/umami-python","owner":"mikeckennedy","description":"Umami Analytics Client for Python","archived":false,"fork":false,"pushed_at":"2024-04-19T00:42:13.000Z","size":84,"stargazers_count":68,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-27T00:04:42.932Z","etag":null,"topics":["analytics","dashboards","events","privacy","python","umami","umami-analytics","website"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikeckennedy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["mikeckennedy"]}},"created_at":"2024-01-17T17:36:05.000Z","updated_at":"2025-02-15T21:28:07.000Z","dependencies_parsed_at":"2024-03-18T21:12:14.892Z","dependency_job_id":"7948ad59-38cb-4ff2-89ae-c3813dee50eb","html_url":"https://github.com/mikeckennedy/umami-python","commit_stats":null,"previous_names":["mikeckennedy/umami-python"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikeckennedy%2Fumami-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikeckennedy%2Fumami-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikeckennedy%2Fumami-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikeckennedy%2Fumami-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikeckennedy","download_url":"https://codeload.github.com/mikeckennedy/umami-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243718809,"owners_count":20336589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","dashboards","events","privacy","python","umami","umami-analytics","website"],"created_at":"2024-08-01T21:01:51.088Z","updated_at":"2026-02-03T07:03:20.007Z","avatar_url":"https://github.com/mikeckennedy.png","language":"Python","readme":"# Umami Analytics Client for Python\n\nClient for privacy-preserving, open source [Umami analytics platform](https://umami.is) based on \n`httpx` and `pydantic`. \n\n`umami-analytics` is intended for adding custom data to your Umami instance (self-hosted or SaaS). Many umami events can supplied directly from HTML via their `data-*` attributes. However, some cannot. For example, if you have an event that is triggered in your app but doesn't have a clear HTML action you can add custom events. These will appear at the bottom of your Umami analtytics page for a website.\n\nOne example is a **purchase-course** event that happens deep inside the Python code rather than in HTML at [Talk Python Training](https://training.talkpython.fm). This is what our events section looks like for a typical weekend day (US Pacific Time):\n\n![](https://raw.githubusercontent.com/mikeckennedy/umami-python/main/readme_resources/events-example.jpg)\n\n## Focused on what you need, not what is offered\n\nThe [Umami API is extensive](https://umami.is/docs/api) and much of that is intended for their frontend code to be able to function. You probably don't want or need that. `umami-analytics` only covers the subset that most developers will need for common SaaS actions such as adding [custom events](https://umami.is/docs/event-data). That said, PRs are weclome.\n\n## Core Features\n\n* ➕ **Add a custom event** to your Umami analytics dashboard.\n* 📄 **Add a page view** to your Umami analytics dashboard.\n* 🌐 List all websites with details that you have registered at Umami.\n* 📊 **Get website statistics** including page views, visitors, bounce rate, and more.\n* 👥 **Get active users** count for real-time monitoring.\n* 💓 **Heartbeat check** to verify Umami server connectivity.\n* 🔀 Both **sync** and **async** programming models.\n* ⚒️ **Structured data with Pydantic** models for API responses.\n* 👩‍💻 **Login / authenticate** for either a self-hosted or SaaS hosted instance of Umami.\n* 🥇Set a **default website** for a **simplified API** going forward.\n* 🔧 **Enable/disable tracking** for development and testing environments.\n\n## Development and Testing Support\n\n🔧 **Disable tracking in development**: Use `umami.disable()` to disable all event and page view tracking without changing your code. Perfect for development and testing environments where you don't want to pollute your analytics with test data.\n\n```python\nimport umami\n\n# Configure as usual\numami.set_url_base(\"https://umami.hostedbyyouorthem.com\")\numami.set_website_id('cc726914-8e68-4d1a-4be0-af4ca8933456')\numami.set_hostname('somedomain.com')\n\n# Disable tracking for development/testing\numami.disable()\n\n# These calls will return immediately without sending data to Umami\numami.new_event('test-event')  # No HTTP request made\numami.new_page_view('Test Page', '/test')  # No HTTP request made\n\n# Re-enable when needed (default state is enabled)\numami.enable()\n```\n\nWhen tracking is disabled:\n- ✅ **No HTTP requests** are made to your Umami server\n- ✅ **API calls still validate** parameters (helps catch configuration issues)\n- ✅ **All other functions work normally** (login, websites, stats, etc.)\n- ✅ **Functions return appropriate values** for compatibility\n\nSee the usage example below for the Python API around these features.\n\n## Async or sync API? You choose\n\n🔀 **Async is supported but not required** for your Python code. For functions that access the network, there is a `func()` and `func_async()` variant that works with Python's `async` and `await`.\n\n## Installation\n\nJust `pip install umami-analytics`\n\n## Usage\n\n```python\n\nimport umami\n\numami.set_url_base(\"https://umami.hostedbyyouorthem.com\")\n\n# Auth is NOT required to send events, but is for other features.\nlogin = umami.login(username, password)\n\n# Skip the need to pass the target website in subsequent calls.\numami.set_website_id('cc726914-8e68-4d1a-4be0-af4ca8933456')\numami.set_hostname('somedomain.com')\n\n# Optional: Disable tracking for development/testing\n# umami.disable()  # Uncomment to disable tracking\n\n# List your websites\nwebsites = umami.websites()\n\n# Create a new event in the events section of the dashboards.\nevent_resp = umami.new_event(\n    website_id='a7cd-5d1a-2b33', # Only send if overriding default above\n    event_name='Umami-Test',\n    title='Umami-Test', # Defaults to event_name if omitted.\n    hostname='somedomain.com', # Only send if overriding default above.\n    url='/users/actions',\n    custom_data={'client': 'umami-tester-v1'},\n    referrer='https://some_url')\n\n# Create a new page view in the pages section of the dashboards.\npage_view_resp = umami.new_page_view(\n    website_id='a7cd-5d1a-2b33', # Only send if overriding default above\n    page_title='Umami-Test', # Defaults to event_name if omitted.\n    hostname='somedomain.com', # Only send if overriding default above.\n    url='/users/actions',\n    referrer='https://some_url')\n\n# Get website statistics for a date range\nfrom datetime import datetime, timedelta\n\nend_date = datetime.now()\nstart_date = end_date - timedelta(days=7)  # Last 7 days\n\nstats = umami.website_stats(\n    start_at=start_date,\n    end_at=end_date,\n    website_id='a7cd-5d1a-2b33'  # Only send if overriding default above\n)\nprint(f\"Page views: {stats.pageviews}\")\nprint(f\"Unique visitors: {stats.visitors}\")\nprint(f\"Bounce rate: {stats.bounces}\")\n\n# Get current active users count\nactive_count = umami.active_users(\n    website_id='a7cd-5d1a-2b33'  # Only send if overriding default above\n)\nprint(f\"Currently active users: {active_count}\")\n\n# Check if Umami server is accessible\nserver_ok = umami.heartbeat()\nprint(f\"Umami server is {'accessible' if server_ok else 'not accessible'}\")\n\n# Call after logging in to make sure the auth token is still valid.\numami.verify_token()\n```\n\nThis code listing is very-very high fidelity pseudo code. If you want an actually executable example, see the [example client](https://github.com/mikeckennedy/umami-python/tree/main/umami/example_client) in the repo.\n\n## Want to contribute?\n\nSee the [API documentation](https://umami.is/docs/api) for the remaining endpoints to be added. PRs are welcome. But please open an issue first to see if the proposed feature fits with the direction of this library.\n\nEnjoy.","funding_links":["https://github.com/sponsors/mikeckennedy"],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikeckennedy%2Fumami-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikeckennedy%2Fumami-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikeckennedy%2Fumami-python/lists"}