Experiments in code
In a request-response context
Using experiments in an environment where a request is available is the default assumed mode. Little is required to use experiments in your Django code.
Anywhere you have access to a HttpRequest object, you can call is_variant(),
is_on(), or is_off.
from django.shortcuts import render
from cravensworth.core import experiment
def my_experimental_view(request):
is_active = experiment.is_variant(request, 'my_experiment', 'active')
feature_on = experiment.is_on(request, 'my_feature')
context = {
'experiment_is_active': is_active,
'feature_is_on: feature_on,
}
return render(request, 'some_template.html', context)
The decorators package also provides some convenient decorators that you can
use to control access to views based on experiments or switches.
from cravensworth.core.decorators import variant, switch_on
@variant('my_experiment, 'active', redirect_to='/')
def active_only_view(request):
"""This view can only be accessed if the variant is 'active'. If it is
another variant, the user will be redirected to '/'
"""
return render(request, 'experimental_template.html')
@switch_on('best_new_feature')
def switch_on_view(request):
"""This view can only be accessed if the switch is on. If it is off, the
user will receive a 404 Not Found.
"""
return render(request, 'new_feature_template.html')
In a non-request context
If you don't have a request available, you can still use Cravensworth, but you will have to do more of the setup work. Not having a request is common if you are building command or a background job.
Setting up the context
You can use the context provider, configured in settings.py, by calling
get_context_provider(), which returns an instance of a context provider.
from cravensworth.core.experiment import get_context_provider
context_provider = get_context_provider()
context = context_provider.context(
# Params as required by provider...
)
Note
The default context provider is DjangoRequestContextProvider, which
requires a request. To use context providers in a non-request context, you
must configure a provider that doesn't require a request by setting the
CONTEXT_PROVIDER setting in settings.py.
Or you can create a context directly by passing a dictionary to Context()
populated with data required for your experiments.
from cravensworth.core.experiment import Context
context = Context({
# Data required by your experiments...
})
Overrides
If you want to use overrides variant in a non-request environment, you will need to source them yourself. Overrides are provided to the state as a dictionary mapping experiment name to the override variant.
Loading experiments
To load experiments, you can call get_source() to get an instance of the
configured experiment source, then call load() to get the list of experiments.
Depending on your needs, you may only have to do this once. If you are using
experiments in a long-running process, where experiment updates need to go into
effect quickly, then you may have to call load() more often.
Checking variants
Finally, we can put it all together to populate a state object and check variants.
from cravensworth.core.experiment import Context, CravensworthState
from cravensworth.core.source import get_source
import User from .models
def some_batch_job_or_whatever():
experiments = get_source().load()
overrides = { 'my_super_experiment': 'active' }
for user in User.objects.all():
context = Context({'user': user})
state = CravensworthState(experiments, overrides, context)
if state.is_variant('my_super_experiment', 'active'):
... # Do something when variant is "active"...
else:
... # Do something else...