track_event() mechanism for analytics and plugins

* Closes #2240
* Documentation for event plugin hooks, refs #2240
* Include example track_event plugin in docs, refs #2240
* Tests for track_event() and register_events() hooks, refs #2240
* Initial documentation for core events, refs #2240
* Internals documentation for datasette.track_event()
This commit is contained in:
Simon Willison 2024-01-31 15:21:40 -08:00 committed by GitHub
commit bcc4f6bf1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 614 additions and 10 deletions

View file

@ -9,8 +9,9 @@ from .fixtures import (
TestClient as _TestClient,
) # noqa
from click.testing import CliRunner
from dataclasses import dataclass
from datasette.app import Datasette
from datasette import cli, hookimpl, Permission
from datasette import cli, hookimpl, Event, Permission
from datasette.filters import FilterArguments
from datasette.plugins import get_plugins, DEFAULT_PLUGINS, pm
from datasette.utils.sqlite import sqlite3
@ -18,6 +19,7 @@ from datasette.utils import CustomRow, StartupError
from jinja2.environment import Template
from jinja2 import ChoiceLoader, FileSystemLoader
import base64
import datetime
import importlib
import json
import os
@ -1437,3 +1439,30 @@ async def test_hook_top_canned_query(ds_client):
assert "Xtop_query:fixtures:from_hook:xyz" in response.text
finally:
pm.unregister(name="SlotPlugin")
@pytest.mark.asyncio
async def test_hook_track_event():
datasette = Datasette(memory=True)
from .conftest import TrackEventPlugin
await datasette.invoke_startup()
await datasette.track_event(
TrackEventPlugin.OneEvent(actor=None, extra="extra extra")
)
assert len(datasette._tracked_events) == 1
assert isinstance(datasette._tracked_events[0], TrackEventPlugin.OneEvent)
event = datasette._tracked_events[0]
assert event.name == "one"
assert event.properties() == {"extra": "extra extra"}
# Should have a recent created as well
created = event.created
assert isinstance(created, datetime.datetime)
assert created.tzinfo == datetime.timezone.utc
@pytest.mark.asyncio
async def test_hook_register_events():
datasette = Datasette(memory=True)
await datasette.invoke_startup()
assert any(k.__name__ == "OneEvent" for k in datasette.event_classes)