Flask Environment Configuration
Your application may require a large number of packages to work properly. If you don't need a flask package, you may have read the wrong tutorial. When the application is running, the environment of your application is basically the foundation of all things. We are fortunate because there are many ways in which we can manage our environment easily.
use virtualenv to manage your environment
Virtualenv is a tool for isolating your application in a so-called virtual environment. A virtual environment is a directory of software that contains your application dependencies. A virtual environment can also change your environment variables to maintain the environment variables that your development environment contains. Instead of downloading packages, like flask, to your system-level or user-level package directory, we can download them to a separate directory that is used only for our application. This makes it easy to specify the version of Python to use and the packages that each project relies on.
Virtualenv can also allow you to use different versions of the same package in different projects. This flexibility may be very important if you are using an older system and there are several items on it that require a different version.
When using virtualenv, you usually only need to install a few Python packages on your system. One of them is virtualenv itself. You can use the Pip to install the VIRTUALENV package.
Once you have Virtualenv installed on your system, you can start creating a virtual environment. Go to the directory where your project is located and run the virtualenv command. It requires a parameter, which is the target directory of the virtual environment. The following shows what it looks like.
$ virtualenv venv
New python executable in Venv/bin/python
installing Setuptools ..... [...] ... done.
Installing Pip ........... [...] ... done.
Virtualenv creates a new directory, and the dependency pack will be installed in this directory.
Once the new virtual environment has been created, you must activate it by launching the Bin/activate script created in the virtual environment.
$ which Python
/usr/local/bin/python
$ source venv/bin/activate
(venv) $ which Python
/users/robert/ Code/myapp/venv/bin/python
The Bin/activate script makes some changes to your shell environment variables so that everything points to the new virtual environment rather than the global system. You can see the effect in the code block above. After activation, the Python command points to the bin directory of Python in the virtual environment. When the virtual environment is activated, the dependent packages that are installed using Pip are downloaded to the virtual environment rather than the global system.
You may notice that the prompt in the shell has also changed. Virtualenv the name of the current activation virtual environment, so you will know that you are not working on the global system.
You can deactivate your virtual environment by running the Deactivate command.
Virtualenvwrapper
Virtualenvwrapper is a software package that manages the virtual environment created by Virtualenv. I don't want to mention this tool until you see the basics of virtualenv so you understand what it improves and why we should use it.
The virtual Environment directory created in the previous section brings some confusion to your project library. You only need to activate the virtual environment and interact with it, but it should not be in version control, so this virtual environment directory should not be here. The solution is to use Virtualenvwrapper. This package will put all your virtual environment in a directory way, usually by default in ~/.virtualenvs/.
To install Virtualenvwrapper, follow the instructions in the documentation, which is located in http://virtualenvwrapper.readthedocs.org/en/latest/install.html.
Make sure that you have deactivated all of your virtual environments before installing Virtualenvwrapper. You need to install it in the global system, not in the virtual environment.
Now, instead of running virtualenv to create an environment, you need to run MKVIRTUALENV:
$ mkvirtualenv Rocket
New python executable in Rocket/bin/python
installing Setuptools ..... [...] ... done.
Installing Pip ........... [...] ... done.
(rocket) $
Mkvirtualenv creates a folder in your virtual environment directory and activates the virtual environment for you. Like the virtualenv above, Python and Pip point to binary files in the virtual environment rather than the global system. To activate a specific environment, use the command: Workon [environment name]. Deactivate will still deactivate the virtual environment.
Install Dependency Pack
as the project progresses, you will find that the list of dependent packages increases. It is not uncommon to need dozens of Python packages to run a flask application. The easiest way to manage these is to use a simple text file. The PIP can generate a text file that lists all installed packages. On a new system, or in a new environment just created, you can read the list in the file and install each of them.
Requirements.txt is a text file that is used by many flask applications to list all the packages needed to run the application. This block of code is used to illustrate how to create this file, and then the next code block is used to illustrate the use of this file in a new environment to install a dependency pack.
(rocket) $ pip freeze > Requirements.txt
$ workon fresh-env
(fresh-env) $ pip install-r requirements.txt
[ ...]
Successfully installed Flask Werkzeug JINJA2 itsdangerous markupsafe up
...
(fresh-env) $
Manual Management dependency Pack
as the project progresses, you may find that some of the packages listed in the PIP freeze are not actually required to run the application. You install these packages only for development purposes. Pip freeze is not distinguishable, it simply lists the packages that are currently installed. As a result, you may want to manually manage these dependency packs. You can place the packages that are required to run the application into Require\_run.txt and the packages that are needed to develop the application into require\_dev.txt.
version Control
selects a version control system and uses it. I recommend Git. From what I've seen, Git is the most popular choice for new projects these days. It is invaluable to be able to delete code without having to worry about making an irreversible mistake. You can also get your project out of the way of a lot of annotated code, because you can delete them and recover them if you need them later. Alternatively, you can back up the entire project on Github,bitbucket or on your own gitolite server.
Files outside version control
I usually put a file outside of version control for two reasons: either it makes the whole project messy, or it's a very private key/certificate. Compiled. pyc files and virtual environments-if for some reason you are not using virtualenvwrapper-is an example of confusing the project. They do not need to be in version control because they can be recreated separately from the. py file and your requirements.txt file. The
API secret key, Application secret key, and database certificate are examples of very private keys/certificates. They should not appear in version control because their exposure would be a huge security vulnerability.
When it comes to security-related decisions, I always like to assume that my version library will become public at some point. This means keeping a secret and never assuming that a security breach will not be found, and "who will guess what they can do" this type of assumption is called hiding to achieve security, which is a very bad strategy.
When you use Git, you can create a special file named. Gitignore in your version library. In this file, use a list wildcard to match the filename. Any filename that matches one of these patterns will be ignored by Git. I recommend using. Gitignore to control files that do not require version control. For example,
The Instance folder is an application-sensitive configuration variable that is provided to you in a more secure manner. I'll talk more about it in the back.
You can read more about the. Gitignore content from here: Http://git-scm.com/docs/gitignore
Debugging
1. Debug mode
Flask has a convenient feature called debug mode. To turn on debugging, you only have to set debug = True in your development configuration. When it is turned on, the server will automatically load when the code changes and an error will accompany a stack trace and an interactive console.
Be careful! Do not use debug mode in a production environment. The interactive console allows arbitrary code execution and can be a huge security vulnerability.
2.flask-debugtoolbar
Flask-debugtoolbar is another great tool that can help you debug problems in your application. In debug mode, it places a sidebar on every page of your application. Sidebar provides information about SQL queries, log records, versions, templates, configurations, and other interesting things that make it easier to track issues.
Look at the debugging mode in QuickStart. There are some good information about error handling, logging, and using the debugger in the Flask official documentation.
Flask project Configuration
When you learn flask, the configuration looks very simple. You just have to define some variables in the config.py then everything will work. These simplicity starts to fade when you start to manage the configuration of your production applications. You may need to protect the API keys and use different configurations for different environments (for example, development and production environments). In this section we will introduce some of the advanced features of flask, which make it easier to manage the configuration.
A simple example
A simple application may not require any of these complex features. You may only need to place config.py in the root of your warehouse/repository and load it in app.py or yourapp/\\_init\\_.py.
The config.py file should contain a configuration variable assignment per row. When your application initializes, the configuration variables in config.py are used to configure flask and its extensions and they can be accessed through the app.config dictionary-for example, app.config["DEBUG".
DEBUG = True # turns on debugging features in flask
bcrypt_level = # Configuration for the Flask-bcrypt extension
mail_from_email = "robert@example.com" # for use in application emails
The configured variable can be flask, its extension or you to use it. In this example, whenever we need a default "sender" in a transactional message, we can use the app.config["Mail_from_email"]– for example, a password reset. Placing this information in a configuration variable makes it easy to modify it later.
# app.py or app/__init__.pyfrom flask import flask
app = Flask (__name__)
app.config.from_object (' config ')
# Now we can access the configuration variables via app.config[' Var_name '.
- Debug: Provides you with some handy tools for debugging errors. This includes a web-based stack trace and an interactive Python console. Set to True in the development environment, set to False in the production environment.
- Secret\_key: This is the key that flask uses to sign cookies. It can also be used as an extension of the Flask-bcrypt class. You should define it in your instance folder so that you can stay away from version control. You can read more about the sample folder in the next section. In general, this should be a complex random value.
- Bcrypt\_level: If you use Flask-bcrypt to hash out the user's password, you need to specify a "loop" number that is required for the algorithm that executes the hash cipher. If you don't use flask-bcrypt, you can ignore it here. The larger the number of loops used for hashing passwords, the longer the attacker guesses the password. At the same time, the number of loops increases the time of hashing the password. Later we will give some best practices for using Bcrypt in flask applications.
Make sure that DEBUG is set to False in the production environment. If you leave DEBUG true, it allows the user to execute arbitrary Python on your server.
Instance Folder
Sometimes you need to define a configuration variable that contains sensitive information. We want to detach these variables from the config.py and keep them out of the warehouse/version library. You may hide sensitive information like database passwords and API keys, or define configuration variables that are specific to the specified machine. To make it easier to implement these requirements, Flask provides a feature called instance folders. The instance folder is a subdirectory under the Warehouse/version library and contains a configuration file specifically for instances of this application. We do not want it submitted to version control.
config.py
requirements.txt
run.py
instance/
config.py
yourapp/ models.py
views.py
templates/
static/
Working with instance folders
we use App.config.from_pyfile () to load configuration variables from an instance folder. When we call flask () to create our application, if we set the Instance_relative_config=true, App.config.from_pyfile () will load the specified file from the instance/directory.
# app.py or app/__init__.py
app = Flask (__name__, instance_relative_config=true)
app.config.from_object (' Config ')
app.config.from_pyfile (' config.py ')
Now we can define configuration variables in the instance/config.py as we do in config.py. You should also add your instance folder to the Ignore list in the version control system. To do this with Git, you need to add instance/to a new line in the. Gitignore.
Secret key
The privacy of an instance folder becomes the best candidate within it to define a key that you do not want to expose to version control. These keys may contain your application's key or Third-party API key. This is especially important if your application is open source or may be published in the future. We usually ask other users or contributors to use their own keys.
# instance/config.py
secret_key = ' Sm9obibty2hyb20ga2lja3mgyxnz '
stripe_api_key = ' smfjb2igs2fwbgfulu1vc3mgaxmgysbozxjv '
sqlalchemy_database_uri= \ Postgresql://user: Twljaghfgibcyxj0b3n6a2lld2ljeieh@localhost/databasename "
Environment-based configuration
If the difference between your production environment and your development environment is very small, you may want to use an instance folder to handle configuration changes. Configuration variables defined in ' instance/config.py ' files can overwrite values in ' config.py '. You only need to call ' app.config.from_pyfile () ' After ' App.config.from_object () '. One of the benefits of this usage is to modify the configuration of your application on different machines.
# config.py
debug = False
Sqlalchemy_echo = False
# instance/config.py
debug = True
sqlalchemy_ ECHO = True
In the production environment, we omit the configuration variable from the ' instance/-config.py ' above, and it returns to the value defined in ' config.py '.
Learn more about Flask-sqlalchemy configuration items. (The Chinese version is located in: Http://www.pythondoc.com/flask-sqlalchemy/config.html#configuration-keys)
configuration based on environment variables
The instance folder should not appear in version control. This means that you will not be able to track changes to your instance configuration. If it's just one or two variables, this may not be a problem, but if you fine-tune your configuration in different environments (production, pre-upgrade, development, etc.), you don't want to risk losing them.
Flask gives us the ability to choose a profile, which can load a different configuration file based on the value of an environment variable. This means that in our warehouse/version library We can have multiple profiles and always load the right one. Once we have more than one configuration file, I can move them into their config folder.
Requirements.txt
run.py
config/
__init__.py # Empty, just-to-tell Python, it's a package.
default.py
production.py
development.py
staging.py
instance/
config.py
__init__.py
models.py
views.py
static/
templates/
We have a number of different profiles in the file list above.
- config/default.py: The default configuration value that can be used for all environments or to be overwritten by a personal environment.
- config/development.py: The configuration value for the development environment. Here you may specify the URI of the local database.
- config/production.py: The configuration value for the production environment. DEBUG must be set to False here.
- config/staging.py: Depending on the development progress, you may have a simulated production environment, this file is mainly used for this scenario.
In order to decide which configuration file to load, we call ' App.config.from_envvar () '.
# yourapp/\\_\\_init\\_\\_.py
app = Flask (__name__, Instance_relative_config=true)
# Load the default Configuration
app.config.from_object (' Config.default ')
# Load The configuration from the instance folder
App.config.from_pyfile (' config.py ')
# Load The file specified by the App\\_config\\_file environment variable# Variables defined here'll override those in the default configuration
app.config.from_envvar (' App_config_file ')
The value of the environment variable should be the absolute path of the configuration file.
How we set this environment variable depends on the platform where we run the application. If we run on an ordinary Linux server, we can write a shell script that sets the environment variables and run run.py.
# start.sh
app\\_config\\_file=/var/www/yourapp/config/production.py
python run.py
Start.sh is unique to every environment, so it should be excluded from version control. On the Heroku, we need to use the Heroku tool to set the environment variable. This setting is also applicable to other PaaS platforms.