Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
master_doc = "index"

# General information about the project.
project = "Experiments"
project = "Experiments.py"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand All @@ -54,7 +54,7 @@
# -- Options for HTML output ----------------------------------------------

html_theme_path = [alabaster.get_path()]
html_static_path = []
html_static_path = ["images"]

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
Expand All @@ -67,7 +67,7 @@
# which templates to put in the sidebar. we're just removing the relations
# section from the defaults here, that's "next article" and "previous article"
html_sidebars = {
"**": []
"**": ["about.html", "searchbox.html", "navigation.html"]
}

html_theme_options = {
Expand All @@ -76,6 +76,7 @@
"github_repo": "experiments.py",
"github_user": "reddit",
"github_banner": True,
"logo": "ddg-logo.png",
"logo_name": True,
"show_powered_by": False,
"show_related": False,
Expand Down
Binary file added docs/images/ddg-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 46 additions & 20 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
``reddit_experiments``
.. _reddit_decider:

``reddit_decider``
===============================

.. automodule:: reddit_decider


Prerequisite packages
-------
---------------------
.. code-block:: python

baseplate>=2.0.0
Expand All @@ -18,13 +20,13 @@ Prerequisite packages
reddit-v2-events

Prerequisite infrastructure
-------
---------------------------
Set up your service to pull down & synchronize experiment configurations from Zookeeper via the Baseplate `live-data watcher sidecar
<https://baseplate.readthedocs.io/en/stable/api/baseplate/lib/live_data.html?highlight=sidecar#watcher-daemon>`_ (minimum v2.4.13).
You'll have to make sure that your service is authorized to fetch the appropriate secret from Vault.

Prerequisite configuration:
-------
Prerequisite configuration
---------------------------
Setup :code:`reddit-experiments` in your application's configuration file:

.. code-block:: ini
Expand All @@ -50,7 +52,18 @@ Setup :code:`reddit-experiments` in your application's configuration file:


Integrate :code:`reddit-experiments` into Baseplate service
-------
-----------------------------------------------------------

Upgrade or integrate reddit-experiments package:

.. code-block:: python

# import latest reddit-experiments package in service requirements.txt
reddit-experiments>=1.3.7

Initialize :code:`decider` instance on Baseplate context
--------------------------------------------------------

In your service's initialization process, add a :code:`decider` instance to baseplate's context:
(Note the use of the :code:`ExperimentLogger`, which is used to publish exposure V2 events,
an example can be seen `here <https://github.snooguts.net/reddit/reddit-service-graphql/blob/3734b51732c29d07eef32aced86677cce5064dbb/graphql-py/graphql_api/events/utils.py#L205>`_)
Expand All @@ -68,7 +81,7 @@ an example can be seen `here <https://github.snooguts.net/reddit/reddit-service-
def make_wsgi_app(app_config):
baseplate = Baseplate(app_config)
decider_factory = decider_client_from_config(app_config=app_config,
event_logger=ExperimentLogger,
event_logger=ExperimentLogger(),
prefix="experiments.",
request_field_extractor=my_field_extractor) # this is optional, can be `None` if edge_context contains all the fields you need
baseplate.add_to_context("decider", decider_factory)
Expand All @@ -78,11 +91,11 @@ an example can be seen `here <https://github.snooguts.net/reddit/reddit-service-
baseplate.configure_context({
"decider": DeciderClient(
prefix="experiments.",
event_logger=EventLogger,
event_logger=ExperimentLogger,
request_field_extractor=my_field_extractor # optional
})

Make sure :code:`edge_context` is accessible on :code:`request` object like so:
Make sure :code:`EdgeContext` is accessible on :code:`request` object like so:

.. code-block:: python

Expand All @@ -108,16 +121,17 @@ Make sure :code:`edge_context` is accessible on :code:`request` object like so:

# Customized fields can be defined below to be extracted from a baseplate request
# and will override above edge_context fields.
# These fields may be used for targeting.

def my_field_extractor(request):
# an example of customized baseplate request field extractor:
return {"foo": request.headers.get("Foo"), "bar": "something"}


Usage
-------
Use the attached :py:class:`~reddit_decider.Decider` object in request and
:code:`decider.get_variant()` (which will automatically send an expose event)::
Basic Usage
-----------
Use the attached :py:class:`~reddit_decider.Decider` object in request to call
:code:`decider.get_variant()` (automatically sends an expose event)::

def my_method(request):
if request.decider.get_variant("foo") == "bar":
Expand All @@ -130,20 +144,32 @@ or optionally, if manual exposure is necessary, use::
...
request.decider.expose(experiment_name='experiment_name', variant_name=variant)

Configuration Classes
-------------

.. autofunction:: decider_client_from_config
Decider API
-----------

.. autoclass:: Decider
:members:

Configuration Class
-------------------

.. autoclass:: DeciderClient

Configuration Function
----------------------

.. autofunction:: decider_client_from_config


Configuration Context Factory
-----------------------------

.. autoclass:: DeciderContextFactory

Legacy API docs:
----------------

Decider API
-------
.. toctree::

.. autoclass:: Decider
:members:
legacy/index
91 changes: 91 additions & 0 deletions docs/legacy/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
``reddit_experiments (legacy)``
===============================

.. automodule:: reddit_experiments

Please consider upgrading your service to use the latest :ref:`reddit_decider` SDK
to gain access to new features, such as **Mutually Exclusive Groups**, **Holdout Groups**, and **Dynamic Configurations**.


Initialize :py:class:`~reddit_experiments.Experiments` instance on Baseplate context
------------------------------------------------------------------------------------

Add the :code:`Experiments` client to your application via::

baseplate.configure_context(
{
...
"experiments": ExperimentsClient(event_logger),
...
}
)

or alternatively using::

experiments_factory = experiments_client_from_config(
app_config=app_config,
event_logger=ExperimentLogger
)
baseplate.add_to_context("experiments", experiments_factory)


Configure :py:class:`~reddit_experiments.Experiments` client
------------------------------------------------------------

Configure the client in your application's configuration file:

.. code-block:: ini

[app:main]

...

# optional: a path to the file where experiment configuration is written
# (default: /var/local/experiments.json)
experiments.path = /var/local/foo.json

# optional: how long to wait for the experiments file to exist before failing
# (default: do not wait. fail immediately if not available)
experiments.timeout = 60 seconds

# optional: the base amount of time for exponential backoff while waiting
# for the file to be available.
# (default: no backoff time between tries)
experiments.backoff = 1 second

...


Usage
-----
Use the attached :py:class:`~reddit_experiments.Experiments` object in
request to get a variant::

def my_method(request):
if request.experiments.variant("foo") == "bar":
pass

Experiments API
---------------

.. autoclass:: Experiments
:members:

Configuration Class
-------------------

.. autoclass:: ExperimentsClient

Configuration Function
----------------------

.. autofunction:: experiments_client_from_config

Configuration Context Factory
-----------------------------

.. autoclass:: ExperimentsContextFactory

Link to Latest SDK
------------------
See :ref:`reddit_decider`
Loading