Packages! Packages! Packages!
Published July 19, 2024
This video features Will Barton at Wagtail Space US 2019 in Philadelphia, Pennsylvania, USA.
Feature flags let teams turn code on or off without a deployment. The speaker explains how Django Flags replaces scattered settings and custom database models with flags defined by conditions—such as environment, date, user, or URL parameter—and how Wagtail Flags gives non-developers an admin interface to manage them. Used throughout a feature’s lifecycle, flags let developers, designers, researchers, stakeholders, and content editors review, test, and launch work independently; old code still needs cleanup after launch, and teams should avoid unnecessary dependencies between flags.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: So I'm Lil. I am a developer at the Consumer Financial Protection Bureau. I'm also a Wagtail core team member, and I am going to talk about feature flags. So starting off with like what are feature flags? Folks are probably somewhat familiar. It comes up a lot if you're talking, you know. DevOps, um it's feature flags, feature toggles. More or less ways that you can switch a feature on or off without necessarily having to deploy code and have like this massive process in order to launch a thing. I for the purposes of this talk, I'm just gonna treat flags.
Speaker 1: We don't need to know anything about deployments, DevOps, anything. Feature flags are simply a way to turn code off or on, depending on Conditions that we'll talk about. So I'm going to start with some in-code examples because what I want to do is I want to contrast managing feature flags in code and what that looks like versus B enabling non-developers to manage them. So when you decide to, you know, you have code that you want to turn off or on depending on a thing in Django. First thing you're probably going to try to do is just add a variable that's either true or false in the settings files.
Speaker 1: Imagine a lot of us have probably done this. And that works. You know, you can turn it on locally. merge your code, it's off, wherever. And then you can use it. So in your view you can check settings. my flag and render a different template based on whether it's on or off And then say you want to in on your testing server, you want to enable it, but in production, no, not yet. So then you have your testing settings and your production settings. And you it's true in one and false in the next. And that's all fine and good. But maybe you have an environment variable that you can check to see if
Speaker 1: see what environment. it's the code is deployed in so you add a check of the environment to see what it is and that becomes whether or not your flag is on or off And that's good. So what if you want to turn it on on a particular day? You know when launch is going to be. And you know that at that point it's going to be on and you don't want to have to change the configuration and redeploy. So check today's date against that expected date. And that works. But that's starting to get a bit complicated, especially if you have
Speaker 1: more than like a single feature that someone's working on you end up with a lot of these very bespoke sort of blocks of settings. And the other thing is, what if you want to? So all of these examples and settings require you to redeploy your configuration at least. Depending on how it's managed, it might live with the code base view. And that's still that extra deploy that has to happen in order to turn things off or on. That still requires whoever has the keys to the deployment process to do. So what If you don't want to do it that way. So we're talking about Django. So you create a database model. Alright, it's your feature flag, you've got your name, and you've got whether it's on or off.
Speaker 1: And then you can Turn it off or on in the Django admin, right? But in the example that I was giving earlier, we also had a date, right? So we want to turn it off or on on a particular day, so we Could use a field for that. We had environment specific, an environment specific sort of test. So we could add a field for that and then start doing some stuff to figure out what environment it is in code that depends on the model, which is maybe not ideal And you could envision possible other things you would end up adding to that increasingly Frankenstein model. And this is about the point in time where you'd kind of put all that down and go and look for a library where someone has already done all of this work
Speaker 1: so that you don't end up with your Frankenstein model. Because presumably someone's already done it differently and run into problems that you will run into and has hopefully solved them. This is more or less how feature flags evolved at CFPB. We had settings, we moved them into the database, and then we broke that off into to a library that we have made available. We couldn't find anything that really fit the way we were already using them, which is another reason to look for a library ahead of time and to understand that what you're creating is a feature flag to begin with. So we created Django flags. It supports
Speaker 1: defining features, feature flags in settings as well as in the database. It has all the utility functions, view decorators, whatever you need in templates in Python to check the state of a flag for a particular request. So all of that's already done. It also has, so instead of, you know, we can have dates, environments, so instead of lots of different possible fields, it has a concept of conditions. And these are all the different ways that a flag uh you know uh a feature could be turned off or on. In our previous examples, it was Turned off or on, either Boolean true or false.
Speaker 1: We had when the date is a particular day and when the environment was fast. So that's more or less how Django Flags conceptualizes feature flags. It is They said a name and then a set of conditions that could be met. And each of those conditions has an expected value. So you have your flag. Okay. So the Boolean condition is either true or false. Like that is something that you tell it. It's either off or on. You can tell it the date is after particular value and that the environment is test environment. And
Speaker 1: So we can replicate the complex series of settings that we had earlier. In Django flags in settings like this, which is fine, that puts it in the settings file where it already already was. It's basically just giving it conditions and values. And so we can also do it in the admin. Which is nice because that way it doesn't require you to edit the settings file necessarily And so because conditions are extensible, so you can register a function that checks something about a request or about
Speaker 1: the running state of the application and then returns whether the flag is off-run. So that's we can define those and make them available to anyone who's has access to the Django admin and can edit or it can add or edit any of these conditions. The other thing that we can do is Looking at these, you can see that my flag is enabled when the Boolean is true, so it's more or less always enabled. Or it's enabled after that date or when the environment is tested. So all of these, any one of those could be true, and the flag would be enabled
Speaker 1: for that particular check. So that's the other thing that it lets us do is define A possibly complex series of things that tell it that can enable the flag under any number of circumstances. Which is not something that happens very often. Usually you either want it on or off for a specific reason. Anyway, so what are five good for? I mean that's getting into how you create them and manage them. So I can tell you they're turning off or on code and whatnot, but stepping back from that, they're good
Speaker 1: for enabling collaboration between developers and designers and stakeholders. over the full life of a feature or a project or whatever whatever thing is being built. or whatever structure that has, like team structure that has. So what we will do is like at the start of a project, just introduce a feature flag for it. And that way everything we do is contained within that feature flag. We have a way to turn it off or on. And then we can use it in code. So we can flag a URL for that feature if it's introducing a new URL. We're serving the feature if the flag is turned on.
Speaker 1: And then we could enable that flag on the development server. So it's not on in production, the code is barely working, but we have we can Turn it on on a development server and our design team members can look and provide feedback. Stakeholders can look and provide feedback. And so that lets us close that feedback loop a little bit so that like developers are working on the code, designers are working on the design, and it lets everybody who needs to see the thing working, see it working the same way in the same place without having too much of uh wait for
Speaker 1: okay we're finishing this thing and then it gets deployed to the other place. So let's just turn things off or on. in places. The other thing about this is that creating a Boolean condition with a true value in the Django admin does not require a developer. So anyone who has access to the Django admin could do this. But the Django admin, I don't know if how many people have tried to customize a Django, Django model admin or even or add a custom view to the Django admin. It's not fun. The Django admin is very model centric. And it suits it very well.
Speaker 1: But we use Wagtail and the Wagtail admin is a lot more customizable and extensible. So We created a front end for Django flags called Wagtail flags, which adds a friendly Wagtail admin in front of all of this functionality So that again using the the example conditions earlier any of our content editors who have or anyone we provide permission to access the flags part of the admin Has access to this. We have a human readable string there at the top that tries to give an idea of what
Speaker 1: the expected kind of state of the flag is. So when any of these conditions are met, the flag is on. So we have the date condition we had before. We have the test environment condition. We also have this file. That button is what creates the Boolean true condition. So it is an on-off button to always turn on the flag or once you've turned it on, turn it off. And you can add conditions, you can edit them. It's all the functionality is there. So getting back to what flags are actually good for and kind of that life cycle of a feature thing.
Speaker 1: So once Once we've created our flag, we have our code. Whoever needs to turn it off or on or see it or do whatever with it can We can we can work on the feature. It's right now disabled for all requests. So, you know We can turn it on, but it's just pushing that button. And now it's enabled on the dev server or wherever it happens to be We can specifically add a condition that if we're in the dev environment, it's always on. And once we're done with kind of that initial sort of iterating and within the teamwork, we have something that we're ready to, you know.
Speaker 1: do some user research on. User researchers. UX researchers can use that flag and See, I think I've got my slides slightly out of order. They can add whatever conditions might suit where they're doing the testing. We can add a parameter which basically just checks if a certain git parameter has been provided to the URL. So if you go to a URL with that parameter on the end, the flag's state. is true, so you get the new code. Um if there's a particular user that we're using to test, if it's
Speaker 1: you know A feature that requires logging in somehow, somewhere, we could create a user condition. The other thing is as we're starting to get to the point of Sorry, backing up. If the new feature is not a new feature, but it's actually replacing some other other thing. We can sunset that old thing at the same time we launch the new thing. So that in our URLs we have the new feature and it's gonna serve the new feature. That slide is true, otherwise it's going to fall back to serving little feature at that URL. So
Speaker 1: not only do we not have to do a deployment to launch our new thing. We don't necessarily have to do anything to remove the old thing. That code sits there and just stops being used when it's time to launch. So when it is time to launch, you know it might be part of a larger initiative. There might be Events, there might be blog posts or something else, and you know blog posts have scheduled publishing dates, that sort of thing. So we can add a date That corresponds to you know the the same date that the events, that the blog posts, whatever are going up. And it will just turn on at that time.
Speaker 1: This could actually be a date date or it could be a date time, but for simplicity If it's delayed, if for whatever reason, well outside of like the development team responsible for the for the code. A decision's made, it doesn't have to go back to the developers to change, okay, so we you know the dates changed when a content editor is going in, and changing the published date on the blog posts, they could also change the date the state. So again, it enables them to do all of that without having to come back to the development team.
Speaker 1: So this is just a really quick kind of overview of how we're doing feature flags. It gets us to a place where we've got developers, designers, and stakeholders, UX researchers, content editors involved and empowered through the whole life cycle of a feature. You know, no one's waiting for anyone else in order for them to do their job. Everyone who needs to, like content editors, can do what they need to do with what goes on with the content of the website. And everyone's trusted to do the things that they are good at doing. You know, their domain of expertise doesn't require someone else to
Speaker 1: Do something so that they can do what they need to do. And that's I think how it should be So yeah, got developers, designers, stakeholders, UXers, and content editors. And I think that is the power of feature flags, is that You get that level of collaboration without the overhead of deployments code changes, you know, not everyone can run the can run a Wagtail site on their laptops, nor do they need to. So it enables collaboration and for us developers it lets us
Speaker 1: let all of our non-developer colleagues it gets us out of their way, you know So everyone, nope, yep, points for that too. Everyone can fly a flag. Thank you very much. Anyone have questions or anything? Yes.
Speaker 2: So if you're using this for launching a feature, and that means you have to decode the old feature and the new feature simultaneously. Do you then later go and clear out the old feature, hopefully?
Speaker 1: Yeah, basically. Yeah. There's hygiene involved. But yeah, it it basically makes that asynchronous to the like launch of a thing. Yeah And makes it not oh my god, I forgot to remove this one thing at this URL. So Yes.
Speaker 3: I thought about doing this with our work now and I really hit. environments, uh or we should say that it's it's really more useful for collaboration. Like uh one or two environments where you can
Speaker 1: That's certainly possible. We so what we have some kind of a combination of that goes on. We have separate servers with separate databases for like development work if we want to like deploy a branch or something like that. And then we do have environments that share the same database where we enable it for a particular like domain but not the production domain or something like that. So there's there's a mix of the two.
Speaker 3: And do you find that like your programmers and colleagues like did they adopt the flag system ultimately easily or did it was it still like yeah you can ask them weren't they weren't still coming to you and asking you to turn the flags on Oh
Speaker 1: well it's it's not just me, but uh we we yes. Well um I think As developers, making sure that, you know, our UX colleagues, for example, are aware of how to do it. is something that that there's that little reminder and I I am somewhat of an evangelist amongst us so in our work chat I have the word flag It notifies me if someone's thinking about it. But yeah, it's making sure folks are aware that this is something you can do. Um is an ongoing thing. Yes.
Speaker 4: foresee any coordination issues with everyone having access to just kind of put flags and then you turn off features.
Speaker 1: There have been times where we've had some odd interactions between flags But not not so much, I don't think. I can't think of a good example. Most of the time we do So I I showed how you can still define a flag in settings and that's what we try to do anyway is in the the settings file we have our list of flags and then we have comments describing what they do so that it's a little bit hopefully self-documented.
Speaker 4: Do you have any word dependencies between some flags?
Speaker 1: I think we've avoided that. But that that takes intentionality to not have one flag need another. Code that's behind one flag need code that's behind another flag to work. So I think that's just keeping things clean on the on the back, like when we're writing the code
Speaker 5: Um, do you have any tooling around using these for like AP testing stuff?
Speaker 1: Yes, we do. Um and we could so I'll let Scott.
Speaker 6: So as far as an X Raging testing goes. The basic thing we do is we have a flag and I think it's just called AB testing and it's got path conditions. So we say on this path enable the flag and then within that um most of the AB testing we do is see Google optimize so if it is on the path and the flag is evaluated to true, the template will include the Google optimized. So yeah, we do a lot of switching things on and off in templates with flag condition
Speaker 1: Anyone else?
Speaker 7: Yes. Maybe this is built in already, but possible to chain date. If it ends in a flag, so if I want something on by this date and off by this date, and then another thing on by this date, depending on the first flag.
Speaker 1: Yes. Um that is built in. Let's see. So there 's a column that's not named there for a required flag. So you can have required flags that basically and the conditions together instead of ordering them. Yes.
Speaker 4: Okay, I have uh two questions. One is you might say the sorry I missed it. Is there a limited interject like dynamic conditions uh would apply like say 50% of users see this and it's like a random dice role or a user is a number of these
Speaker 1: Yes, so conditions are more or less just functions that get the request and And whatever arguments they might need. So so yeah, you can create an a new condition that does that that just flip a coin. around uh caching. Like is there a way for it to have to cache? No, not yet. And that is That is a problem with the the date condition that I glossed over that we have right now. All right. Thank you very much.
Feature flags let you turn code on or off without deploying. They can also let developers, designers, researchers, stakeholders, and content editors collaborate on a feature without waiting on one another or relying on developers to change deployment settings.
Discussed at 0:46Django Flags represents a flag as a name plus conditions, such as a Boolean value, date, or environment. Flags can be defined in settings or the database, and the library provides utilities for checking them in Python, views, and templates.
Discussed at 5:32A team can put a feature behind a flag and enable it on a development server so designers and stakeholders can review it and give feedback while it is still being built. Researchers can also use conditions such as a URL parameter or a specific user to access a feature for testing.
Discussed at 9:25Wagtail Flags provides a Wagtail admin interface for Django Flags, where permitted users can switch a flag on or off and add or edit conditions. That means content editors and other colleagues can manage flags without changing code or settings.
Discussed at 11:45Yes. A date condition can activate a flag at the same time as scheduled content or other launch activities, and an authorized content editor can change that date if plans shift, without involving developers.
Discussed at 15:43Yes. The old code should eventually be cleaned up, but flags let that cleanup happen separately from the launch, so removing the old feature does not have to block the release.
Discussed at 19:31Yes. The speaker describes enabling a flag on a particular path and using it in a template to include Google Optimize, which they use for much of their A/B testing.
Discussed at 23:15Yes. Conditions can be combined with a required flag, so the required flag and the conditions must be satisfied together. The team tries to avoid making code behind one flag depend on code behind another, since that requires deliberate coordination.
Discussed at 24:12Yes. Since conditions are functions that receive the request, you can create a custom condition that effectively flips a coin to decide whether the flag is enabled.
Discussed at 24:50The speaker says caching was not supported at the time of the talk, and notes that this was a problem for the date condition.
Discussed at 24:50Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published July 19, 2024
Published July 19, 2024
Published July 19, 2024
Published July 19, 2024
Published July 19, 2024
Published July 19, 2024