Boilerplate how to get started using the Flask framework.
- create new virtual env and install the necessary packages and get a basic Hello World Application running in our browser.
- create register and login form using wtforms
- adding styling(used sass pre-processor - libsass)
- database with Flask-SQLAlchemy
- user authentication
- creating user account with uploading the picture
- adding pagination
- creating custom error pages
- deployment
Virtual Environments in Python allow us to keep project-specific dependencies in a separate place than our global site-packages. This is extremely useful when you have different versions of packages for different projects.
/Environments
virtualenv {nameOfProject}
In case, when you want create new, virtual env with specific version of Python:
virtualenv -p /usr/bin/python2.6 {nameOfProject}
source {nameOfNewProject}/bin/activate
pip install {nameOfPackage}
pip install flask
If you want to go back to being in the global env:
deactivate
Prompt with name of project no longer shows up.
If you want delete virtual env:
rm -rf {nameOfProject}
To enlist all packages:
pip list
You can also use your global site packages within virtual Python environment.
Freezing is a process where pip reads the versions of all installed packages in a local virtual environment and then produces a text file with the package version for each python package specified. By convention, it's named requirements. txt .
pip freeze --local >environment.txt
To make sure you got all packages:
cat environment.txt
You get list of all packages with versions.
In case, you want install those packages from environment.txt in next project:
pip install -r requirements.txt
Create new folder for your application and file app.py, starting with example from the documentation:
from flask import Flask, escape, request
app = Flask(__name__)
@app.route('/')
def hello():
name = request.args.get("name", "World")
return f'Hello, {escape(name)}!'
Before running application you need to set an environment variable to the file, that you want to be flask application.
In line command of your virtual Python environment go to your project's folder and type in:
export FLASK_APP=app.py
On the port 5000 it will show Hello world.
pip install flask-wtf
Create files: register.html and login.html. Build new forms according to documentation using packages below:
- wtforms,
- flash,
- url_for,
- redirect
In the virtual env install new packages:
pip install rcssmin rjsmin sass
Using these 3 packages: - Compiles scss to css - Minifies css - Minifies JavaScript
In new script runner.py:
sass_map = {"app/static/scss/style.scss": "app/static/css/style.css"}
css_map = {"app/static/css/style.css": "app/static/css/style.min.css"}
js_map = {"app/static/js/app.js": "app/static/js/app.min.js"}
def compile_sass_to_css(sass_map):
print("Compiling scss to css:")
for source, dest in sass_map.items():
with open(dest, "w") as outfile:
outfile.write(sass.compile(filename=source))
print(f"{source} compiled to {dest}")
def minify_css(css_map):
print("Minifying css files:")
for source, dest in css_map.items():
with open(source, "r") as infile:
with open(dest, "w") as outfile:
outfile.write(rcssmin.cssmin(infile.read()))
print(f"{source} minified to {dest}")
def minify_javascript(js_map):
print("Minifying JavaScript files:")
for source, dest in js_map.items():
with open(source, "r") as infile:
with open(dest, "w") as outfile:
outfile.write(rjsmin.jsmin(infile.read()))
print(f"{source} minified to {dest}")
Add to app.py:
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.min.css') }}">
install new package in virtual env:
pip install flask-sqlalchemy
and import into application. After that, choose location of database and create database instance:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
After creating tables, import database from application file:
$ python
>>> from app import db
>>> db.create_all()
>>> from app import User, Recipe
After that, create user and add into a database:
>>> user_1 = User(username='user', email='[email protected]', password='password')
>>> db.session.add(user_1)
pip install flask-bcrypt
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for application. To use the extension simply import the class wrapper and pass the Flask app object.
What is hashing function? It takes plain text and turns into a string of text that always has the same length. And it works only one way.
Bcrypt takes a password as input along with a salt and a cost. Salt is a fixed-length cryptographically-strong random value that is added to the input of hash functions to create unique hashes for every input. A salt is added to make a password hash output unique even for users adopting common passwords.
@app.route("/recipe/new", methods=['GET', 'POST'])
@login_required
def new_recipe():
form = RecipeForm()
if form.validate_on_submit():
recipe = Recipe(title=form.title.data, content=form.content.data, ingredients=form.ingredients.data, image_file_recipe=form.picture.data, tag=form.tag.data, author=current_user)
db.session.add(recipe)
db.session.commit()
flash('Twój przepis został dodany!', 'success')
return redirect(url_for('home'))
return render_template('new_recipe.html', title='New Title', form=form)
validate_on_submit will check if it is a POST request and if it is valid.
On the home route add variable recipes, which gather all those recipes from the database:
def home():
recipes = Recipe.query.all()
return render_template('home.html', recipes=recipes)
In the html add form:
<form action="/upload-image" method="POST" enctype="multipart/form-data">
</form>
enctype="multipart/form-data" allows to send files and upload from database. We'll be making a POST request to the server, so we've added methods=["GET", "POST"] to the route.
There are two parts, the client index.html which asks the user to browse for a file, the client then sends a multipart POST (enctype="multipart/form-data") request and the server back-end python side where it accepts the file and saves it on the server.