Favorite 3rd Party Environment Variables Package?

I’m curious what 3rd party packages folks like for managing environment variables. And please justify why? The popular packages I’m aware of are:

Personally I’m partial to environs because you can install it with additional Django support to also use dj-database-url, django-cache-url, and dj-email-url. But all of the popular packages listed above do more of less the same thing.

Does anyone feel very strongly about one package over another? Or is there an obvious additional package I’m missing from this list?

1 Like

environs, specifically environs[django] is my env library of choice. Not only does it bundle the libraries you mentioned, but it also has a few Django-specific parsing features, which are nice. I use environs for non-Django projects, too, so having a library that works with both is nice.

One tip that I think is worth passing along is to avoid using the read_env() method even though all of these libraries recommend it. read_env() will look for a .env file which sounds good in theory, but use a library like direnv to load your ENV variables into memory or let your container load ENV variables from either a .env file or from secrets. This will save you grief/bad production practices later.

3 Likes

Yes! What @jeff said around read_env() and not relying on a .env file if you can since it is easy to have that loaded into Git or production by mistake.

I’m using environs. It’s worked well and I like that it’s a minimal package relying marshmallow to do the heavy lifting.

1 Like

I’m a big fan of python-dotenv for local development. Hooking it into manage.py and using a filename which docker won’t try to read for its own variables. (I think it uses .env if that exists…)

I tried swapping to environs but I didn’t get on with it. I recall it throwing errors if things weren’t defined.

1 Like

Historically, I used django-environ for my Django projects, so I use it everywhere now on all projects.

I’m working with django-environ , But I like to know more about the other packages like
python-dotenv that @markwalker talked about and environs that @jeff, @satya and @wsvincent talked about,

nice post and discussion @wsvincent

I’m partial to my own speckenv library but I’m always looking around to find other solutions.

What I like most about it is the simple and short implementation speckenv/speckenv.py at main · matthiask/speckenv · GitHub and maybe the fact that it contains opinionated replacements for other 12 factor libraries which 1. only support what I want them to and 2. do not add schemes to urllib without any need. Maybe it was necessary to register custom schemes in the past. Everything works fine these days without adding schemes to a list which isn’t owned by the 12 factor library.

2 Likes

I’m using os.getenv("KEY", 'default_value'), and I must admit that I don’t really know why there is so much environment-variables-managing-packages laying around, what are their advantages over this function?

@Corentin If you’re doing it like that then you need to make sure the environment variables are set.

With these packages you can define key/value pairs in a file which are automatically loaded into the environment.

This might not sound that useful, but consider a local file, ignored by git. A developer can define everything they need for running a project such as their local database server details. The projects manage.py is updated to use the chosen env var package and when the file is used, it loads the variables from the file into the environment.

At least this is my workflow with python-dotenv.

I’m using a .env file in my project folder, and I source it after activating the venv, it works really well and I don’t have ton install another dependency.
My personal django projects are started by services (launching scripts containing the source venv/.env) so it’s fully automated :slight_smile:

One feature of these packages is that they tend to provide for “type awareness”. For example, your DEBUG setting should be True or False (boolean value). However, os.getenv is going to return a string, regardless of the desired type. It would then be up to you to add the code to your settings file to verify or convert values.

This becomes extremely valuable when you’re working in an environment where developers don’t have control over that environment settings file.

1 Like

Thanks for the explanation :slight_smile:

I’m using two settings files, settings/dev.py & settings/base.py, and I just set the DJANGO_SETTINGS_MODULE to either website.settings.dev or website.settings.base. But I see the good points of type awareness. It’s just I didn’t need them for my small projects (for now).

I have only ever used python-decouple after it was suggested to me in a tutorial. I haven’t found it lacking, so haven’t had reason to look elsewhere. One feature I do like is specifying an env file, so that I can use a docker secret to store my environment variable files.

@sdolemelipone
Python-decouple makes conflicts with deployment so I’m using django-environs . But If it’s OK with you that’s nice.
The bad behavior of it come when I tried to deploy my project on Heroku (also I do’t like it) but I have to deploy the project on Heroku because my manager ask me to do so.
I like deployment on pythonanywhere or digital ocean (both sites are good and meet the developer brain schema)