- Python – Exporting environment variables for Flask Application in Windows
- Best Solution
- 1. Setting environment variables from commandline:
- Using a .env file
- Related Solutions
- Interacting With Environment Variables in Python
- Accessing, exporting and unsetting environment variables with Python
- Introduction
- Accessing environment variable
Python – Exporting environment variables for Flask Application in Windows
I am following a Youtube Tutorial Full-featured Web application and I am having issue with application factory. Based on my understanding, I need to put sensitive information such as SECRET_KEY and SQLALCHEMY_DATABASE_URI into environment variables. In the video , the creator was working on a Mac and he opened his .bash_profile file and added these lines (I leave the real values blank):
export SECRET_KEY='. ' export SQLALCHEMY_DATABASE_URI='. '
I am working with Windows and I could not find the .bash_profile file in my computer, so I went to Control Panel and set new environment variables SECRET_KEY and SQLALCHEMY_DATABASE_URI. Then I proceeded as in the video by creating this class Config in config.py
class Config: SECRET_KEY = os.environ.get('SECRET_KEY') SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI') MAIL_SERVER = 'smtp.gmail.com' MAIL_PORT = 587 MAIL_USE_TLS = True MAIL_USERNAME = os.environ.get('EMAIL_USER') MAIL_PASSWORD = os.environ.get('EMAIL_PASSWORD')
Then I ran my application, but an error message appeared «A secret key is required to use CSRF.», so I think my flask application was unable to get the SECRET_KEY or other environment variables I set. Before when I had these configurations in my init.py, the application was working fine, but now when I moved these configurations to inside an object in config.py, it stopped working.
Based on my understanding, export is a command to create environment variables, so I thought exporting those variables in a .bash_profile file is equal to set environment variables.
To fix my problem, I tried following the tutorial (https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xv-a-better-application-structure) by creating .env file. In the command prompt, I ran
from dotenv import load_dotenv basedir = os.path.abspath(os.path.dirname(__file__)) load_dotenv(os.path.join(basedir, '.env'))
I thought this would create a .env file in which I can store my environment variables, but it did nothing and I did not see any .env file in my directory. Can someone please help me ? I have a few questions:
- What do I need to add/fix to make my application work ?
- Is setting environment variables and exporting it the same ? If not, how do I export environment variables after setting environment variables so my application can work ?
- How is storing environment variables in .env file different from setting environment variables in Control Panel? Because when I tried to search «Edit .env file in windows» on google, results such as «adding environment variables» come up.
- What is the difference between .bash_profile and .env file ? I ran man bash and it said .bash_profile is The personal initialization file, executed for login shells , but I do not understand whether this means it is totally different from .env file.
Best Solution
The problem with setting environment variables from Control Panel is that for a program to detect the change in these variables, it needs to be closed and reopened. BUT, when you run a program it inherits environment variables from its parent process. So you need to close that too, and on and on it goes until explorer.exe . So it’s a bit tricky.
So you need to follow a different approach.
1. Setting environment variables from commandline:
You can set an environment variable for a commandline session using set command on cmd (or $env global on PowerShell) ( export doesn’t exist on Windows).
# cmd set "SECRET_KEY=s3cr3t" # powershell $env:SECRET_KEY = 's3cr3t';
Then to check if it’s really set:
# cmd echo %SECRET_KEY% # powershell $env:SECRET_KEY
which should print s3cr3t . Or you can just use set command without any arguments, which will print all environment variables.
After you set all environment variables this way, you run your app:
# app.py from flask import Flask import config app = Flask(__name__) @app.route('/') def home(): return 'secret is ' + config.SECRET_KEY app.run()
# config.py from os import getenv SECRET_KEY = getenv('SECRET_KEY', None) assert SECRET_KEY # make sure app doesn't run without this value # use the key print(SECRET_KEY)
Now you can import config.py from in other files.
One thing to look out is that once you close that cmd window, these environment values will be unset. So you need to reenter them if you open a new commandline window. Or you can set the values from Control Panel, which then will be inherited by new cmd windows automatically (similar to a .bashrc file).
Using a .env file
Another method is to create a .env file in the root folder of your project, which is a text file formatted like this
SECRET_KEY=s3cr3t SQLALCHEMY_DATABASE_URI=sqlite:///app.db
You SHOULD NOT commit and share these .env files together with other source files. Because then what’s the point of not hard-coding configuration in the source, right?
To import these values, you need to parse it and inject it into app environment. For Python you can use python-dotenv library.
Now we can change config.py into:
# config.py from os import getenv from dotenv import load_dotenv load_dotenv() SECRET_KEY = getenv('SECRET_KEY', None) assert SECRET_KEY # use the key print(SECRET_KEY)
which will allow us to load configuration from both .env file and from environment variables.
A common pattern is to make an .env.sample file with unfilled keys to remind the admin that’s setting up the application to fill those values.
# .env.sample SECRET_KEY= SQLALCHEMY_DATABASE_URI=
Now, as for your questions:
Is setting environment variables and exporting it the same ? If not, how do I export environment variables after setting environment variables so my application can work ?
«export»ing an environment variable is the same with setting them from control panel. Both are ways to remove secrets from the source code. I’ve explained two ways above to make your application work.
How is storing environment variables in .env file different from setting environment variables in Control Panel? Because when I tried to search «Edit .env file in windows» on google, results such as «adding environment variables» come up.
Storing environment variables in .env file is a bit prone to error, because with a small server configuration error, you might expose these secrets to the open for everyone to see. By setting them with set / export you close that vulnerability (a hacker can still get those if he manages to take over your application, because if you notice we can access it using from the app with getenv function).
What is the difference between .bash_profile and .env file ? I ran man bash and it said .bash_profile is The personal initialization file, executed for login shells, but I do not understand whether this means it is totally different from .env file.
Bash is a popular shell application in UNIX systems. .bashrc is a file that gets executed every time you open a terminal. So when you add export ENV_VAR=value commands into it, every terminal you open will effectively have those environment variables already set.
Related Solutions
Bash – Setting environment variables on OS X
Bruno is right on track. I’ve done extensive research and if you want to set variables that are available in all GUI applications, your only option is /etc/launchd.conf .
- Open a terminal prompt
- Type sudo vi /etc/launchd.conf (note: this file might not yet exist)
- Put contents like the following into the file
# Set environment variables here so they are available globally to all apps # (and Terminal), including those launched via Spotlight. # # After editing this file run the following command from the terminal to update # environment variables globally without needing to reboot. # NOTE: You will still need to restart the relevant application (including # Terminal) to pick up the changes! # grep -E "^setenv" /etc/launchd.conf | xargs -t -L 1 launchctl # # See http://www.digitaledgesw.com/node/31 # and http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x/ # # Note that you must hardcode the paths below, don't use environment variables. # You also need to surround multiple values in quotes, see MAVEN_OPTS example below. # setenv JAVA_VERSION 1.6 setenv JAVA_HOME /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home setenv GROOVY_HOME /Applications/Dev/groovy setenv GRAILS_HOME /Applications/Dev/grails setenv NEXUS_HOME /Applications/Dev/nexus/nexus-webapp setenv JRUBY_HOME /Applications/Dev/jruby setenv ANT_HOME /Applications/Dev/apache-ant setenv ANT_OPTS -Xmx512M setenv MAVEN_OPTS "-Xmx1024M -XX:MaxPermSize=512m" setenv M2_HOME /Applications/Dev/apache-maven setenv JMETER_HOME /Applications/Dev/jakarta-jmeter
Windows – command to refresh environment variables from the command prompt in Windows
On Windows 7/8/10, you can install Chocolatey, which has a script for this built-in.
After installing Chocolatey, just type refreshenv .
Interacting With Environment Variables in Python
Accessing, exporting and unsetting environment variables with Python
Introduction
Certain applications may have to make use of variables that have been initialised outside of the program itself, but instead in the environment that the source code is supposed to be executed.
Environment variables are assigned as part of an environment in which processes (such as Python applications) get executed. It is consisted of a name/value pair and can be accessed, overwritten and unset at any given time. Such variables are usually defined directly on the command line interface or with bash scripts (e.g. upon the startup of the operating system). However, even software programs can themselves interact with them.
In today’s short tutorial we will be showcasing how to programmatically access overwrite and unset existing environment variables as well as how to export new ones. Finally, we will also demonstrate a couple of ways for checking wether an environment variable exists.
Accessing environment variable
First, we will demonstrate how we can programmatically access environment variables that were exported already as part of the environment in which our Python application is being executed.
Let’s suppose that a system administrator has initialised an environment variable called ENV with the value dev :
We can verify that the environment variable has been initialised by echoing the value through the command line:
Now if we want to programmatically access the environment variable with Python, we need to use the os.environ mapping object:
A mapping object where keys and values are strings that represent the process environment. For example, environ[‘HOME’] is the pathname of your home directory (on some platforms), and is equivalent to getenv(«HOME») in C.
This mapping is captured the first time the os module is imported, typically during Python startup as part of processing site.py . Changes to the environment made after this time are not reflected in…