23
Dealing with Environment Variables in Flask
Welcome to yet another article. Thanks for being a dedicated reader. More knowledge unto you, more skills learnt, and a better you. Before we begin on today's article, we will just have a brief recap of what we have learned over the course of time together.
Python is a widely-used, interpreted, object-oriented, and high-level programming language with dynamic semantics, used for general-purpose programming.
It was created by Guido van Rossum as a 'hobby' programming project.
- Because it is an easy and intuitive language;
- Open source programming language. As a result, everyone may contribute to its growth;
- Code that is as simple to comprehend as plain English;
- Appropriate for day-to-day work, with quick development times
Python has its application domains in many areas and these are but not limited to;
- Web Applications
- Data Science
- Mobile Applications
- Big Data
- Artificial Intelligence
- Automation
- Testing
To have a more detailed Introduction to Python, please feel free to check out this resource. Python Basics, Pythons 101!
Once that article has been read, we have a look at some concepts in Python worth remembering. These may not be explained exhaustively for beginners but gives a refresher to intermediate and expert python programmers. Even beginners can relate, good news!!
Literals are data whose values are decided by the literal itself, which Python provides out of the box.
Common literals in Python include;
- Numeric literals
- Strings literals
- Special literal None
- Boolean literals
- Collection literals
In simple terms, literals are the raw data that are assigned to variables or constants while programming.
Python supports out of the box support for arithmetic operations. With it you can perform these operations using expressions and operators.
A variable is a named location reserved to store values in the memory.
Whenever you want to store results from operations, use a container called a variable to store them. When naming variables, make sure you follow the PEP Standards defined here, PEP 8 --Style Guide for Python Code
Comments can be used to add more information to your code. At runtime, they are removed. Human readers are addressed by the information left in source code. A comment in Python is a line of text that starts with #
for single line and """
for multi-line comments
A function is a group of related statements that perform a given task. So whenever you call a function, those statements will perform that task, however many times you call the function.
Functions help us as programmers to;
- Avoid code repetitions
- Have cleaner and readable code
- Decompose large problems into small chunks.
There are 3 major types of functions these are;
- In-built functions
- User defined functions
- Pre-Installed module functions
For a more detailed guide on functions, please check out this resource. Introduction to Python Functions
Great, welcome back from that recap about Python. Remember, the more you familiarize yourself with what Python is and how you use it, the better programmer you become at Python.
Every expert was once a beginner.
So one of the application domains of Python is Web development. You can use it to make powerful and fast web applications. In so making, a number of tools and frameworks have been developed to aid web development in Python.
Some of these are but not limited to;
- Django
- Flask
- Pyramid
(The picture below shows a list of web frameworks using Python)
Our focus will be on the Flask framework. For an Introduction to FLASK, please checkout their official documentation.
Official Flask Documentation
And for a quick overview on how to get started with Python Web development, consider looking into, Getting Started with Python Web Development using FLASK
Once you have mastered the basic overview of flask, we will dive into the topic of the day. Phew!!! What an introduction !!! Hope you are enjoying the article. Let us refocus now.
Given a minimal Flask application, such as;
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World, dear Friend!'
@app.route('/page/<int:page_num>')
def content(page_num):
return f'<h1>Yoo.. It is your page {page_num}</h1>'
if __name__ == '__main__':
app.run(host='',port='',debug=True)
The minimal application can be run following the steps below, (as you might be familiar),
On Bash
export FLASK_APP=app.py
flask run
Other scenarios you might want to specify the host and port number, environment, debug mode etc. for which you want your flask application to run, you would have to include all that into the export command
above.
That can become tedious over time as you develop your cool project, pressing up arrow key many times to retrace the export command (bash users, you know what I mean).
Our goal is to save some time and when running our flask application, we simply do;
On Bash
flask run
The variables that we add to the export command
are known as environment variables. These variables are used by your flask application to serve your project.
- FLASK_ENV
- FLASK_DEBUG.
- FLASK_RUN_EXTRA_FILES
- FLASK_RUN_HOST
- FLASK_RUN_PORT
- FLASK_RUN_CERT
- FLASK_RUN_KEY
Those are default flask environment variables defined by the framework. If not specified, they use their default values.
Also, if you wanted to connect your application to a database, you would have to hard code your credentials into your python code, which is not recommended.
A simple example would be;
from flask import Flask
app = Flask(__name__)
app.config[MYSQL_USER]="your_username"
app.config[MYSQL_HOST]="localhost"
app.config[MYSQL_DB]="my_appdb"
app.config[MYSQL_PASSWORD]="your_password"
@app.route('/')
def index():
return {'Message': 'Hello World'}
That kind of hard coding credentials is not ideal if you are working on a large project with other people
Incase you do not follow Strict password policies and use one password everywhere....You are hacked!!!. You just shared your password with the world.
We are going to see how to load flask environment variables automatically. You are here because you're tired of setting environment variables every time you are running your flask app? Variables like FLASK_APP or FLASK_ENV using export command
. Am going to help you do just that.
In your virtual environment, run;
pip install python-dotenv
I emphasize, always use virtual environments on your system to prevent corrupting your main Python installation. In case you want a recap on how to create virtual environments, refer to this guide. Creation of Virtual Environments
On Bash
touch .env
touch .flaskenv
Depending on your use case, this will guide you on what to include.
In .flaskenv
//this is the .flaskenv file
FLASK_ENV - Controls the environment.
FLASK_DEBUG - Enables debug mode.
FLASK_RUN_EXTRA_FILES - A list of files that will be watched by the re-loader in addition to the Python modules.
FLASK_RUN_HOST - The host you want to bind your app to.
FLASK_RUN_PORT - The port you want to use.
FLASK_RUN_CERT - A certificate file for so your app can be run with HTTPS.
FLASK_RUN_KEY - The key file for your cert.
for example; FLASK_APP=app.py
Boom, great work done. To run your app now, Simply do run;
That was fast,.... right?? Yes so you can now focus on programming instead of looking for which flask environment variable is missing.
Yes getting to that now. Follow this guide.
These can include;
- Login credentials to the database
- API keys
- SECRET_KEY (among others)
In .env
//This is the .env file
MYSQL_USER=root
MYSQL_PASSWORD=my_mysql_password
MYSQL_DB=userdb
MYSQL_HOST=localhost
SECRET_KEY=topsecretkey
API_KEY=donotsharethisapikeywithanyone
(Since these variables are not served automatically, we have to load them through this settings.py
file)
In settings.py
//This is the settings.py file
from os import environ
SECRET_KEY=environ.get('SECRET_KEY)
API_KEY=environ.get('API_KEY')
MYSQL_USER=environ.get('MYSQL_USER')
//add any more variables you have
Note: For consistency, it is good to keep the same variable name as the environment variable.
In your app.py
, the file that has your flask object.
app.config.from_pyfile('settings.py')
# loading all environment variables from settings.py
So what happens is that the settings.py will read the values you placed in your .env file and store them in variables as you defined them in settings.py.
When you use the flask object's config method, together with the from_pyfile
sub-method, the app will have access to the secretly defined variables in a secure way.
Run your app as before, and boom you can now serve the world with your cool project
To avoid surbotaging your efforts to secure your credentials, when using a version control system such as git , do not push the .flaskenv and .env files. You can use .gitignore file to ignore them in your project directory. They remain on your local system.
I love to learn with you dear reader. Share your feedback with me in the discussion section below. Are there better ways to do this?
A great friend improves another, feel free to share
I appreciate all the feedback in advance.
23