Flask is the go-to micro web framework written in Python for anyone looking to build small applications and APIs with ease. Its simplicity and flexibility make it an excellent choice, especially if you’re just starting out or prefer an uncluttered environment. Here’s a handy guide to get you up and running with Flask, even to the point of mastering it.
First things first, you’ll need to install Flask. Fortunately, that’s easy-peasy with pip, Python’s package manager. Simply open your terminal and punch in the command:
python -m pip install Flask
With Flask installed, you can dive right into creating your very first app. Let’s start with a basic “Hello, World!” application. This example gets you up and running with the minimum code required to have a functional Flask app:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World'
if __name__ == '__main__':
app.run(debug=True)
This snippet sets up a simple Flask application with a single route for the root URL (’/’) that returns “Hello, World!” whenever someone visits that URL. Next, let’s look at structuring your application for something more substantial.
When applications get larger, it’s a good idea to organize your code neatly. Blueprints are a way to chop up your app into smaller, reusable components. Here’s how you can layout your project with Blueprints:
project/
run.py
project/
__init__.py
config.py
forms.py
models.py
admin/
__init__.py
routes.py
main/
__init__.py
routes.py
templates/
index.html
static/
css/
style.css
Your run.py
, the main entry point, should look like this:
from project import app
if __name__ == '__main__':
app.run()
In project/__init__.py
, register the Blueprints like so:
from flask import Flask
from project.main.routes import main
from project.admin.routes import admin
app = Flask(__name__)
app.register_blueprint(main, url_prefix='/')
app.register_blueprint(admin, url_prefix='/admin')
Here’s how you define routes inside your Blueprints:
For project/main/routes.py
:
from flask import Blueprint
main = Blueprint('main', __name__)
@main.route('/')
def index():
return "Hello, World! This is the main page."
And for project/admin/routes.py
:
from flask import Blueprint
admin = Blueprint('admin', __name__)
@admin.route('/')
def index():
return "Hello, World! This is the admin page."
Let’s talk configuration. Flask allows you to set configuration values directly or via external files. You can directly set a configuration value like this:
app.config['CONFIG_NAME'] = 'config value'
Or import configurations from an environment variable:
app.config.from_envvar('ENV_VAR_NAME')
Routing is essential for any web app, and Flask makes it super simple. Define routes using the @app.route
decorator. For example, to create a route that accepts a string parameter:
@app.route('/hello/<string:name>')
def hello(name):
return 'Hello ' + name + '!'
You can specify which request methods are allowed for a route too:
@app.route('/test', methods=['GET', 'POST'])
def test():
if request.method == 'POST':
# Handle POST request
pass
else:
# Handle GET request
pass
Flask uses the Jinja2 template engine for rendering HTML. You can easily pass variables from your route functions to the templates. Here’s an example:
from flask import render_template
@app.route('/')
def index():
data = {'company_name': "TCET"}
return render_template('hello_world.html', data=data)
And the corresponding hello_world.html
template:
<h1>Hello World</h1>
<h3>Welcome to {{ data['company_name'] }}</h3>
Flask is also great for returning JSON responses, making it ideal for creating REST APIs. Here’s an example of how to return a JSON response:
from flask import jsonify
@app.route('/returnstuff')
def returnstuff():
num_list = [1, 2, 3, 4, 5]
num_dict = {'numbers': num_list, 'name': 'Numbers'}
return jsonify({'output': num_dict})
Accessing request data is straightforward with Flask. Here are some ways to get at incoming request data:
-
Query String Arguments:
num1 = int(request.args.get('num1'))
-
Form Data:
num1 = int(request.form['num1'])
-
Request Method:
if request.method == 'POST': # Handle POST request pass
-
Cookies:
cookie_value = request.cookies.get('cookie_name')
-
Files:
file = request.files['file']
Redirecting users to different routes is also super simple in Flask. You can use the redirect
function like this:
from flask import url_for, redirect
@app.route('/redirect')
def redirect_example():
return redirect(url_for('home'))
When things go wrong, you can handle errors gracefully using Flask’s abort
function and custom error handlers.
Here’s an example of handling a 404 error:
from flask import abort
@app.route('/')
def index():
abort(404)
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html', title='404: Missing Page'), 404
Session handling in Flask is cool and secure. Here’s a quick look at how to set and read session variables:
from flask import session
app.config['SECRET_KEY'] = 'your_very_secure_key'
@app.route('/login_success')
def login_success():
session['key_name'] = 'key_value'
return redirect(url_for('index'))
@app.route('/')
def index():
if 'key_name' in session:
session_var = session['key_name']
# Use the session variable
else:
# Handle the case where the session does not exist
pass
Flask doesn’t come with a built-in database abstraction layer, but extensions like SQLAlchemy can help. Here’s how you can define a model using SQLAlchemy:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(256))
def __init__(self, body):
self.body = body
def __repr__(self):
return "<Post({})>".format(self.id)
Initialize the database in your application like this:
app = Flask(__name__)
app.config.from_object(config.DevelopmentConfig)
with app.app_context():
db.init_app(app)
For advanced applications, you might need authentication and authorization. Here’s an example using a custom decorator to authorize requests:
from functools import wraps
from flask import make_response
def authorize(f):
@wraps(f)
def decorated_function(*args, **kwargs):
err_msg = "Authentication required"
if request.authorization is None:
return make_response('Not Authorized', 403, {'WWW-Authenticate': err_msg})
username = request.authorization.username
password = request.authorization.password
if username == 'admin' and password == 'admin@123':
return f(*args, **kwargs)
return make_response('Not Authorized', 403, {'WWW-Authenticate': err_msg})
return decorated_function
class MyApi(Resource):
method_decorators = [authorize]
def get(self):
return {"msg": "get method"}
def post(self):
return {"msg": "post method"}
def put(self):
return {"msg": "put method"}
def delete(self):
return {"msg": "delete method"}
This decorator checks for basic HTTP authentication and throws a 403 error if the credentials are off.
In conclusion, Flask is a mighty yet nimble microframework perfect for a wide array of web applications. Its straightforward, flexible nature makes it a darling among developers. These examples and best practices can set you on a path to building robust web applications with Flask. Dive in and happy coding!