Writing Features¶
Features are very small and easy to write. They’re subclasses of
Feature
, which are typically placed in a features.py
file
in the app defining the feature.
Let’s start with a basic example:
# myapp/features.py
from djblets.features import Feature, FeatureLevel
class MyFeature(Feature):
feature_id = 'myproject.myfeature'
name = 'My Feature'
summary = 'This feature does some neat things.'
level = FeatureLevel.EXPERIMENTAL
my_feature = MyFeature()
Each feature must have a unique ID. This ID is how you look up a feature dynamically and is used when specifying which features are enabled (through a feature checker).
Features should also have a name and a summary. These aren’t used directly by the Djblets Features code, but applications may want to use these to show a human-readable list of possible features.
You’ll also want to instantiate your feature subclass, but just once. We recommend instantiating it in the same file in which it’s defined, as a top-level variable. At this point, the feature will be registered with the feature registry, allowing the feature to be used and its enable state computed.
Stability Levels¶
A feature has a stability level, which indicates whether it’s enabled by default, or even whether it can be enabled at all.
The built-in stability levels are defined in FeatureLevel
, and
include:
UNAVAILABLE
:- The feature is unavailable for use, and can’t be enabled through a feature checker. Useful when shipping code that you don’t want used at all yet by anybody else, and you just want to selectively enable in your own tree or in a development branch.
EXPERIMENTAL
:- The feature is experimental and disabled by default, but can be enabled through the feature checker.
BETA
:- The feature is in beta. It will be disabled by default if
settings.DEBUG
isFalse
, but can be enabled through the feature checker. Ifsettings.DEBUG
isTrue
, it will be enabled. STABLE
:- The feature is always enabled.
The meaning of these levels can be changed in the feature checker by
overriding
min_enabled_level()
.
You can set the stability level of your feature through the
Feature.level
attribute:
from djblets.features import FeatureLevel
class MyFeature(Feature):
level = FeatureLevel.BETA
Feature Initialization/Shutdown¶
If you need to perform some logic surrounding the initialization of a feature,
such as registering signal handlers, then you can do so by defining a
initialize()
method:
class MyFeature(Feature):
...
def initialize(self):
# Your code goes here.
Similarly, you can handle feature shutdown through a
shutdown()
method. This is only ever called if the
application unregisters the feature, which not all applications will do, but
if yours does, this would be a good place to put shutdown logic.
class MyFeature(Feature):
...
def shutdown(self):
# Your code goes here.
Not all features are going to need these capabilities, but they’re there if you do need them.