wagtail-experiments


Namewagtail-experiments JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://github.com/torchbox/wagtail-experiments
SummaryA/B testing for Wagtail
upload_time2023-11-06 20:37:51
maintainer
docs_urlNone
authorMatthew Westcott
requires_python>=3.8
licenseBSD
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: wagtail-experiments.png

Wagtail Experiments
===================

**A/B testing for Wagtail**

This module supports the creation of A/B testing experiments within a Wagtail site. Several alternative versions of a page are set up, and on visiting a designated control page, a user is presented with one of those variations, selected at random (using a simplified version of the `PlanOut algorithm <https://facebook.github.io/planout/>`_). The number of visitors receiving each variation is logged, along with the number that subsequently go on to complete the experiment by visiting a designated goal page.


Installation
------------

wagtail-experiments is compatible with Wagtail 4.1 to 5.2, and Django 3.2 to 4.2. It depends on the Wagtail ModelAdmin module, which is available as an external package as of Wagtail 5.0; we recommend using this rather than the bundled `wagtail.contrib.modeladmin` module to avoid deprecation warnings. The external package will be required as of Wagtail 6.0.

### On Wagtail 5.0 and above

To install::

    pip install wagtail-experiments wagtail-modeladmin

and ensure that the apps ``wagtail_modeladmin`` and ``experiments`` are included in your project's ``INSTALLED_APPS``:

.. code-block:: python

    INSTALLED_APPS = [
        # ...
        'wagtail_modeladmin',
        'experiments',
        # ...
    ]

Then migrate::

    ./manage.py migrate

### On Wagtail 4.x

To install::

    pip install wagtail-experiments

and ensure that the apps ``wagtail.contrib.modeladmin`` and ``experiments`` are included in your project's ``INSTALLED_APPS``:

.. code-block:: python

    INSTALLED_APPS = [
        # ...
        'wagtail.contrib.modeladmin',
        'experiments',
        # ...
    ]

Then migrate::

    ./manage.py migrate

Usage
-----

After installation, a new 'Experiments' item is added to the Wagtail admin menu under Settings. This is available to superusers and any other users with add/edit permissions on experiments. An experiment is created by specifying a control page and any number of alternative versions of that page, along with an optional goal page. Initially the experiment is in the 'draft' status and does not take effect on the site front-end; to begin the experiment, change the status to 'live'.

When the experiment is live, a user visiting the URL of the control page will be randomly assigned to a test group, to be served either the control page or one of the alternative variations. This assignment persists for the user's session (according to `Django's session configuration <https://docs.djangoproject.com/en/1.10/topics/http/sessions/#browser-length-sessions-vs-persistent-sessions>`_) so that each user receives the same variation each time. When a user subsequently visits the goal page, they are considered to have completed the experiment and a completion is logged against that user's test group. The completion rate over time for each test group can then be viewed through the admin interface, under 'View report'.

.. image:: https://i.imgur.com/tG7JH13.png
   :width: 728 px

From the report page, an administrator can select a winning variation; the experiment status is then changed to 'completed', and all visitors to the control page are served the chosen variation.

Typically, the alternative versions of the page will be left unpublished, as this prevents them from appearing as duplicate copies of the control page in the site navigation. If an unpublished page is selected as an alternative, the page revision shown to users on the front-end will be the draft revision that existed at the moment the experiment status was set to 'live'. When displaying an alternative variation, the title and tree location are overridden to appear as the control page's title and location; this means that the title of the alternative page can be set to something descriptive, such as "Signup page (blue text)", without this text 'leaking' to site visitors.


Direct URLs for goal completion
-------------------------------

If you want goal completion to be linked to some action other than visiting a designated Wagtail page - for example, clicking a 'follow us on Twitter' link - you can set up a Javascript action that sends a request to a URL such as ``/experiments/complete/twitter-follow/`` , where ``twitter-follow`` is the experiment slug. To set this URL route up, add the following to your URLconf:

.. code-block:: python

    from experiments import views as experiment_views

    urlpatterns = [
        # ...

        url(r'^experiments/complete/([^\/]+)/$', experiment_views.record_completion),

        # ...
    ]


Alternative backends
--------------------

wagtail-experiments supports pluggable backends for tracking participants and completions. The default backend, ``experiments.backends.db``, records these in a database table, aggregated by day. Alternative backends can be specified through the ``WAGTAIL_EXPERIMENTS_BACKEND`` setting:

.. code-block:: python

    WAGTAIL_EXPERIMENTS_BACKEND = 'mypackage.backends.thecloud'

A backend is a Python module that provides the following functions:

**record_participant(experiment, user_id, variation, request):**

Called when a user visits the control page for ``experiment``. ``user_id`` is the persistent user ID assigned to that visitor; ``variation`` is the Page object for the variation to be served; and ``request`` is the user's current request.

**record_completion(experiment, user_id, variation, request):**

Called when a visitor completes the ``experiment``, either by visiting the goal page or triggering the ``record_completion``. ``user_id`` is the persistent user ID assigned to that visitor; ``variation`` is the Page object for the variation that was originally served to that user; and ``request`` is the user's current request.

**get_report(experiment):**

Returns report data for ``experiment``, consisting of a dict containing:

``variations``
  A list of records, one for each variation (including the control page). Each record is a dict containing:

  ``variation_pk``
    The primary key of the Page object

  ``is_control``
    A boolean indicating whether this is the control page

  ``is_winner``
    A boolean indicating whether this variation has been chosen as the winner

  ``total_participant_count``
    The number of visitors who have been assigned this variation

  ``total_completion_count``
    The number of visitors assigned this variation who have gone on to complete the experiment

  ``history``
    A list of dicts showing the breakdown of participants and completions over time; each dict contains ``date``, ``participant_count`` and ``completion_count``.


Test data
---------

wagtail-experiments provides a management command ``experiment-data``, to allow populating an experiment with dummy data for testing or demonstration purposes, and purging existing data. This command is called with the experiment's slug::

    # Populate the experiment 'homepage-banner' with 5 days of test data,
    # with 100-200 views per variation. All parameters other than experiment slug
    # are optional
    ./manage.py experiment-data homepage-banner --days 5 --min=100 --max=200

    # Purge data for the experiment 'homepage-banner'
    ./manage.py experiment-data homepage-banner --purge

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/torchbox/wagtail-experiments",
    "name": "wagtail-experiments",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "",
    "author": "Matthew Westcott",
    "author_email": "matthew.westcott@torchbox.com",
    "download_url": "https://files.pythonhosted.org/packages/c4/ac/97ab54c756a3222a7918b358b583d2a1756bdd5e17b9ecf003c0579fdf88/wagtail-experiments-0.3.1.tar.gz",
    "platform": null,
    "description": ".. image:: wagtail-experiments.png\n\nWagtail Experiments\n===================\n\n**A/B testing for Wagtail**\n\nThis module supports the creation of A/B testing experiments within a Wagtail site. Several alternative versions of a page are set up, and on visiting a designated control page, a user is presented with one of those variations, selected at random (using a simplified version of the `PlanOut algorithm <https://facebook.github.io/planout/>`_). The number of visitors receiving each variation is logged, along with the number that subsequently go on to complete the experiment by visiting a designated goal page.\n\n\nInstallation\n------------\n\nwagtail-experiments is compatible with Wagtail 4.1 to 5.2, and Django 3.2 to 4.2. It depends on the Wagtail ModelAdmin module, which is available as an external package as of Wagtail 5.0; we recommend using this rather than the bundled `wagtail.contrib.modeladmin` module to avoid deprecation warnings. The external package will be required as of Wagtail 6.0.\n\n### On Wagtail 5.0 and above\n\nTo install::\n\n    pip install wagtail-experiments wagtail-modeladmin\n\nand ensure that the apps ``wagtail_modeladmin`` and ``experiments`` are included in your project's ``INSTALLED_APPS``:\n\n.. code-block:: python\n\n    INSTALLED_APPS = [\n        # ...\n        'wagtail_modeladmin',\n        'experiments',\n        # ...\n    ]\n\nThen migrate::\n\n    ./manage.py migrate\n\n### On Wagtail 4.x\n\nTo install::\n\n    pip install wagtail-experiments\n\nand ensure that the apps ``wagtail.contrib.modeladmin`` and ``experiments`` are included in your project's ``INSTALLED_APPS``:\n\n.. code-block:: python\n\n    INSTALLED_APPS = [\n        # ...\n        'wagtail.contrib.modeladmin',\n        'experiments',\n        # ...\n    ]\n\nThen migrate::\n\n    ./manage.py migrate\n\nUsage\n-----\n\nAfter installation, a new 'Experiments' item is added to the Wagtail admin menu under Settings. This is available to superusers and any other users with add/edit permissions on experiments. An experiment is created by specifying a control page and any number of alternative versions of that page, along with an optional goal page. Initially the experiment is in the 'draft' status and does not take effect on the site front-end; to begin the experiment, change the status to 'live'.\n\nWhen the experiment is live, a user visiting the URL of the control page will be randomly assigned to a test group, to be served either the control page or one of the alternative variations. This assignment persists for the user's session (according to `Django's session configuration <https://docs.djangoproject.com/en/1.10/topics/http/sessions/#browser-length-sessions-vs-persistent-sessions>`_) so that each user receives the same variation each time. When a user subsequently visits the goal page, they are considered to have completed the experiment and a completion is logged against that user's test group. The completion rate over time for each test group can then be viewed through the admin interface, under 'View report'.\n\n.. image:: https://i.imgur.com/tG7JH13.png\n   :width: 728 px\n\nFrom the report page, an administrator can select a winning variation; the experiment status is then changed to 'completed', and all visitors to the control page are served the chosen variation.\n\nTypically, the alternative versions of the page will be left unpublished, as this prevents them from appearing as duplicate copies of the control page in the site navigation. If an unpublished page is selected as an alternative, the page revision shown to users on the front-end will be the draft revision that existed at the moment the experiment status was set to 'live'. When displaying an alternative variation, the title and tree location are overridden to appear as the control page's title and location; this means that the title of the alternative page can be set to something descriptive, such as \"Signup page (blue text)\", without this text 'leaking' to site visitors.\n\n\nDirect URLs for goal completion\n-------------------------------\n\nIf you want goal completion to be linked to some action other than visiting a designated Wagtail page - for example, clicking a 'follow us on Twitter' link - you can set up a Javascript action that sends a request to a URL such as ``/experiments/complete/twitter-follow/`` , where ``twitter-follow`` is the experiment slug. To set this URL route up, add the following to your URLconf:\n\n.. code-block:: python\n\n    from experiments import views as experiment_views\n\n    urlpatterns = [\n        # ...\n\n        url(r'^experiments/complete/([^\\/]+)/$', experiment_views.record_completion),\n\n        # ...\n    ]\n\n\nAlternative backends\n--------------------\n\nwagtail-experiments supports pluggable backends for tracking participants and completions. The default backend, ``experiments.backends.db``, records these in a database table, aggregated by day. Alternative backends can be specified through the ``WAGTAIL_EXPERIMENTS_BACKEND`` setting:\n\n.. code-block:: python\n\n    WAGTAIL_EXPERIMENTS_BACKEND = 'mypackage.backends.thecloud'\n\nA backend is a Python module that provides the following functions:\n\n**record_participant(experiment, user_id, variation, request):**\n\nCalled when a user visits the control page for ``experiment``. ``user_id`` is the persistent user ID assigned to that visitor; ``variation`` is the Page object for the variation to be served; and ``request`` is the user's current request.\n\n**record_completion(experiment, user_id, variation, request):**\n\nCalled when a visitor completes the ``experiment``, either by visiting the goal page or triggering the ``record_completion``. ``user_id`` is the persistent user ID assigned to that visitor; ``variation`` is the Page object for the variation that was originally served to that user; and ``request`` is the user's current request.\n\n**get_report(experiment):**\n\nReturns report data for ``experiment``, consisting of a dict containing:\n\n``variations``\n  A list of records, one for each variation (including the control page). Each record is a dict containing:\n\n  ``variation_pk``\n    The primary key of the Page object\n\n  ``is_control``\n    A boolean indicating whether this is the control page\n\n  ``is_winner``\n    A boolean indicating whether this variation has been chosen as the winner\n\n  ``total_participant_count``\n    The number of visitors who have been assigned this variation\n\n  ``total_completion_count``\n    The number of visitors assigned this variation who have gone on to complete the experiment\n\n  ``history``\n    A list of dicts showing the breakdown of participants and completions over time; each dict contains ``date``, ``participant_count`` and ``completion_count``.\n\n\nTest data\n---------\n\nwagtail-experiments provides a management command ``experiment-data``, to allow populating an experiment with dummy data for testing or demonstration purposes, and purging existing data. This command is called with the experiment's slug::\n\n    # Populate the experiment 'homepage-banner' with 5 days of test data,\n    # with 100-200 views per variation. All parameters other than experiment slug\n    # are optional\n    ./manage.py experiment-data homepage-banner --days 5 --min=100 --max=200\n\n    # Purge data for the experiment 'homepage-banner'\n    ./manage.py experiment-data homepage-banner --purge\n",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "A/B testing for Wagtail",
    "version": "0.3.1",
    "project_urls": {
        "Homepage": "https://github.com/torchbox/wagtail-experiments"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "760823179468399e757450a880881441ea1d511355eba1d8078f14b49003be58",
                "md5": "3408c6e89d860f2af56b172d7a1e12b2",
                "sha256": "9c6debd9709e51288bf3efe62bfa9de8dc23b73c66d975cb9bb78b5101d092a9"
            },
            "downloads": -1,
            "filename": "wagtail_experiments-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3408c6e89d860f2af56b172d7a1e12b2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 122404,
            "upload_time": "2023-11-06T20:37:49",
            "upload_time_iso_8601": "2023-11-06T20:37:49.303295Z",
            "url": "https://files.pythonhosted.org/packages/76/08/23179468399e757450a880881441ea1d511355eba1d8078f14b49003be58/wagtail_experiments-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c4ac97ab54c756a3222a7918b358b583d2a1756bdd5e17b9ecf003c0579fdf88",
                "md5": "e9fda9cbab3cf659974e078e1d868ea3",
                "sha256": "bb8e6f3ed7919e5662c97cbbe3154e0269774a6c65b38087eb4d53069b45f1f7"
            },
            "downloads": -1,
            "filename": "wagtail-experiments-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "e9fda9cbab3cf659974e078e1d868ea3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 119560,
            "upload_time": "2023-11-06T20:37:51",
            "upload_time_iso_8601": "2023-11-06T20:37:51.353196Z",
            "url": "https://files.pythonhosted.org/packages/c4/ac/97ab54c756a3222a7918b358b583d2a1756bdd5e17b9ecf003c0579fdf88/wagtail-experiments-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-06 20:37:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "torchbox",
    "github_project": "wagtail-experiments",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "wagtail-experiments"
}
        
Elapsed time: 0.14642s