Flask Python
Flask Python
Release 0.11.dev
January 11, 2016
Contents
Users Guide
Foreword
1.1 What does micro mean? . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Configuration and Conventions . . . . . . . . . . . . . . . . . . . . . . .
1.3 Growing with Flask . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
3
4
5
5
5
6
Installation
3.1 virtualenv . . . . . . . . . . . .
3.2 System-Wide Installation . . .
3.3 Living on the Edge . . . . . . .
3.4 pip and setuptools on Windows
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
7
8
9
9
Quickstart
4.1 A Minimal Application . . . . . . . . .
4.2 What to do if the Server does not Start .
4.3 Debug Mode . . . . . . . . . . . . . . .
4.4 Routing . . . . . . . . . . . . . . . . . .
4.5 Static Files . . . . . . . . . . . . . . . . .
4.6 Rendering Templates . . . . . . . . . . .
4.7 Accessing Request Data . . . . . . . . .
4.8 Redirects and Errors . . . . . . . . . . .
4.9 About Responses . . . . . . . . . . . . .
4.10 Sessions . . . . . . . . . . . . . . . . . .
4.11 Message Flashing . . . . . . . . . . . . .
4.12 Logging . . . . . . . . . . . . . . . . . .
4.13 Hooking in WSGI Middlewares . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
12
13
14
18
18
20
23
24
24
26
26
26
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tutorial
5.1 Introducing Flaskr . . . . . . . .
5.2 Step 0: Creating The Folders . .
5.3 Step 1: Database Schema . . . .
5.4 Step 2: Application Setup Code .
5.5 Step 3: Database Connections . .
5.6 Step 4: Creating The Database .
5.7 Step 5: The View Functions . . .
5.8 Step 6: The Templates . . . . . .
5.9 Step 7: Adding Style . . . . . . .
5.10 Bonus: Testing the Application .
Templates
6.1 Jinja Setup . . . . . . . . .
6.2 Standard Context . . . . .
6.3 Standard Filters . . . . . .
6.4 Controlling Autoescaping
6.5 Registering Filters . . . .
6.6 Context Processors . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
29
29
30
31
31
33
34
36
37
39
40
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
41
41
41
42
43
43
44
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
45
45
45
46
47
48
48
49
50
51
Application Errors
8.1 Error handlers . . . . . . .
8.2 Error Mails . . . . . . . . .
8.3 Logging to a File . . . . . .
8.4 Controlling the Log Format
8.5 Other Libraries . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
53
53
54
55
56
57
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10 Configuration Handling
61
10.1 Configuration Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
10.2 Builtin Configuration Values . . . . . . . . . . . . . . . . . . . . . . . . . 62
10.3 Configuring from Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
ii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
69
69
71
71
72
72
72
12 Pluggable Views
12.1 Basic Principle . . . . . . .
12.2 Method Hints . . . . . . . .
12.3 Method Based Dispatching
12.4 Decorating Views . . . . . .
12.5 Method Views for APIs . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
73
73
74
75
75
76
.
.
.
.
79
79
80
80
80
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
83
83
84
84
85
86
86
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
89
89
90
90
90
91
93
93
.
.
.
.
.
.
16 Flask Extensions
95
16.1 Finding Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
16.2 Using Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
16.3 Flask Before 0.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
17 Command Line Interface
97
17.1 Basic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
iii
17.2
17.3
17.4
17.5
17.6
17.7
17.8
17.9
Virtualenv Integration
Debug Flag . . . . . .
Running a Shell . . . .
Custom Commands .
Application Context .
Factory Functions . .
Custom Scripts . . . .
The Script Info . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
98
98
98
98
99
99
100
101
18 Development Server
103
18.1 Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
18.2 In Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
19 Working with the Shell
19.1 Command Line Interface . . . . . . . .
19.2 Creating a Request Context . . . . . . .
19.3 Firing Before/After Request . . . . . .
19.4 Further Improving the Shell Experience
20 Patterns for Flask
20.1 Larger Applications . . . . . . . .
20.2 Application Factories . . . . . . .
20.3 Application Dispatching . . . . . .
20.4 Implementing API Exceptions . .
20.5 Using URL Processors . . . . . . .
20.6 Deploying with Distribute . . . .
20.7 Deploying with Fabric . . . . . . .
20.8 Using SQLite 3 with Flask . . . . .
20.9 SQLAlchemy in Flask . . . . . . .
20.10 Uploading Files . . . . . . . . . . .
20.11 Caching . . . . . . . . . . . . . . .
20.12 View Decorators . . . . . . . . . .
20.13 Form Validation with WTForms .
20.14 Template Inheritance . . . . . . . .
20.15 Message Flashing . . . . . . . . . .
20.16 AJAX with jQuery . . . . . . . . .
20.17 Custom Error Pages . . . . . . . .
20.18 Lazily Loading Views . . . . . . .
20.19 MongoKit in Flask . . . . . . . . .
20.20 Adding a favicon . . . . . . . . . .
20.21 Streaming Contents . . . . . . . .
20.22 Deferred Request Callbacks . . . .
20.23 Adding HTTP Method Overrides
20.24 Request Content Checksums . . .
20.25 Celery Based Background Tasks .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
105
105
105
106
106
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
109
109
111
113
117
118
121
123
127
130
133
137
138
141
143
144
147
150
151
153
156
157
158
160
160
161
21 Deployment Options
165
21.1 Hosted options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
21.2 Self-hosted options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
iv
22 Becoming Big
22.1 Read the Source. . . . . . . .
22.2 Hook. Extend. . . . . . . . .
22.3 Subclass. . . . . . . . . . . . .
22.4 Wrap with middleware. . . .
22.5 Fork. . . . . . . . . . . . . . .
22.6 Scale like a pro. . . . . . . . .
22.7 Discuss with the community.
II
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
API Reference
23 API
23.1
23.2
23.3
23.4
23.5
23.6
23.7
23.8
23.9
23.10
23.11
23.12
23.13
23.14
23.15
23.16
23.17
23.18
23.19
23.20
23.21
III
.
.
.
.
.
.
.
Application Object . . . . . .
Blueprint Objects . . . . . . .
Incoming Request Data . . .
Response Objects . . . . . . .
Sessions . . . . . . . . . . . .
Session Interface . . . . . . .
Test Client . . . . . . . . . . .
Application Globals . . . . .
Useful Functions and Classes
Message Flashing . . . . . . .
JSON Support . . . . . . . . .
Template Rendering . . . . .
Configuration . . . . . . . . .
Extensions . . . . . . . . . . .
Stream Helpers . . . . . . . .
Useful Internals . . . . . . . .
Signals . . . . . . . . . . . . .
Class-Based Views . . . . . .
URL Route Registrations . .
View Function Options . . .
Command Line Interface . .
179
179
179
179
180
180
180
181
183
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Additional Notes
185
185
207
212
215
216
216
220
220
221
228
229
231
232
235
235
236
238
242
243
245
246
249
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
251
251
252
252
253
254
254
25 HTML/XHTML FAQ
255
25.1 History of XHTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
25.2 History of HTML5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
v
25.3
25.4
25.5
25.6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
256
257
258
259
26 Security Considerations
261
26.1 Cross-Site Scripting (XSS) . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
26.2 Cross-Site Request Forgery (CSRF) . . . . . . . . . . . . . . . . . . . . . . 262
26.3 JSON Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
27 Unicode in Flask
27.1 Automatic Conversion . . . . . .
27.2 The Golden Rule . . . . . . . . .
27.3 Encoding and Decoding Yourself
27.4 Configuring Editors . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
265
265
266
266
266
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
269
269
270
271
272
274
274
275
275
276
29 Pocoo Styleguide
29.1 General Layout . . . . . . .
29.2 Expressions and Statements
29.3 Naming Conventions . . .
29.4 Docstrings . . . . . . . . . .
29.5 Comments . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
277
277
278
279
280
280
.
.
.
.
.
30 Python 3 Support
31 Upgrading to Newer Releases
31.1 Version 1.0 . . . . . . . . .
31.2 Version 0.10 . . . . . . . .
31.3 Version 0.9 . . . . . . . . .
31.4 Version 0.8 . . . . . . . . .
31.5 Version 0.7 . . . . . . . . .
31.6 Version 0.6 . . . . . . . . .
31.7 Version 0.5 . . . . . . . . .
31.8 Version 0.4 . . . . . . . . .
31.9 Version 0.3 . . . . . . . . .
281
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
283
283
284
284
285
285
288
289
289
289
32 Flask Changelog
291
32.1 Version 1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
vi
32.2
32.3
32.4
32.5
32.6
32.7
32.8
32.9
32.10
32.11
32.12
32.13
32.14
32.15
32.16
32.17
32.18
32.19
32.20
32.21
Version 0.10.2
Version 0.10.1
Version 0.10 .
Version 0.9 . .
Version 0.8.1 .
Version 0.8 . .
Version 0.7.3 .
Version 0.7.2 .
Version 0.7.1 .
Version 0.7 . .
Version 0.6.1 .
Version 0.6 . .
Version 0.5.2 .
Version 0.5.1 .
Version 0.5 . .
Version 0.4 . .
Version 0.3.1 .
Version 0.3 . .
Version 0.2 . .
Version 0.1 . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
293
293
293
295
297
297
298
298
298
299
300
300
301
301
301
302
302
302
303
303
33 License
33.1 Authors . . . . . . . . . . .
33.2 General License Definitions
33.3 Flask License . . . . . . . .
33.4 Flask Artwork License . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
305
305
306
306
307
vii
viii
Part I
USERS GUIDE
This part of the documentation, which is mostly prose, begins with some background
information about Flask, then focuses on step-by-step instructions for web development with Flask.
CHAPTER 1
Foreword
Read this before you get started with Flask. This hopefully answers some questions
about the purpose and goals of the project, and when you should or should not be
using it.
CHAPTER 2
Depending on the kind of attack, chances are that automated bots are probing for ways
to fill your database with spam, links to malicious software, and the like.
Flask is no different from any other framework in that you the developer must build
with caution, watching for exploits when building to your requirements.
CHAPTER 3
Installation
Flask depends on some external libraries, like Werkzeug and Jinja2. Werkzeug is a
toolkit for WSGI, the standard Python interface between web applications and a variety of servers for both development and deployment. Jinja2 renders templates.
So how do you get all that on your computer quickly? There are many ways you could
do that, but the most kick-ass method is virtualenv, so lets have a look at that first.
You will need Python 2.6 or newer to get started, so be sure to have an up-to-date
Python 2.x installation. For using Flask with Python 3 have a look at Python 3 Support.
3.1 virtualenv
Virtualenv is probably what you want to use during development, and if you have
shell access to your production machines, youll probably want to use it there, too.
What problem does virtualenv solve? If you like Python as much as I do, chances are
you want to use it for other projects besides Flask-based web applications. But the
more projects you have, the more likely it is that you will be working with different
versions of Python itself, or at least different versions of Python libraries. Lets face it:
quite often libraries break backwards compatibility, and its unlikely that any serious
application will have zero dependencies. So what do you do if two or more of your
projects have conflicting dependencies?
Virtualenv to the rescue! Virtualenv enables multiple side-by-side installations of
Python, one for each project. It doesnt actually install separate copies of Python, but
it does provide a clever way to keep different project environments isolated. Lets see
how virtualenv works.
If you are on Mac OS X or Linux, chances are that one of the following two commands
will work for you:
$ sudo easy_install virtualenv
or even better:
7
One of these will probably install virtualenv on your system. Maybe its even in your
package manager. If you use Ubuntu, try:
$ sudo apt-get install python-virtualenv
If you are on Windows and dont have the easy_install command, you must install it
first. Check the pip and setuptools on Windows section for more information about how
to do that. Once you have it installed, run the same commands as above, but without
the sudo prefix.
Once you have virtualenv installed, just fire up a shell and create your own environment. I usually create a project folder and a venv folder within:
$ mkdir myproject
$ cd myproject
$ virtualenv venv
New python executable in venv/bin/python
Installing setuptools, pip............done.
Now, whenever you want to work on a project, you only have to activate the corresponding environment. On OS X and Linux, do the following:
$ . venv/bin/activate
Either way, you should now be using your virtualenv (notice how the prompt of your
shell has changed to show the active environment).
And if you want to go back to the real world, use the following command:
$ deactivate
After doing this, the prompt of your shell should be as familiar as before.
Now, lets move on. Enter the following command to get Flask activated in your virtualenv:
$ pip install Flask
(On Windows systems, run it in a command-prompt window with administrator privileges, and leave out sudo.)
This will pull in the dependencies and activate the git head as the current version
inside the virtualenv. Then all you have to do is run git pull origin to update to the
latest version.
Most often, once you pull up a command prompt you want to be able to type pip
and python which will run those things, but this might not automatically happen on
Windows, because it doesnt know where those executables are (give either a try!).
To fix this, you should be able to navigate to your Python install directory (e.g
C:Python27), then go to Tools, then Scripts; then find the win_add2path.py file and
run that. Open a new Command Prompt and check that you can now just type python
to bring up the interpreter.
Finally, to install virtualenv, you can simply run:
> pip install virtualenv
Then you can be off on your way following the installation instructions above.
10
CHAPTER 4
Quickstart
Eager to get started? This page gives a good introduction to Flask. It assumes you
already have Flask installed. If you do not, head over to the Installation section.
itself.
To run the application you can either use the flask command or pythons -m switch
with Flask:
$ flask -a hello run
* Running on http://127.0.0.1:5000/
or alternatively:
$ python -m flask -a hello run
* Running on http://127.0.0.1:5000/
This launches a very simple builtin server, which is good enough for testing but probably not what you want to use in production. For deployment options see Deployment
Options.
Now head over to http://127.0.0.1:5000/, and you should see your hello world greeting.
Externally Visible Server
If you run the server you will notice that the server is only accessible from your own
computer, not from any other in the network. This is the default because in debugging
mode a user of the application can execute arbitrary Python code on your computer.
If you have the debugger disabled or trust the users on your network, you can make
the server publicly available simply by adding --host=0.0.0.0 to the command line:
flask -a hello run --host=0.0.0.0
12
13
4.4 Routing
Modern web applications have beautiful URLs. This helps people remember the
URLs, which is especially handy for applications that are used from mobile devices
with slower network connections. If the user can directly go to the desired page without having to hit the index page it is more likely they will like the page and come back
next time.
As you have seen above, the route() decorator is used to bind a function to a URL.
Here are some basic examples:
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello')
def hello():
return 'Hello, World'
14
But there is more to it! You can make certain parts of the URL dynamic and attach
multiple rules to a function.
Though they look rather similar, they differ in their use of the trailing slash in the URL
definition. In the first case, the canonical URL for the projects endpoint has a trailing
slash. In that sense, it is similar to a folder on a filesystem. Accessing it without a
trailing slash will cause Flask to redirect to the canonical URL with the trailing slash.
In the second case, however, the URL is defined without a trailing slash, rather like the
pathname of a file on UNIX-like systems. Accessing the URL with a trailing slash will
produce a 404 Not Found error.
15
This behavior allows relative URLs to continue working even if the trailing slash is
omitted, consistent with how Apache and other servers work. Also, the URLs will
stay unique, which helps search engines avoid indexing the same page twice.
(This also uses the test_request_context() method, explained below. It tells Flask
to behave as though it is handling a request, even though we are interacting with it
through a Python shell. Have a look at the explanation below. Context Locals).
Why would you want to build URLs using the URL reversing function url_for() instead of hard-coding them into your templates? There are three good reasons for this:
1. Reversing is often more descriptive than hard-coding the URLs. More importantly, it allows you to change URLs in one go, without having to remember to
change URLs all over the place.
2. URL building will handle escaping of special characters and Unicode data transparently for you, so you dont have to deal with them.
3. If your application is placed outside the URL root (say, in /myapplication instead
of /), url_for() will handle that properly for you.
16
If GET is present, HEAD will be added automatically for you. You dont have to deal
with that. It will also make sure that HEAD requests are handled as the HTTP RFC (the
document describing the HTTP protocol) demands, so you can completely ignore that
part of the HTTP specification. Likewise, as of Flask 0.6, OPTIONS is implemented for
you automatically as well.
You have no idea what an HTTP method is? Worry not, here is a quick introduction to
HTTP methods and why they matter:
The HTTP method (also often called the verb) tells the server what the clients wants
to do with the requested page. The following methods are very common:
GET The browser tells the server to just get the information stored on that page and
send it. This is probably the most common method.
HEAD The browser tells the server to get the information, but it is only interested in the
headers, not the content of the page. An application is supposed to handle that as
if a GET request was received but to not deliver the actual content. In Flask you
dont have to deal with that at all, the underlying Werkzeug library handles that
for you.
POST The browser tells the server that it wants to post some new information to that
URL and that the server must ensure the data is stored and only stored once.
This is how HTML forms usually transmit data to the server.
PUT Similar to POST but the server might trigger the store procedure multiple times by
overwriting the old values more than once. Now you might be asking why this
is useful, but there are some good reasons to do it this way. Consider that the
connection is lost during transmission: in this situation a system between the
browser and the server might receive the request safely a second time without
breaking things. With POST that would not be possible because it must only be
triggered once.
DELETE Remove the information at the given location.
OPTIONS Provides a quick way for a client to figure out which methods are supported
by this URL. Starting with Flask 0.6, this is implemented for you automatically.
17
Now the interesting part is that in HTML4 and XHTML1, the only methods a form can
submit to the server are GET and POST. But with JavaScript and future HTML standards
you can use the other methods as well. Furthermore HTTP has become quite popular
lately and browsers are no longer the only clients that are using HTTP. For instance,
many revision control systems use it.
Flask will look for templates in the templates folder. So if your application is a module,
this folder is next to that module, if its a package its actually inside your package:
Case 1: a module:
/application.py
/templates
/hello.html
Case 2: a package:
18
/application
/__init__.py
/templates
/hello.html
For templates you can use the full power of Jinja2 templates. Head over to the official
Jinja2 Template Documentation for more information.
Here is an example template:
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
Inside templates you also have access to the request, session and g 1 objects as well
as the get_flashed_messages() function.
Templates are especially useful if inheritance is used. If you want to know how that
works, head over to the Template Inheritance pattern documentation. Basically template inheritance makes it possible to keep certain elements on each page (like header,
navigation and footer).
Automatic escaping is enabled, so if name contains HTML it will be escaped automatically. If you can trust a variable and you know that it will be safe HTML (for example
because it came from a module that converts wiki markup to HTML) you can mark
it as safe by using the Markup class or by using the |safe filter in the template. Head
over to the Jinja 2 documentation for more examples.
Here is a basic introduction to how the Markup class works:
>>> from flask import Markup
>>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
Markup(u'<strong>Hello <blink>hacker</blink>!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup(u'<blink>hacker</blink>')
>>> Markup('<em>Marked up</em> » HTML').striptags()
u'Marked up \xbb HTML'
Changed in version 0.5: Autoescaping is no longer enabled for all templates. The
following extensions for templates trigger autoescaping: .html, .htm, .xml, .xhtml.
Templates loaded from a string will have autoescaping disabled.
1 Unsure what that g object is? Its something in which you can store information for your own needs,
check the documentation of that object (g) and the Using SQLite 3 with Flask for more information.
19
20
The current request method is available by using the method attribute. To access form
data (data transmitted in a POST or PUT request) you can use the form attribute. Here is
a full example of the two attributes mentioned above:
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
What happens if the key does not exist in the form attribute? In that case a special
KeyError is raised. You can catch it like a standard KeyError but if you dont do that, a
HTTP 400 Bad Request error page is shown instead. So for many situations you dont
have to deal with that problem.
To access parameters submitted in the URL (?key=value) you can use the args attribute:
searchword = request.args.get('key', '')
We recommend accessing URL parameters with get or by catching the KeyError because users might change the URL and presenting them a 400 bad request page in that
case is not user friendly.
For a full list of methods and attributes of the request object, head over to the request
documentation.
object, but it also has a save() method that allows you to store that file on the filesystem of the server. Here is a simple example showing how that works:
from flask import request
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/uploaded_file.txt')
...
If you want to know how the file was named on the client before it was uploaded to
your application, you can access the filename attribute. However please keep in mind
that this value can be forged so never ever trust that value. If you want to use the filename of the client to store the file on the server, pass it through the secure_filename()
function that Werkzeug provides for you:
from flask import request
from werkzeug.utils import secure_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/' + secure_filename(f.filename))
...
4.7.4 Cookies
To access cookies you can use the cookies attribute. To set cookies you can use the
set_cookie method of response objects. The cookies attribute of request objects is a
dictionary with all the cookies the client transmits. If you want to use sessions, do not
use the cookies directly but instead use the Sessions in Flask that add some security on
top of cookies for you.
Reading cookies:
from flask import request
@app.route('/')
def index():
username = request.cookies.get('username')
# use cookies.get(key) instead of cookies[key] to not get a
# KeyError if the cookie is missing.
Storing cookies:
22
Note that cookies are set on response objects. Since you normally just return strings
from the view functions Flask will convert them into response objects for you. If you
explicitly want to do that you can use the make_response() function and then modify
it.
Sometimes you might want to set a cookie at a point where the response object does
not exist yet. This is possible by utilizing the Deferred Request Callbacks pattern.
For this also see About Responses.
This is a rather pointless example because a user will be redirected from the index to
a page they cannot access (401 means access denied) but it shows how that works.
By default a black and white error page is shown for each error code. If you want to
customize the error page, you can use the errorhandler() decorator:
from flask import render_template
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
Note the 404 after the render_template() call. This tells Flask that the status code of
that page should be 404 which means not found. By default 200 is assumed which
translates to: all went well.
See Error handlers for more details.
23
You just need to wrap the return expression with make_response() and get the response object to modify it, then return it:
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
4.10 Sessions
In addition to the request object there is also a second object called session which
allows you to store information specific to a user from one request to the next. This is
implemented on top of cookies for you and signs the cookies cryptographically. What
this means is that the user could look at the contents of your cookie but not modify it,
unless they know the secret key used for signing.
In order to use sessions you have to set a secret key. Here is how sessions work:
24
The escape() mentioned here does escaping for you if you are not using the template
engine (as in this example).
How to generate good secret keys
The problem with random is that its hard to judge what is truly random. And a secret
key should be as random as possible. Your operating system has ways to generate
pretty random stuff based on a cryptographic random generator which can be used to
get such a key:
>>> import os
>>> os.urandom(24)
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
Just take that thing and copy/paste it into your code and youre done.
A note on cookie-based sessions: Flask will take the values you put into the session
object and serialize them into a cookie. If you are finding some values do not persist across requests, cookies are indeed enabled, and you are not getting a clear error
message, check the size of the cookie in your page responses compared to the size
25
4.12 Logging
New in version 0.3.
Sometimes you might be in a situation where you deal with data that should be correct,
but actually is not. For example you may have some client-side code that sends an
HTTP request to the server but its obviously malformed. This might be caused by a
user tampering with the data, or the client code failing. Most of the time its okay to
reply with 400 Bad Request in that situation, but sometimes that wont do and the
code has to continue working.
You may still want to log that something fishy happened. This is where loggers come
in handy. As of Flask 0.3 a logger is preconfigured for you to use.
Here are some example log calls:
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
The attached logger is a standard logging Logger, so head over to the official logging
documentation for more information.
Read more on Application Errors.
26
27
28
CHAPTER 5
Tutorial
You want to develop an application with Python and Flask? Here you have the chance
to learn by example. In this tutorial, we will create a simple microblogging application.
It only supports one user that can create text-only entries and there are no feeds or
comments, but it still features everything you need to get started. We will use Flask
and SQLite as a database (which comes out of the box with Python) so there is nothing
else you need.
If you want the full source code in advance or for comparison, check out the example
source.
29
The flaskr folder is not a Python package, but just something where we drop our files.
Later on, we will put our database schema as well as main module into this folder. It
is done in the following way. The files inside the static folder are available to users
of the application via HTTP. This is the place where CSS and Javascript files go. Inside
the templates folder, Flask will look for Jinja2 templates. The templates you create
later on in the tutorial will go in this directory.
Continue with Step 1: Database Schema.
30
This schema consists of a single table called entries. Each row in this table has an id,
a title, and a text. The id is an automatically incrementing integer and a primary
key, the other two are strings that must not be null.
Continue with Step 2: Application Setup Code.
Next, we can create our actual application and initialize it with the config from the
same file in flaskr.py:
# create our little application :)
app = Flask(__name__)
app.config.from_object(__name__)
# Load default config and override config from an environment variable
app.config.update(dict(
DATABASE=os.path.join(app.root_path, 'flaskr.db'),
SECRET_KEY='development key',
USERNAME='admin',
31
PASSWORD='default'
))
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
The Config object works similarly to a dictionary so we can update it with new values.
Database Path
Operating systems know the concept of a current working directory for each process.
Unfortunately, you cannot depend on this in web applications because you might have
more than one application in the same process.
For this reason the app.root_path attribute can be used to get the path to the application. Together with the os.path module, files can then easily be found. In this example,
we place the database right next to it.
For a real-world application, its recommended to use Instance Folders instead.
Usually, it is a good idea to load a separate, environment-specific configuration file.
Flask allows you to import multiple configurations and it will use the setting defined
in the last import. This enables robust configuration setups. from_envvar() can help
achieve this.
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
Simply define the environment variable FLASKR_SETTINGS that points to a config file to
be loaded. The silent switch just tells Flask to not complain if no such environment
key is set.
In addition to that, you can use the from_object() method on the config object and
provide it with an import name of a module. Flask will then initialize the variable
from that module. Note that in all cases, only variable names that are uppercase are
considered.
The SECRET_KEY is needed to keep the client-side sessions secure. Choose that key
wisely and as hard to guess and complex as possible.
We will also add a method that allows for easy connections to the specified database.
This can be used to open a connection on request and also from the interactive Python
shell or a script. This will come in handy later. We create a simple database connection
through SQLite and then tell it to use the sqlite3.Row object to represent rows. This
allows us to treat the rows as if they were dictionaries instead of tuples.
def connect_db():
"""Connects to the specific database."""
rv = sqlite3.connect(app.config['DATABASE'])
rv.row_factory = sqlite3.Row
return rv
With that out of the way, you should be able to start up the application without problems. Do this with the following command:
32
The --debug flag enables or disables the interactive debugger. Never leave debug mode
activated in a production system, because it will allow users to execute code on the server!
You will see a message telling you that server has started along with the address at
which you can access it.
When you head over to the server in your browser, you will get a 404 error because
we dont have any views yet. We will focus on that a little later, but first, we should
get the database working.
Externally Visible Server
Want your server to be publicly available? Check out the externally visible server section
for more information.
Continue with Step 3: Database Connections.
33
So now we know how to connect, but how do we properly disconnect? For that, Flask
provides us with the teardown_appcontext() decorator. Its executed every time the
application context tears down:
@app.teardown_appcontext
def close_db(error):
"""Closes the database again at the end of the request."""
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()
Functions marked with teardown_appcontext() are called every time the app context
tears down. What does this mean? Essentially, the app context is created before the
request comes in and is destroyed (torn down) whenever the request finishes. A teardown can happen because of two reasons: either everything went well (the error parameter will be None) or an exception happened, in which case the error is passed to
the teardown function.
Curious about what these contexts mean? Have a look at the The Application Context
documentation to learn more.
Continue to Step 4: Creating The Database.
Hint: Where do I put this code?
If youve been following along in this tutorial, you might be wondering where to put
the code from this step and the next. A logical place is to group these module-level
functions together, and put your new get_db and close_db functions below your existing connect_db function (following the tutorial line-by-line).
If you need a moment to find your bearings, take a look at how the example source
is organized. In Flask, you can put all of your application code into a single Python
module. You dont have to, and if your app grows larger, its a good idea not to.
The downside of this is that it requires the sqlite3 command to be installed, which is
not necessarily the case on every system. This also requires that we provide the path
to the database, which can introduce errors. Its a good idea to add a function that
initializes the database for you to the application.
34
To do this, we can create a function and hook it into the flask command that initializes the database. Let me show you the code first. Just add this function below the
connect_db function in flaskr.py:
def init_db():
db = get_db()
with app.open_resource('schema.sql', mode='r') as f:
db.cursor().executescript(f.read())
db.commit()
@app.cli.command('initdb')
def initdb_command():
"""Initializes the database."""
init_db()
print 'Initialized the database.'
The app.cli.command() decorator registers a new command with the flask script.
When the command executes, Flask will automatically create a application context
for us bound to the right application. Within the function, we can then access flask.g
and other things as we would expect. When the script ends, the application context
tears down and the database connection is released.
We want to keep an actual functions around that initializes the database, though, so
that we can easily create databases in unit tests later on. (For more information see
Testing Flask Applications.)
The open_resource() method of the application object is a convenient helper function
that will open a resource that the application provides. This function opens a file from
the resource location (your flaskr folder) and allows you to read from it. We are using
this here to execute a script on the database connection.
The connection object provided by SQLite can give us a cursor object. On that cursor, there is a method to execute a complete script. Finally, we only have to commit
the changes. SQLite3 and other transactional databases will not commit unless you
explicitly tell it to.
Now, it is possible to create a database with the flask script:
flask --app=flaskr initdb
Initialized the database.
Troubleshooting
If you get an exception later on stating that a table cannot be found, check that you
did execute the initdb command and that your table names are correct (singular vs.
plural, for example).
Continue with Step 5: The View Functions
35
Note that we check that the user is logged in here (the logged_in key is present in the
session and True).
Security Note
Be sure to use question marks when building SQL statements, as done in the example
above. Otherwise, your app will be vulnerable to SQL injection when you use string
formatting to build SQL statements. See Using SQLite 3 with Flask for more.
36
The logout function, on the other hand, removes that key from the session again. We
use a neat trick here: if you use the pop() method of the dict and pass a second parameter to it (the default), the method will delete the key from the dictionary if present or
do nothing when that key is not in there. This is helpful because now we dont have
to check if the user was logged in.
@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
37
We are also using template inheritance which makes it possible to reuse the layout of
the website in all pages.
Put the following templates into the templates folder:
5.8.1 layout.html
This template contains the HTML skeleton, the header and a link to log in (or log out
if the user was already logged in). It also displays the flashed messages if there are
any. The {% block body %} block can be replaced by a block of the same name (body)
in a child template.
The session dict is available in the template as well and you can use that to check
if the user is logged in or not. Note that in Jinja you can access missing attributes
and items of objects / dicts which makes the following code work, even if there is no
logged_in key in the session:
<!doctype html>
<title>Flaskr</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
<h1>Flaskr</h1>
<div class=metanav>
{% if not session.logged_in %}
<a href="{{ url_for('login') }}">log in</a>
{% else %}
<a href="{{ url_for('logout') }}">log out</a>
{% endif %}
</div>
{% for message in get_flashed_messages() %}
<div class=flash>{{ message }}</div>
{% endfor %}
{% block body %}{% endblock %}
</div>
5.8.2 show_entries.html
This template extends the layout.html template from above to display the messages. Note that the for loop iterates over the messages we passed in with the
render_template() function. We also tell the form to submit to your add_entry function
and use POST as HTTP method:
{% extends "layout.html" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method=post class=add-entry>
<dl>
<dt>Title:
<dd><input type=text size=30 name=title>
38
<dt>Text:
<dd><textarea name=text rows=5 cols=40></textarea>
<dd><input type=submit value=Share>
</dl>
</form>
{% endif %}
<ul class=entries>
{% for entry in entries %}
<li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
{% else %}
<li><em>Unbelievable. No entries here so far</em>
{% endfor %}
</ul>
{% endblock %}
5.8.3 login.html
This is the login template, which basically just displays a form to allow the user to
login:
{% extends "layout.html" %}
{% block body %}
<h2>Login</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method=post>
<dl>
<dt>Username:
<dd><input type=text name=username>
<dt>Password:
<dd><input type=password name=password>
<dd><input type=submit value=Login>
</dl>
</form>
{% endblock %}
{
{
{
{
{
39
.page
40
CHAPTER 6
Templates
Flask leverages Jinja2 as template engine. You are obviously free to use a different template engine, but you still have to install Jinja2 to run Flask itself. This requirement is
necessary to enable rich extensions. An extension can depend on Jinja2 being present.
This section only gives a very quick introduction into how Jinja2 is integrated into
Flask. If you want information on the template engines syntax itself, head over to the
official Jinja2 Template Documentation for more information.
request
The current request object (flask.request). This variable is unavailable if the
template was rendered without an active request context.
session
The current session object (flask.session). This variable is unavailable if the
template was rendered without an active request context.
g
The request-bound object for global variables (flask.g). This variable is unavailable if the template was rendered without an active request context.
url_for()
The flask.url_for() function.
get_flashed_messages()
The flask.get_flashed_messages() function.
The Jinja Context Behavior
These variables are added to the context of variables, they are not global variables.
The difference is that by default these will not show up in the context of imported
templates. This is partially caused by performance considerations, partially to keep
things explicit.
What does this mean for you? If you have a macro you want to import, that needs to
access the request object you have two possibilities:
1. you explicitly pass the request to the macro as parameter, or the attribute of the
request object you are interested in.
2. you import the macro with context.
Importing with context looks like this:
{% from '_helpers.html' import my_macro with context %}
42
Whenever you do this, please be very cautious about the variables you are using in
this block.
43
In case of the decorator the argument is optional if you want to use the function name
as name of the filter. Once registered, you can use the filter in your templates in the
same way as Jinja2s builtin filters, for example if you have a Python list in context
called mylist:
{% for x in mylist | reverse %}
{% endfor %}
The context processor above makes a variable called user available in the template
with the value of g.user. This example is not very interesting because g is available in
templates anyways, but it gives an idea how this works.
Variables are not limited to values; a context processor can also make functions available to templates (since Python allows passing around functions):
@app.context_processor
def utility_processor():
def format_price(amount, currency=u''):
return u'{0:.2f}{1}'.format(amount, currency)
return dict(format_price=format_price)
The context processor above makes the format_price function available to all templates:
{{ format_price(0.33) }}
You could also build format_price as a template filter (see Registering Filters), but this
demonstrates how to pass functions in a context processor.
44
CHAPTER 7
os
flaskr
unittest
tempfile
class FlaskrTestCase(unittest.TestCase):
def setUp(self):
45
The code in the setUp() method creates a new test client and initializes a new database.
This function is called before each individual test function is run. To delete the
database after the test, we close the file and remove it from the filesystem in the
tearDown() method. Additionally during setup the TESTING config flag is activated.
What it does is disable the error catching during request handling so that you get better error reports when performing test requests against the application.
This test client will give us a simple interface to the application. We can trigger test
requests to the application, and the client will also keep track of cookies for us.
Because SQLite3 is filesystem-based we can easily use the tempfile module to create a
temporary database and initialize it. The mkstemp() function does two things for us: it
returns a low-level file handle and a random file name, the latter we use as database
name. We just have to keep the db_fd around so that we can use the os.close() function to close the file.
If we now run the test suite, we should see the following output:
$ python flaskr_tests.py
---------------------------------------------------------------------Ran 0 tests in 0.000s
OK
Even though it did not run any actual tests, we already know that our flaskr application is syntactically valid, otherwise the import would have died with an exception.
46
Notice that our test functions begin with the word test; this allows unittest to automatically identify the method as a test to run.
By using self.app.get we can send an HTTP GET request to the application with the
given path. The return value will be a response_class object. We can now use the
data attribute to inspect the return value (as string) from the application. In this case,
we ensure that No entries here so far is part of the output.
Run it again and you should see one passing test:
$ python flaskr_tests.py
.
---------------------------------------------------------------------Ran 1 test in 0.034s
OK
Now we can easily test that logging in and out works and that it fails with invalid
credentials. Add this new test to the class:
47
def test_login_logout(self):
rv = self.login('admin', 'default')
assert 'You were logged in' in rv.data
rv = self.logout()
assert 'You were logged out' in rv.data
rv = self.login('adminx', 'default')
assert 'Invalid username' in rv.data
rv = self.login('admin', 'defaultx')
assert 'Invalid password' in rv.data
Here we check that HTML is allowed in the text but not in the title, which is the intended behavior.
Running that should now give us three passing tests:
$ python flaskr_tests.py
...
---------------------------------------------------------------------Ran 3 tests in 0.332s
OK
For more complex tests with headers and status codes, check out the MiniTwit Example from the sources which contains a larger test suite.
48
import flask
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
assert flask.request.path == '/'
assert flask.request.args['name'] == 'Peter'
All the other objects that are context bound can be used in the same way.
If you want to test your application with different configurations and there does not
seem to be a good way to do that, consider switching to application factories (see
Application Factories).
Note however that if you are using a test request context, the before_request()
functions are not automatically called same for after_request() functions. However teardown_request() functions are indeed executed when the test request context
leaves the with block. If you do want the before_request() functions to be called as
well, you need to call preprocess_request() yourself:
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
app.preprocess_request()
...
This in general is less useful because at that point you can directly start using the test
client.
49
def get_user():
user = getattr(g, 'user', None)
if user is None:
user = fetch_current_user_from_database()
g.user = user
return user
For a test it would be nice to override this user from the outside without
having to change some code.
This can be accomplished with hooking the
flask.appcontext_pushed signal:
from contextlib import contextmanager
from flask import appcontext_pushed, g
@contextmanager
def user_set(app, user):
def handler(sender, **kwargs):
g.user = user
with appcontext_pushed.connected_to(handler, app):
yield
50
If you were to use just the test_client() without the with block, the assert would
fail with an error because request is no longer available (because you are trying to use
it outside of the actual request).
This however does not make it possible to also modify the session or to access the session before a request was fired. Starting with Flask 0.8 we provide a so called session
transaction which simulates the appropriate calls to open a session in the context of
the test client and to modify it. At the end of the transaction the session is stored. This
works independently of the session backend used:
with app.test_client() as c:
with c.session_transaction() as sess:
sess['a_key'] = 'a value'
# once this is reached the session was stored
Note that in this case you have to use the sess object instead of the flask.session
proxy. The object however itself will provide the same interface.
51
52
CHAPTER 8
Application Errors
53
8.1.1 Registering
Register error handlers using errorhandler() or register_error_handler():
@app.errorhandler(werkzeug.exceptions.BadRequest)
def handle_bad_request(e):
return 'bad request!'
app.register_error_handler(400, lambda e: 'bad request!')
Those two ways are equivalent, but the first one is more clear and leaves
you with a function to call on your whim (and in tests).
Note that
werkzeug.exceptions.HTTPException subclasses like BadRequest from the example
and their HTTP codes are interchangable when handed to the registration methods
or decorator (BadRequest.code == 400).
You are however not limited to a HTTPException or its code but can register a handler
for every exception class you like.
Changed in version 1.0: Errorhandlers are now prioritized by specifity instead of the
order theyre registered in.
8.1.2 Handling
Once an exception instance is raised, its class hierarchy is traversed, and searched for
in the exception classes for which handlers are registered. The most specific handler is
selected.
E.g.
if a instance of ConnectionRefusedError is raised, and a handler is
registered for ConnectionError and ConnectionRefusedError, the more specific
ConnectionRefusedError handler is called on the exception instance, and its response
is shown to the user.
54
ADMINS = ['yourname@example.com']
if not app.debug:
import logging
from logging.handlers import SMTPHandler
mail_handler = SMTPHandler('127.0.0.1',
'server-error@example.com',
ADMINS, 'YourApplication Failed')
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
So what just happened? We created a new SMTPHandler that will send mails with
the mail server listening on 127.0.0.1 to all the ADMINS from the address servererror@example.com with the subject YourApplication Failed. If your mail server requires credentials, these can also be provided. For that check out the documentation
for the SMTPHandler.
We also tell the handler to only send errors and more critical messages. Because we
certainly dont want to get a mail for warnings or other useless logs that might happen
during request handling.
Before you run that in production, please also look at Controlling the Log Format to put
more information into that error mail. That will save you from a lot of frustration.
55
file_handler = TheHandlerYouWant(...)
file_handler.setLevel(logging.WARNING)
app.logger.addHandler(file_handler)
8.4.1 Email
from logging import Formatter
mail_handler.setFormatter(Formatter('''
Message type:
%(levelname)s
Location:
%(pathname)s:%(lineno)d
Module:
%(module)s
Function:
%(funcName)s
Time:
%(asctime)s
Message:
%(message)s
'''))
Format
%(levelname)s
%(pathname)s
%(filename)s
%(module)s
%(funcName)s
%(lineno)d
%(asctime)s
%(message)s
Description
Text logging level for the message (DEBUG, INFO, WARNING,
ERROR, CRITICAL).
Full pathname of the source file where the logging call was issued
(if available).
Filename portion of pathname.
Module (name portion of filename).
Name of function containing the logging call.
Source line number where the logging call was issued (if available).
Human-readable time when the LogRecord was created. By default this is of the form "2003-07-08 16:49:45,896" (the numbers after the comma are millisecond portion of the time). This
can be changed by subclassing the formatter and overriding the
formatTime() method.
The logged message, computed as msg % args
If you want to further customize the formatting, you can subclass the formatter. The
formatter has three interesting methods:
format(): handles the actual formatting. It is passed a LogRecord object and has to
return the formatted string.
formatTime(): called for asctime formatting. If you want a different time format you
can override this method.
formatException() called for exception formatting. It is passed an exc_info tuple and
has to return a string. The default is usually fine, you dont have to override it.
For more information, head over to the official documentation.
57
58
CHAPTER 9
For production applications, configure your application with logging and notifications
as described in Application Errors. This section provides pointers when debugging
deployment configuration and digging deeper with a full-featured Python debugger.
A possible useful pattern for configuration is to set the following in your config.yaml
(change the block as appropriate for your application, of course):
FLASK:
DEBUG: True
DEBUG_WITH_APTANA: True
Then in your applications entry-point (main.py), you could have something like:
if __name__ == "__main__":
# To allow aptana to receive errors, set use_debugger=False
app = create_app(config="config.yaml")
if app.debug: use_debugger = True
try:
# Disable Flask's debugger if external debugger is requested
use_debugger = not(app.config.get('DEBUG_WITH_APTANA'))
except:
pass
app.run(use_debugger=use_debugger, debug=app.debug,
use_reloader=use_debugger, host='0.0.0.0')
60
CHAPTER 10
Configuration Handling
Certain configuration values are also forwarded to the Flask object so you can read
and write them from there:
app.debug = True
To update multiple keys at once you can use the dict.update() method:
app.config.update(
DEBUG=True,
SECRET_KEY='...'
)
61
62
DEBUG
TESTING
PROPAGATE_EXCEPTIONS
PRESERVE_CONTEXT_ON_EXCEPTION
SECRET_KEY
SESSION_COOKIE_NAME
SESSION_COOKIE_DOMAIN
SESSION_COOKIE_PATH
SESSION_COOKIE_HTTPONLY
SESSION_COOKIE_SECURE
PERMANENT_SESSION_LIFETIME
SESSION_REFRESH_EACH_REQUEST
USE_X_SENDFILE
LOGGER_NAME
LOGGER_HANDLER_POLICY
SERVER_NAME
More on SERVER_NAME
The SERVER_NAME key is used for the subdomain support. Because Flask cannot guess
the subdomain part without the knowledge of the actual server name, this is required
if you want to work with subdomains. This is also used for the session cookie.
Please keep in mind that not only Flask has the problem of not knowing what subdomains are, your web browser does as well. Most modern web browsers will not
allow cross-subdomain cookies to be set on a server name without dots in it. So if
your server name is localhost you will not be able to set a cookie for localhost
and every subdomain of it. Please choose a different server name in that case, like
myapplication.local and add this name + the subdomains you want to use into
your host config or setup a local bind.
New in version 0.4: LOGGER_NAME
New in version 0.5: SERVER_NAME
New in version 0.6: MAX_CONTENT_LENGTH
New in version 0.7: PROPAGATE_EXCEPTIONS, PRESERVE_CONTEXT_ON_EXCEPTION
New in version 0.8:
TRAP_BAD_REQUEST_ERRORS,
APPLICATION_ROOT,
SESSION_COOKIE_DOMAIN,
SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SECURE
TRAP_HTTP_EXCEPTIONS,
SESSION_COOKIE_PATH,
$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
$ python run-app.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader...
The configuration files themselves are actual Python files. Only values in uppercase
are actually stored in the config object later on. So make sure to use uppercase letters
for your config keys.
Here is an example of a configuration file:
# Example configuration
DEBUG = False
SECRET_KEY = '?\xbf,\xb4\x8d\xa3"<\x9c\xb0@\x0f5\xab,w\xee\x8d$0\x13\x8b83'
Make sure to load the configuration very early on, so that extensions have the ability
to access the configuration when starting up. There are other methods on the config
object as well to load from individual files. For a complete reference, read the Config
objects documentation.
65
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
Then you just have to add a separate config.py file and export
YOURAPPLICATION_SETTINGS=/path/to/config.py and you are done.
However
there are alternative ways as well. For example you could use imports or subclassing.
What is very popular in the Django world is to make the import explicit in the config file by adding an from yourapplication.default_settings import * to the top
of the file and then overriding the changes by hand. You could also inspect an environment variable like YOURAPPLICATION_MODE and set that to production, development etc
and import different hardcoded files based on that.
An interesting pattern is also to use classes and inheritance for configuration:
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
There are many different ways and its up to you how you want to manage your configuration files. However here a list of good recommendations:
Keep a default configuration in version control. Either populate the config with
this default configuration or import it in your own configuration files before
overriding values.
Use an environment variable to switch between the configurations. This can be
done from outside the Python interpreter and makes development and deployment much easier because you can quickly and easily switch between different
configs without having to touch the code at all. If you are working often on different projects you can even create your own script for sourcing that activates a
virtualenv and exports the development configuration for you.
Use a tool like fabric in production to push code and configurations separately
to the production server(s). For some details about how to do that, head over to
the Deploying with Fabric pattern.
66
Please keep in mind that this path must be absolute when provided.
If the instance_path parameter is not provided the following default locations are used:
Uninstalled module:
/myapp.py
/instance
Uninstalled package:
/myapp
/__init__.py
/instance
$PREFIX is the prefix of your Python installation. This can be /usr or the path to
your virtualenv. You can print the value of sys.prefix to see what the prefix is
set to.
Since the config object provided loading of configuration files from relative filenames
we made it possible to change the loading via filenames to be relative to the instance
path if wanted. The behavior of relative paths in config files can be flipped between
relative to the application root (the default) to relative to instance folder via the
instance_relative_config switch to the application constructor:
app = Flask(__name__, instance_relative_config=True)
67
Here is a full example of how to configure Flask to preload the config from a module
and then override the config from a file in the config folder if it exists:
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('yourapplication.default_settings')
app.config.from_pyfile('application.cfg', silent=True)
The path to the instance folder can be found via the Flask.instance_path.
Flask also provides a shortcut to open a file from the instance folder with
Flask.open_instance_resource().
Example usage for both:
filename = os.path.join(app.instance_path, 'application.cfg')
with open(filename) as f:
config = f.read()
# or via open_instance_resource:
with app.open_instance_resource('application.cfg') as f:
config = f.read()
68
CHAPTER 11
Signals
69
listen for signals from all applications. This is especially true if you are developing an
extension.
For example, here is a helper context manager that can be used in a unittest to determine which templates were rendered and what variables were passed to the template:
from flask import template_rendered
from contextlib import contextmanager
@contextmanager
def captured_templates(app):
recorded = []
def record(sender, template, context, **extra):
recorded.append((template, context))
template_rendered.connect(record, app)
try:
yield recorded
finally:
template_rendered.disconnect(record, app)
Make sure to subscribe with an extra **extra argument so that your calls dont fail if
Flask introduces new arguments to the signals.
All the template rendering in the code issued by the application app in the body of
the with block will now be recorded in the templates variable. Whenever a template is
rendered, the template object as well as context are appended to it.
Additionally there is a convenient helper method (connected_to()) that allows you
to temporarily subscribe a function to a signal with a context manager on its own.
Because the return value of the context manager cannot be specified that way, you
have to pass the list in as an argument:
from flask import template_rendered
def captured_templates(app, recorded, **extra):
def record(sender, template, context):
recorded.append((template, context))
return template_rendered.connected_to(record, app)
70
...
template, context = templates[0]
The name for the signal here makes it unique and also simplifies debugging. You can
access the name of the signal with the name attribute.
For Extension Developers
If you are writing a Flask extension and you want to gracefully degrade for missing
blinker installations, you can do so by using the flask.signals.Namespace class.
Try to always pick a good sender. If you have a class that is emitting a signal, pass
self as sender. If you are emitting a signal from a random function, you can pass
current_app._get_current_object() as sender.
Passing Proxies as Senders
71
Never
pass
current_app
as
sender
to
a
signal.
Use
current_app._get_current_object() instead. The reason for this is that current_app
is a proxy and not the real application object.
72
CHAPTER 12
Pluggable Views
This is simple and flexible, but if you want to provide this view in a generic fashion
that can be adapted to other models and templates as well you might want more flexibility. This is where pluggable class-based views come into place. As the first step to
convert this into a class based view you would do this:
from flask.views import View
class ShowUsers(View):
def dispatch_request(self):
users = User.query.all()
return render_template('users.html', objects=users)
app.add_url_rule('/users/', view_func=ShowUsers.as_view('show_users'))
As you can see what you have to do is to create a subclass of flask.views.View and implement dispatch_request(). Then we have to convert that class into an actual view
function by using the as_view() class method. The string you pass to that function is
73
the name of the endpoint that view will then have. But this by itself is not helpful, so
lets refactor the code a bit:
from flask.views import View
class ListView(View):
def get_template_name(self):
raise NotImplementedError()
def render_template(self, context):
return render_template(self.get_template_name(), **context)
def dispatch_request(self):
context = {'objects': self.get_objects()}
return self.render_template(context)
class UserView(ListView):
def get_template_name(self):
return 'users.html'
def get_objects(self):
return User.query.all()
This of course is not that helpful for such a small example, but its good enough to
explain the basic principle. When you have a class-based view the question comes up
what self points to. The way this works is that whenever the request is dispatched a
new instance of the class is created and the dispatch_request() method is called with
the parameters from the URL rule. The class itself is instantiated with the parameters
passed to the as_view() function. For instance you can write a class like this:
class RenderTemplateView(View):
def __init__(self, template_name):
self.template_name = template_name
def dispatch_request(self):
return render_template(self.template_name)
That way you also dont have to provide the methods attribute. Its automatically set
based on the methods defined in the class.
75
return decorator
view = user_required(UserAPI.as_view('users'))
app.add_url_rule('/users/', view_func=view)
Starting with Flask 0.8 there is also an alternative way where you can specify a list of
decorators to apply in the class declaration:
class UserAPI(MethodView):
decorators = [user_required]
Due to the implicit self from the callers perspective you cannot use regular view decorators on the individual methods of the view however, keep this in mind.
Method
GET
POST
GET
PUT
DELETE
Description
Gives a list of all users
Creates a new user
Shows a single user
Updates a single user
Deletes a single user
So how would you go about doing that with the MethodView? The trick is to take
advantage of the fact that you can provide multiple rules to the same view.
Lets assume for the moment the view would look like this:
class UserAPI(MethodView):
def get(self, user_id):
if user_id is None:
# return a list of users
pass
else:
# expose a single user
pass
def post(self):
# create a new user
pass
def delete(self, user_id):
# delete a single user
pass
76
So how do we hook this up with the routing system? By adding two rules and explicitly mentioning the methods for each:
user_view = UserAPI.as_view('user_api')
app.add_url_rule('/users/', defaults={'user_id': None},
view_func=user_view, methods=['GET',])
app.add_url_rule('/users/', view_func=user_view, methods=['POST',])
app.add_url_rule('/users/<int:user_id>', view_func=user_view,
methods=['GET', 'PUT', 'DELETE'])
If you have a lot of APIs that look similar you can refactor that registration code:
def register_api(view, endpoint, url, pk='id', pk_type='int'):
view_func = view.as_view(endpoint)
app.add_url_rule(url, defaults={pk: None},
view_func=view_func, methods=['GET',])
app.add_url_rule(url, view_func=view_func, methods=['POST',])
app.add_url_rule('%s<%s:%s>' % (url, pk_type, pk), view_func=view_func,
methods=['GET', 'PUT', 'DELETE'])
register_api(UserAPI, 'user_api', '/users/', pk='user_id')
77
78
CHAPTER 13
79
one of the pillars of Flasks design is that you can have more than one application in
the same Python process.
So how does the code find the right application? In the past we recommended passing applications around explicitly, but that caused issues with libraries that were not
designed with that in mind.
A common workaround for that problem was to use the current_app proxy later on,
which was bound to the current requests application reference. Since creating such
a request context is an unnecessarily expensive operation in case there is no request
around, the application context was introduced.
The application context is also used by the url_for() function in case a SERVER_NAME
was configured. This allows you to generate URLs even in the absence of a request.
storing things on the application context unique names should be chosen as this is a
place that is shared between Flask applications and extensions.
The most common usage is to split resource management into two parts:
1. an implicit resource caching on the context.
2. a context teardown based resource deallocation.
Generally there would be a get_X() function that creates resource X if it does not exist yet and otherwise returns the same resource, and a teardown_X() function that is
registered as teardown handler.
This is an example that connects to a database:
import sqlite3
from flask import g
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = connect_to_database()
return db
@app.teardown_appcontext
def teardown_db(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
The first time get_db() is called the connection will be established. To make this implicit a LocalProxy can be used:
from werkzeug.local import LocalProxy
db = LocalProxy(get_db)
That way a user can directly access db which internally calls get_db().
81
82
CHAPTER 14
This document describes the behavior in Flask 0.7 which is mostly in line with the old
behavior but has some small, subtle differences.
It is recommended that you read the The Application Context chapter first.
As you can see, it accesses the request object. If you try to run this from a plain Python
shell, this is the exception you will see:
>>> redirect_url()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'request'
That makes a lot of sense because we currently do not have a request we could
access. So we have to make a request and bind it to the current context. The
test_request_context method can create us a RequestContext:
>>> ctx = app.test_request_context('/?next=http://example.com/')
This context can be used in two ways. Either with the with statement or by calling the
push() and pop() methods:
83
>>> ctx.push()
From that point onwards you can work with the request object:
>>> redirect_url()
u'http://example.com/'
Because the request context is internally maintained as a stack you can push and pop
multiple times. This is very handy to implement things like internal redirects.
For more information of how to utilize the request context from the interactive Python
shell, head over to the Working with the Shell chapter.
85
Keep in mind that teardown callbacks are always executed, even if before-request callbacks were not executed yet but an exception happened. Certain parts of the test system might also temporarily create a request context without calling the before-request
handlers. Make sure to write your teardown-request handlers in a way that they will
never fail.
case an exception occurred. In Flask 0.6 and earlier in debug mode, if an exception
occurred, the request context was not popped so that the interactive debugger can still
provide you with important information.
Starting with Flask 0.7 you have finer control over that behavior by setting the
PRESERVE_CONTEXT_ON_EXCEPTION configuration variable. By default its linked to the
setting of DEBUG. If the application is in debug mode the context is preserved, in production mode its not.
Do not force activate PRESERVE_CONTEXT_ON_EXCEPTION in production mode as it will
cause your application to leak memory on exceptions. However it can be useful during
development to get the same error preserving behavior as in development mode when
attempting to debug an error that only occurs under production settings.
87
88
CHAPTER 15
Blueprints instead provide separation at the Flask level, share application config, and
can change an application object as necessary with being registered. The downside is
that you cannot unregister a blueprint once an application was created without having
to destroy the whole application object.
When you bind a function with the help of the @simple_page.route decorator the
blueprint will record the intention of registering the function show on the application
when its later registered. Additionally it will prefix the endpoint of the function with
the name of the blueprint which was given to the Blueprint constructor (in this case
also simple_page).
90
If you check the rules registered on the application, you will find these:
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
<Rule '/' (HEAD, OPTIONS, GET) -> simple_page.show>]
The first one is obviously from the application itself for the static files. The other two
are for the show function of the simple_page blueprint. As you can see, they are also
prefixed with the name of the blueprint and separated by a dot (.).
Blueprints however can also be mounted at different locations:
app.register_blueprint(simple_page, url_prefix='/pages')
On top of that you can register blueprints multiple times though not every blueprint
might respond properly to that. In fact it depends on how the blueprint is implemented if it can be mounted more than once.
To quickly open sources from this folder you can use the open_resource() function:
with simple_page.open_resource('static/style.css') as f:
code = f.read()
91
By default the rightmost part of the path is where it is exposed on the web. Because
the folder is called static here it will be available at the location of the blueprint
+ /static. Say the blueprint is registered for /admin the static folder will be at
/admin/static.
The endpoint is named blueprint_name.static so you can generate URLs to it like you
would do to the static folder of the application:
url_for('admin.static', filename='style.css')
15.5.3 Templates
If you want the blueprint to expose templates you can do that by providing the template_folder parameter to the Blueprint constructor:
admin = Blueprint('admin', __name__, template_folder='templates')
As for static files, the path can be absolute or relative to the blueprint resource folder.
The template folder is added to the searchpath of templates but with a lower priority than the actual applications template folder. That way you can easily override
templates that a blueprint provides in the actual application.
So if you have a blueprint in the folder yourapplication/admin and you
want to render the template admin/index.html and you have provided
templates as a template_folder you will have to create a file like this:
yourapplication/admin/templates/admin/index.html.
To further reiterate this: if you have a blueprint named admin and you want to render
a template called index.html which is specific to this blueprint, the best idea is to lay
out your templates like this:
yourpackage/
blueprints/
admin/
templates/
admin/
index.html
__init__.py
And then when you want to render the template, use admin/index.html as the name
to look up the template by. If you encounter problems loading the correct templates
enable the EXPLAIN_TEMPLATE_LOADING config variable which will instruct Flask to print
out the steps it goes through to locate templates on every render_template call.
92
This will link to admin.index for instance in case the current request was dispatched
to any other admin blueprint endpoint.
93
94
CHAPTER 16
Flask Extensions
Flask extensions extend the functionality of Flask in various different ways. For instance they add support for databases and other common tasks.
import flaskext_compat
flaskext_compat.activate()
from flask.ext import foo
Once the flaskext_compat module is activated the flask.ext will exist and you can
start importing from there.
96
CHAPTER 17
Parameters:
97
File names:
flask --app=hello.py run
This will start up an interactive Python shell, setup the correct application context and setup the local variables in the shell. This is done by invoking the
Flask.make_shell_context() method of the application. By default you have access
to your app and g.
98
Once this has happened you can make the flask command automatically pick it up:
export YOURAPPLICATION_CONFIG=/path/to/config.cfg
export FLASK_APP=/path/to/autoapp.py
Thats a lot of code for not much, so lets go through all parts step by step.
1. First we import the click library as well as the click extensions from the
flask.cli package. Primarily we are here interested in the FlaskGroup click
group and the script_info_option() decorator.
2. The next thing we do is defining a function that is invoked with the script info
object (The Script Info) from Flask and its purpose is to fully import and create
100
the application. This can either directly import an application object or create it
(see Application Factories).
What is info.data? Its a dictionary of arbitrary data on the script info that can
be filled by options or through other means. We will come back to this later.
3. Next step is to create a FlaskGroup. In this case we just make an empty function
with a help doc string that just does nothing and then pass the create_wiki_app
function as a factory function.
Whenever click now needs to operate on a Flask application it will call that function with the script info and ask for it to be created.
4. In step 2 you could see that the config is passed to the actual creation function.
This config comes from the script_info_option() decorator for the main script.
It accepts a --config option and then stores it in the script info so we can use it
to create the application.
5. All is rounded up by invoking the script.
101
102
CHAPTER 18
Development Server
Starting with Flask 1.0 there are multiple built-in ways to run a development server.
The best one is the flask command line utility but you can also continue using the
Flask.run() method.
This will enable the debugger, the reloader and then start the server on
http://localhost:5000/.
The individual features of the server can be controlled by passing more arguments to
the run option. For instance the reloader can be disabled:
$ flask -a my_application --debug run --no-reload
18.2 In Code
The alternative way to start the application is through the Flask.run() method. This
will immediately launch a local server exactly the same way the flask script does.
Example:
if __name__ == '__main__':
app.run()
This works well for the common case but it does not work well for development which
is why from Flask 1.0 onwards the flask method is recommended. The reason for this
103
is that due to how the reload mechanism works there are some bizarre side-effects (like
executing certain code twice, sometimes crashing without message or dying when a
syntax or import error happens).
It is however still a perfectly valid method for invoking a non automatic reloading
application.
104
CHAPTER 19
Normally you would use the with statement to make this request object active, but in
the shell its easier to use the push() and pop() methods by hand:
>>> ctx.push()
From that point onwards you can work with the request object until you call pop:
>>> ctx.pop()
Keep in mind that the preprocess_request() function might return a response object,
in that case just ignore it.
To shutdown a request, you need to trick a bit before the after request functions (triggered by process_response()) operate on a response object:
>>> app.process_response(app.response_class())
<Response 0 bytes [200 OK]>
>>> ctx.pop()
106
107
108
CHAPTER 20
Certain things are common enough that the chances are high you will find them in
most web applications. For example quite a lot of applications are using relational
databases and user authentication. In that case, chances are they will open a database
connection at the beginning of the request and get the information of the currently
logged in user. At the end of the request, the database connection is closed again.
There are more user contributed snippets and patterns in the Flask Snippet Archives.
109
/yourapplication
/yourapplication
/__init__.py
/static
/style.css
/templates
layout.html
index.html
login.html
...
What did we gain from this? Now we can restructure the application a bit into multiple
modules. The only thing you have to remember is the following quick checklist:
1. the Flask application object creation has to be in the __init__.py file. That way
each module can import it safely and the __name__ variable will resolve to the
correct package.
2. all the view functions (the ones with a route() decorator on top) have to be
imported in the __init__.py file. Not the object itself, but the module it is in.
Import the view module after the application object is created.
Heres an example __init__.py:
from flask import Flask
app = Flask(__name__)
import yourapplication.views
110
/static
/style.css
/templates
layout.html
index.html
login.html
...
Circular Imports
Every Python programmer hates them, and yet we just added some: circular imports
(Thats when two modules depend on each other. In this case views.py depends on
__init__.py). Be advised that this is a bad idea in general but here it is actually fine.
The reason for this is that we are not actually using the views in __init__.py and just
ensuring the module is imported and we are doing that at the bottom of the file.
There are still some problems with that approach but if you want to use decorators
there is no way around that. Check out the Becoming Big section for some inspiration
how to deal with that.
111
The downside is that you cannot use the application object in the blueprints at import
time. You can however use it from within a request. How do you get access to the
application with the config? Use current_app:
from flask import current_app, Blueprint, render_template
admin = Blueprint('admin', __name__, url_prefix='/admin')
@admin.route('/')
def index():
return render_template(current_app.config['INDEX_TEMPLATE'])
112
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.model import db
db.init_app(app)
Using this design pattern, no application-specific state is stored on the extension object, so one extension object can be used for multiple apps. For more information about
the design of extensions refer to Flask Extension Development.
113
The fundamental difference from the module approach is that in this case you are running the same or different Flask applications that are entirely isolated from each other.
They run different configurations and are dispatched on the WSGI level.
Note that run_simple is not intended for use in production. Use a full-blown WSGI
server.
In order to use the interactive debugger, debugging must be enabled both on the application and the simple server, here is the hello world example with debugging and
run_simple:
from flask import Flask
from werkzeug.serving import run_simple
app = Flask(__name__)
app.debug = True
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
run_simple('localhost', 5000, app,
use_reloader=True, use_debugger=True, use_evalex=True)
114
application = DispatcherMiddleware(frontend, {
'/backend':
backend
})
116
The big difference between this and the subdomain one is that this one falls back to
another application if the creator function returns None:
from myapplication import create_app, default_app, get_user_for_prefix
def make_app(prefix):
user = get_user_for_prefix(prefix)
if user is not None:
return create_app(user)
application = PathDispatcher(default_app, make_app)
117
rv['message'] = self.message
return rv
A view can now raise that exception with an error message. Additionally some extra
payload can be provided as a dictionary through the payload parameter.
118
@app.route('/<lang_code>/')
def index(lang_code):
g.lang_code = lang_code
...
@app.route('/<lang_code>/about')
def about(lang_code):
g.lang_code = lang_code
...
This is an awful lot of repetition as you have to handle the language code setting on the
g object yourself in every single function. Sure, a decorator could be used to simplify
this, but if you want to generate URLs from one function to another you would have
to still provide the language code explicitly which can be annoying.
For the latter, this is where url_defaults() functions come in. They can automatically
inject values into a call for url_for() automatically. The code below checks if the
language code is not yet in the dictionary of URL values and if the endpoint wants a
value named lang_code:
@app.url_defaults
def add_language_code(endpoint, values):
if 'lang_code' in values or not g.lang_code:
return
if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
values['lang_code'] = g.lang_code
The method is_endpoint_expecting() of the URL map can be used to figure out if it
would make sense to provide a language code for the given endpoint.
The reverse of that function are url_value_preprocessor()s. They are executed right
after the request was matched and can execute code based on the URL values. The
idea is that they pull information out of the values dictionary and put it somewhere
else:
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
g.lang_code = values.pop('lang_code', None)
That way you no longer have to do the lang_code assignment to g in every function.
You can further improve that by writing your own decorator that prefixes URLs with
the language code, but the more beautiful solution is using a blueprint. Once the
lang_code is popped from the values dictionary and it will no longer be forwarded
to the view function reducing the code to this:
from flask import Flask, g
app = Flask(__name__)
@app.url_defaults
def add_language_code(endpoint, values):
if 'lang_code' in values or not g.lang_code:
119
return
if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
values['lang_code'] = g.lang_code
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
g.lang_code = values.pop('lang_code', None)
@app.route('/<lang_code>/')
def index():
...
@app.route('/<lang_code>/about')
def about():
...
120
121
Please keep in mind that you have to list subpackages explicitly. If you want distribute
to lookup the packages for you automatically, you can use the find_packages function:
from setuptools import setup, find_packages
setup(
...
packages=find_packages()
)
Dont forget that even if you enlist them in your MANIFEST.in file, they wont be installed for you unless you set the include_package_data parameter of the setup function
to True!
122
I mentioned earlier that dependencies are pulled from PyPI. What if you want to depend on a package that cannot be found on PyPI and wont be because it is an internal
package you dont want to share with anyone? Just still do as if there was a PyPI entry for it and provide a list of alternative locations where distribute should look for
tarballs:
dependency_links=['http://example.com/yourfiles']
Make sure that page has a directory listing and the links on the page are pointing to
the actual tarballs with their correct filenames as this is how distribute will find the
files. If you have an internal company server that contains the packages, provide the
URL to that server there.
If you are developing on the package and also want the requirements to be installed,
you can use the develop command instead:
$ python setup.py develop
This has the advantage of just installing a link to the site-packages folder instead of
copying the data over. You can then continue to work on the code without having to
run install again after each change.
123
124
The example above is well documented and should be straightforward. Here a recap
of the most common commands fabric provides:
run - executes a command on a remote server
local - executes a command on the local machine
put - uploads a file to the remote server
cd - changes the directory on the serverside. This has to be used in combination
with the with statement.
However this requires that our server already has the /var/www/yourapplication
folder created and /var/www/yourapplication/env to be a virtual environment. Furthermore are we not creating the configuration or .wsgi file on the server. So how do
we bootstrap a new server into our infrastructure?
This now depends on the number of servers we want to set up. If we just have one
application server (which the majority of applications will have), creating a command
in the fabfile for this is overkill. But obviously you can do that. In that case you
would probably call it setup or bootstrap and then pass the servername explicitly on the
command line:
$ fab -H newserver.example.com bootstrap
2. Upload a new application.wsgi file to the server and the configuration file for
the application (eg: application.cfg)
3. Create a new Apache config for yourapplication and activate it. Make sure to activate watching for changes of the .wsgi file so that we can automatically reload
the application by touching it. (See mod_wsgi (Apache) for more information)
125
So now the question is, where do the application.wsgi and application.cfg files
come from?
The application itself then has to initialize itself like this to look for the config at that
environment variable:
app = Flask(__name__)
app.config.from_object('yourapplication.default_config')
app.config.from_envvar('YOURAPPLICATION_CONFIG')
This approach is explained in detail in the Configuration Handling section of the documentation.
126
Fabric will now connect to all servers and run the commands as written down in the
fabfile. First it will execute pack so that we have our tarball ready and then it will
execute deploy and upload the source code to all servers and install it there. Thanks
to the setup.py file we will automatically pull in the required libraries into our virtual
environment.
127
if db is not None:
db.close()
Now, to use the database, the application must either have an active application context (which is always true if there is a request in flight) or create an application context
itself. At that point the get_db function can be used to get the current database connection. Whenever the context is destroyed the database connection will be terminated.
Note: if you use Flask 0.9 or older you need to use flask._app_ctx_stack.top instead
of g as the flask.g object was bound to the request and not application context.
Example:
@app.route('/')
def index():
cur = get_db().cursor()
...
Note: Please keep in mind that the teardown request and appcontext functions are always executed, even if a before-request handler failed or was never executed. Because
of this we have to make sure here that the database is there before we close it.
Or even simpler:
128
db.row_factory = sqlite3.Row
Additionally, it is a good idea to provide a query function that combines getting the
cursor, executing and fetching the results:
def query_db(query, args=(), one=False):
cur = get_db().execute(query, args)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
This handy little function, in combination with a row factory, makes working with the
database much more pleasant than it is by just using the raw cursor and connection
objects.
Here is how you can use it:
for user in query_db('select * from users'):
print user['username'], 'has the id', user['user_id']
To pass variable parts to the SQL statement, use a question mark in the statement and
pass in the arguments as a list. Never directly add them to the SQL statement with
string formatting because this makes it possible to attack the application using SQL
Injections.
You can then create such a database from the Python shell:
>>> from yourapplication import init_db
>>> init_db()
129
20.9.2 Declarative
The declarative extension in SQLAlchemy is the most recent method of using
SQLAlchemy. It allows you to define tables and models in one go, similar to how
Django works. In addition to the following text I recommend the official documentation on the declarative extension.
Heres the example database.py module for your application:
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
# import all modules here that might define models so that
# they will be registered properly on the metadata. Otherwise
# you will have to import them first before calling init_db()
import yourapplication.models
Base.metadata.create_all(bind=engine)
To define your models, just subclass the Base class that was created by the code above.
If you are wondering why we dont have to care about threads here (like we did in the
SQLite3 example above with the g object): thats because SQLAlchemy does that for
us already with the scoped_session.
130
To use SQLAlchemy in a declarative way with your application, you just have to put
the following code into your application module. Flask will automatically remove
database sessions at the end of the request or when the application shuts down:
from yourapplication.database import db_session
@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
classes separately and map them together. Its more flexible but a little more to type.
In general it works like the declarative approach, so make sure to also split up your
application into multiple modules in a package.
Here is an example database.py module for your application:
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData()
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
def init_db():
metadata.create_all(bind=engine)
As for the declarative approach you need to close the session after each request or
application context shutdown. Put this into your application module:
from yourapplication.database import db_session
@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
Querying and inserting works exactly the same as in the example above.
132
Then you can either declare the tables in your code like in the examples above, or
automatically load them:
from sqlalchemy import Table
users = Table('users', metadata, autoload=True)
To insert data you can use the insert method. We have to get a connection first so that
we can use a transaction:
>>> con = engine.connect()
>>> con.execute(users.insert(), name='admin', email='admin@localhost')
You can also pass strings of SQL statements to the execute() method:
>>> engine.execute('select * from users where id = :1', [1]).first()
(1, u'admin', u'admin@localhost')
3. use the save() method of the file to save the file permanently somewhere on the
filesystem.
134
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',
filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
So what does that secure_filename() function actually do? Now the problem is that
there is that principle called never trust user input. This is also true for the filename
of an uploaded file. All submitted form data can be forged, and filenames can be dangerous. For the moment just remember: always use that function to secure a filename
before storing it directly on the filesystem.
Information for the Pros
So youre interested in what that secure_filename() function does and what the problem is if youre not using it? So just imagine someone would send the following information as filename to your application:
filename = "../../../../home/username/.bashrc"
Assuming the number of ../ is correct and you would join this with the UPLOAD_FOLDER
the user might have the ability to modify a file on the servers filesystem he or she
should not modify. This does require some knowledge about how the application
looks like, but trust me, hackers are patient :)
Now lets look how that function works:
>>> secure_filename('../../../../home/username/.bashrc')
'home_username_.bashrc'
Now one last thing is missing: the serving of the uploaded files. In the upload_file()
we redirect the user to url_for(uploaded_file, filename=filename), that is,
/uploads/filename. So we write the uploaded_file() function to return the file of
that name. As of Flask 0.5 we can use a function that does that for us:
from flask import send_from_directory
@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename)
Alternatively you can register uploaded_file as build_only rule and use the
SharedDataMiddleware. This also works with older versions of Flask:
135
The code above will limited the maximum allowed payload to 16 megabytes. If a
larger file is transmitted, Flask will raise an RequestEntityTooLarge exception.
This feature was added in Flask 0.6 but can be achieved in older versions as well by
subclassing the request object. For more information on that consult the Werkzeug
documentation on file handling.
implements a full fledged upload mechanism with white and blacklisting of extensions and more.
20.11 Caching
When your application runs slow, throw some caches in. Well, at least its the easiest
way to speed up things. What does a cache do? Say you have a function that takes
some time to complete but the results would still be good enough if they were 5 minutes old. So then the idea is that you actually put the result of that calculation into a
cache for some time.
Flask itself does not provide caching for you, but Werkzeug, one of the libraries it is
based on, has some very basic cache support. It supports multiple cache backends,
normally you want to use a memcached server.
If you want to use memcached, make sure to have one of the memcache modules
supported (you get them from PyPI) and a memcached server running somewhere.
This is how you connect to such an memcached server then:
from werkzeug.contrib.cache import MemcachedCache
cache = MemcachedCache(['127.0.0.1:11211'])
If you are using App Engine, you can connect to the App Engine memcache server
easily:
from werkzeug.contrib.cache import GAEMemcachedCache
cache = GAEMemcachedCache()
137
rv = cache.get('my-item')
To add items to the cache, use the set() method instead. The first argument is the
key and the second the value that should be set. Also a timeout can be provided after
which the cache will automatically remove item.
Here a full example how this looks like normally:
def get_my_item():
rv = cache.get('my-item')
if rv is None:
rv = calculate_value()
cache.set('my-item', rv, timeout=5 * 60)
return rv
138
So how would you use that decorator now? Apply it as innermost decorator to a
view function. When applying further decorators, always remember that the route()
decorator is the outermost:
@app.route('/secret_page')
@login_required
def secret_page():
pass
139
Notice that this assumes an instantiated cache object is available, see Caching for more
information.
As you can see, if no template name is provided it will use the endpoint of the URL
map with dots converted to slashes + .html. Otherwise the provided template name
is used. When the decorated function returns, the dictionary returned is passed to the
template rendering function. If None is returned, an empty dictionary is assumed, if
something else than a dictionary is returned we return it from the function unchanged.
That way you can still use the redirect function or return simple strings.
Here is the code for that decorator:
from functools import wraps
from flask import request, render_template
def templated(template=None):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
template_name = template
if template_name is None:
template_name = request.endpoint \
.replace('.', '/') + '.html'
ctx = f(*args, **kwargs)
if ctx is None:
ctx = {}
elif not isinstance(ctx, dict):
return ctx
return render_template(template_name, **ctx)
140
return decorated_function
return decorator
141
Notice were implying that the view is using SQLAlchemy here (SQLAlchemy in Flask),
but thats not a requirement, of course. Adapt the code as necessary.
Things to remember:
1. create the form from the request form value if the data is submitted via the HTTP
POST method and args if the data is submitted as GET.
2. to validate the data, call the validate() method, which will return True if the
data validates, False otherwise.
3. to access individual values from the form, access form.<NAME>.data.
142
</ul>
{% endif %}
</dd>
{% endmacro %}
This macro accepts a couple of keyword arguments that are forwarded to WTForms
field function, which renders the field for us. The keyword arguments will be inserted
as HTML attributes. So, for example, you can call render_field(form.username,
class=username) to add a class to the input element. Note that WTForms returns
standard Python unicode strings, so we have to tell Jinja2 that this data is already
HTML-escaped with the |safe filter.
Here is the register.html template for the function we used above, which takes advantage of the _formhelpers.html template:
{% from "_formhelpers.html" import render_field %}
<form method=post action="/register">
<dl>
{{ render_field(form.username) }}
{{ render_field(form.email) }}
{{ render_field(form.password) }}
{{ render_field(form.confirm) }}
{{ render_field(form.accept_tos) }}
</dl>
<p><input type=submit value=Register>
</form>
For more information about WTForms, head over to the WTForms website.
143
In this example, the {% block %} tags define four blocks that child templates can fill
in. All the block tag does is tell the template engine that a child template may override
those portions of the template.
The {% extends %} tag is the key here. It tells the template engine that this template
extends another template. When the template system evaluates this template, first
it locates the parent. The extends tag must be the first tag in the template. To render
the contents of a block defined in the parent template, use {{ super() }}.
144
access it next request and only next request. This is usually combined with a layout
template that does this.
145
And here is the login.html template which also inherits from layout.html:
{% extends "layout.html" %}
{% block body %}
<h1>Login</h1>
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}
{% endif %}
<form action="" method=post>
<dl>
<dt>Username:
<dd><input type=text name=username value="{{
request.form.username }}">
<dt>Password:
<dd><input type=password name=password>
</dl>
<p><input type=submit value=Login>
</form>
{% endblock %}
Inside the template you then have to tell the get_flashed_messages() function to also
return the categories. The loop looks slightly different in that situation then:
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class=flashes>
{% for category, message in messages %}
<li class="{{ category }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
This is just one example of how to render these flashed messages. One might also use
the category to add a prefix such as <strong>Error:</strong> to the message.
146
147
In this case you have to put jQuery into your static folder as a fallback, but it will
first try to load it directly from Google. This has the advantage that your website will
probably load faster for users if they went to at least one other website before using
the same jQuery version from Google because it will already be in the browser cache.
The |safe is necessary in Flask before 0.10 so that Jinja does not escape the JSON
encoded string with HTML rules. Usually this would be necessary, but we are inside
a script block here where different rules apply.
Information for Pros
In HTML the script tag is declared CDATA which means that entities will not be parsed.
Everything until </script> is handled as script. This also means that there must
never be any </ between the script tags. |tojson is kind enough to do the right
thing here and escape slashes for you ({{ "</script>"|tojson|safe }} is rendered as
"<\/script>").
In Flask 0.10 it goes a step further and escapes all HTML tags with unicode escapes.
This makes it possible for Flask to automatically mark the result as HTML safe.
148
@app.route('/_add_numbers')
def add_numbers():
a = request.args.get('a', 0, type=int)
b = request.args.get('b', 0, type=int)
return jsonify(result=a + b)
@app.route('/')
def index():
return render_template('index.html')
As you can see I also added an index method here that renders a template. This template will load jQuery as above and have a little form we can add two numbers and a
link to trigger the function on the server side.
Note that we are using the get() method here which will never fail. If the key is
missing a default value (here 0) is returned. Furthermore it can convert values to a
specific type (like in our case int). This is especially handy for code that is triggered by
a script (APIs, JavaScript etc.) because you dont need special error reporting in that
case.
I wont go into detail here about how jQuery works, just a very quick explanation of
the little bit of code above:
149
1. $(function() { ... }) specifies code that should run once the browser is done
loading the basic parts of the page.
2. $(selector) selects an element and lets you operate on it.
3. element.bind(event, func) specifies a function that should run when the user
clicked on the element. If that function returns false, the default behavior will not
kick in (in this case, navigate to the # URL).
4. $.getJSON(url, data, func) sends a GET request to url and will send the contents of the data object as query parameters. Once the data arrived, it will call
the given function with the return value as argument. Note that we can use the
$SCRIPT_ROOT variable here that we set earlier.
If you dont get the whole picture, download the sourcecode for this example from
GitHub.
151
Then, with the centralized approach you would have one file with the views
(views.py) but without any decorator:
def index():
pass
def user(username):
pass
And then a file that sets up an application which maps the functions to URLs:
from flask import Flask
from yourapplication import views
app = Flask(__name__)
app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/user/<username>', view_func=views.user)
152
Whats important here is is that __module__ and __name__ are properly set. This is
used by Flask internally to figure out how to name the URL rules in case you dont
provide a name for the rule yourself.
Then you can define your central place to combine the views like this:
from flask import Flask
from yourapplication.helpers import LazyView
app = Flask(__name__)
app.add_url_rule('/',
view_func=LazyView('yourapplication.views.index'))
app.add_url_rule('/user/<username>',
view_func=LazyView('yourapplication.views.user'))
You can further optimize this in terms of amount of keystrokes needed to write this by
having a function that calls into add_url_rule() by prefixing a string with the project
name and a dot, and by wrapping view_func in a LazyView as needed:
def url(url_rule, import_name, **options):
view = LazyView('yourapplication.' + import_name)
app.add_url_rule(url_rule, view_func=view, **options)
url('/', 'views.index')
url('/user/<username>', 'views.user')
One thing to keep in mind is that before and after request handlers have to be in a file
that is imported upfront to work properly on the first request. The same goes for any
kind of remaining decorator.
20.19.1 Declarative
The default behavior of MongoKit is the declarative one that is based on common
ideas from Django or the SQLAlchemy declarative extension.
Here an example app.py module for your application:
153
To define your models, just subclass the Document class that is imported from MongoKit. If youve seen the SQLAlchemy pattern you may wonder why we do not have
a session and even do not define a init_db function here. On the one hand, MongoKit
does not have something like a session. This sometimes makes it more to type but
also makes it blazingly fast. On the other hand, MongoDB is schemaless. This means
you can modify the data structure from one insert query to the next without any problem. MongoKit is just schemaless too, but implements some validation to ensure data
integrity.
Here is an example document (put this also into app.py, e.g.):
from mongokit import ValidationError
def max_length(length):
def validate(value):
if len(value) <= length:
return True
# must have %s in error format string to have mongokit place key in there
raise ValidationError('%s must be at most {} characters long'.format(length))
return validate
class User(Document):
structure = {
'name': unicode,
'email': unicode,
}
validators = {
'name': max_length(50),
'email': max_length(120)
}
use_dot_notation = True
def __repr__(self):
return '<User %r>' % (self.name)
# register the User document with our current connection
connection.register([User])
154
This example shows you how to define your schema (named structure), a validator for the maximum character length and uses a special MongoKit feature called
use_dot_notation. Per default MongoKit behaves like a python dictionary but with
use_dot_notation set to True you can use your documents like you use models in nearly
any other ORM by using dots to separate between attributes.
You can insert entries into the database like this:
>>>
>>>
>>>
>>>
>>>
>>>
>>>
Note that MongoKit is kinda strict with used column types, you must not use a common str type for either name or email but unicode.
Querying is simple as well:
>>> list(collection.User.find())
[<User u'admin'>]
>>> collection.User.find_one({'name': u'admin'})
<User u'admin'>
To insert data you can use the insert method. We have to get a collection first, this is
somewhat the same as a table in the SQL world.
>>> collection = connection['test'].users
>>> user = {'name': u'admin', 'email': u'admin@localhost'}
>>> collection.insert(user)
>>> list(collection.find())
[{u'_id': ObjectId('4c271729e13823182f000000'), u'name': u'admin', u'email': u'admin@localhost'}
>>> collection.find_one({'name': u'admin'})
{u'_id': ObjectId('4c271729e13823182f000000'), u'name': u'admin', u'email': u'admin@localhost'}
155
Thats all you need for most browsers, however some really old ones do not support
this standard. The old de-facto standard is to serve this file, with this name, at the
website root. If your application is not mounted at the root path of the domain you
either need to configure the web server to serve the icon at the root or if you cant do
that youre out of luck. If however your application is the root you can simply route a
redirect:
app.add_url_rule('/favicon.ico',
redirect_to=url_for('static', filename='favicon.ico'))
If you want to save the extra redirect request you can also write a view using
send_from_directory():
import os
from flask import send_from_directory
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),
'favicon.ico', mimetype='image/vnd.microsoft.icon')
We can leave out the explicit mimetype and it will be guessed, but we may as well
specify it to avoid the extra guessing, as it will always be the same.
The above will serve the icon via your application and if possible its better to configure your dedicated web server to serve it; refer to the web servers documentation.
156
Each yield expression is directly sent to the browser. Note though that some WSGI
middlewares might break streaming, so be careful there in debug environments with
profilers and other things you might have enabled.
157
def render_large_template():
rows = iter_all_rows()
return Response(stream_template('the_template.html', rows=rows))
The trick here is to get the template object from the Jinja2 environment on the application and to call stream() instead of render() which returns a stream object instead
of a string. Since were bypassing the Flask template render functions and using the
template object itself we have to make sure to update the render context ourselves by
calling update_template_context(). The template is then evaluated as the stream is
iterated over. Since each time you do a yield the server will flush the content to the
client you might want to buffer up a few items in the template which you can do with
rv.enable_buffering(size). 5 is a sane default.
158
that code there is just not a very pleasant experience or makes code look very awkward.
As an alternative possibility you can attach a bunch of callback functions to the g object
and call them at the end of the request. This way you can defer code execution from
anywhere in the application.
159
160
you want to calculate the checksum of the incoming request data. This is necessary
sometimes for some APIs.
Fortunately this is however very simple to change by wrapping the input stream.
The following example calculates the SHA1 checksum of the incoming data as it gets
read and stores it in the WSGI environment:
import hashlib
class ChecksumCalcStream(object):
def __init__(self, stream):
self._stream = stream
self._hash = hashlib.sha1()
def read(self, bytes):
rv = self._stream.read(bytes)
self._hash.update(rv)
return rv
def readline(self, size_hint):
rv = self._stream.readline(size_hint)
self._hash.update(rv)
return rv
def generate_checksum(request):
env = request.environ
stream = ChecksumCalcStream(env['wsgi.input'])
env['wsgi.input'] = stream
return stream._hash
To use this, all you need to do is to hook the calculating stream in before the request
starts consuming data. (Eg: be careful accessing request.form or anything of that
nature. before_request_handlers for instance should be careful not to access it).
Example usage:
@app.route('/special-api', methods=['POST'])
def special_api():
hash = generate_checksum(request)
# Accessing this parses the input stream
files = request.files
# At this point the hash is fully constructed.
checksum = hash.hexdigest()
return 'Hash was: %s' % checksum
with Version 3. This guide fills in the blanks in how to properly use Celery with Flask
but assumes that you generally already read the First Steps with Celery guide in the
official Celery documentation.
The function creates a new Celery object, configures it with the broker from the application config, updates the rest of the Celery config from the Flask config and then
creates a subclass of the task that wraps the task execution in an application context.
162
The your_application string has to point to your applications package or module that
creates the celery object.
163
164
CHAPTER 21
Deployment Options
While lightweight and easy to use, Flasks built-in server is not suitable for production as it doesnt scale well and by default serves only one request at a time. Some of
the options available for properly running Flask in production are documented here.
If you want to deploy your Flask application to a WSGI server not listed here, look up
the server documentation about how to use a WSGI app with it. Just remember that
your Flask application object is the actual WSGI application.
165
Please make sure in advance that any app.run() calls you might have in your application file are inside an if __name__ == __main__: block or moved to a separate file.
Just make sure its not called because this will always start a local WSGI server which
we do not want if we deploy that application to mod_wsgi.
Installing mod_wsgi
If you dont have mod_wsgi installed yet you have to either install it using a package
manager or compile it yourself. The mod_wsgi installation instructions cover source
installations on UNIX systems.
If you are using Ubuntu/Debian you can apt-get it and activate it as follows:
# apt-get install libapache2-mod-wsgi
If you are using a yum based distribution (Fedora, OpenSUSE, etc..) you can install it
as follows:
# yum install mod_wsgi
If you are using pkgsrc you can install mod_wsgi by compiling the www/ap2-wsgi package.
If you encounter segfaulting child processes after the first apache reload you can safely
ignore them. Just restart the server.
Creating a .wsgi file
To run your application you need a yourapplication.wsgi file. This file contains the
code mod_wsgi is executing on startup to get the application object. The object called
application in that file is then used as application.
For most applications the following file should be sufficient:
from yourapplication import app as application
If you dont have a factory function for application creation but a singleton instance
you can directly import that one as application.
Store that file somewhere that you will find it again (e.g.: /var/www/yourapplication)
and make sure that yourapplication and all the libraries that are in use are on the python
load path. If you dont want to install it system wide consider using a virtual python
instance. Keep in mind that you will have to actually install your application into the
virtualenv as well. Alternatively there is the option to just patch the path in the .wsgi
file before the import:
166
import sys
sys.path.insert(0, '/path/to/the/application')
Configuring Apache
The last thing you have to do is to create an Apache configuration file for your application. In this example we are telling mod_wsgi to execute the application under a
different user for security reasons:
<VirtualHost *>
ServerName example.com
WSGIDaemonProcess yourapplication user=user1 group=group1 threads=5
WSGIScriptAlias / /var/www/yourapplication/yourapplication.wsgi
<Directory /var/www/yourapplication>
WSGIProcessGroup yourapplication
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Note: There have been some changes in access control configuration for Apache 2.4.
Most notably, the syntax for directory permissions has changed from httpd 2.2
Order allow,deny
Allow from all
Problem: application does not run, errorlog shows SystemExit ignored You have a
app.run() call in your application file that is not guarded by an if __name__
== __main__: condition. Either remove that run() call from the file and move
it into a separate run.py file or put it into such an if block.
Problem: application gives permission errors Probably caused by your application
running as the wrong user. Make sure the folders the application needs access to
have the proper privileges set and the application runs as the correct user (user
and group parameter to the WSGIDaemonProcess directive)
Problem: application dies with an error on print Keep in mind that mod_wsgi disallows doing anything with sys.stdout and sys.stderr. You can disable this
protection from the config by setting the WSGIRestrictStdout to off:
WSGIRestrictStdout Off
Alternatively you can also replace the standard out in the .wsgi file with a different stream:
import sys
sys.stdout = sys.stderr
168
For Python 3 add the following lines to the top of your .wsgi file:
activate_this = '/path/to/env/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
This sets up the load paths according to the settings of the virtual environment. Keep
in mind that the path has to be absolute.
Gunicorn provides many command-line options see gunicorn -h. For example, to
run a Flask application with 4 worker processes (-w 4) binding to localhost port 4000
(-b 127.0.0.1:4000):
gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
Gevent
Gevent is a coroutine-based Python networking library that uses greenlet to provide a
high-level synchronous API on top of libev event loop:
from gevent.wsgi import WSGIServer
from yourapplication import app
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
Twisted Web
Twisted Web is the web server shipped with Twisted, a mature, non-blocking eventdriven networking library. Twisted Web comes with a standard WSGI container which
can be controlled from the command line using the twistd utility:
169
This example will run a Flask application called app from a module named myproject.
Twisted Web supports many flags and options, and the twistd utility does as well; see
twistd -h and twistd web -h for more information. For example, to run a Twisted
Web server in the foreground, on port 8080, with an application from myproject:
twistd -n web --port 8080 --wsgi myproject.app
Proxy Setups
If you deploy your application using one of these servers behind an HTTP proxy you
will need to rewrite a few headers in order for the application to work. The two problematic values in the WSGI environment usually are REMOTE_ADDR and HTTP_HOST. You
can configure your httpd to pass these headers, or you can fix them in middleware.
Werkzeug ships a fixer that will solve some common setups, but you might want to
write your own WSGI middleware for specific setups.
Heres a simple nginx configuration which proxies to an application served on localhost at port 8000, setting appropriate headers:
server {
listen 80;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass
proxy_redirect
proxy_set_header
proxy_set_header
proxy_set_header
http://127.0.0.1:8000/;
off;
Host
X-Real-IP
X-Forwarded-For
$host;
$remote_addr;
$proxy_add_x_forwarded_for;
}
}
If your httpd is not providing these headers, the most common setup invokes the host
being set from X-Forwarded-Host and the remote address from X-Forwarded-For:
from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)
Trusting Headers
Please keep in mind that it is a security issue to use such a middleware in a non-proxy
setup because it will blindly trust the incoming headers which might be forged by
malicious clients.
170
If you want to rewrite the headers from another header, you might want to use a fixer
like this:
class CustomProxyFix(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
host = environ.get('HTTP_X_FHOST', '')
if host:
environ['HTTP_HOST'] = host
return self.app(environ, start_response)
app.wsgi_app = CustomProxyFix(app.wsgi_app)
21.2.3 uWSGI
uWSGI is a deployment option on servers like nginx, lighttpd, and cherokee; see
FastCGI and Standalone WSGI Containers for other options. To use your WSGI application with uWSGI protocol you will need a uWSGI server first. uWSGI is both a
protocol and an application server; the application server can serve uWSGI, FastCGI,
and HTTP protocols.
The most popular uWSGI server is uwsgi, which we will use for this guide. Make sure
to have it installed to follow along.
Watch Out
Please make sure in advance that any app.run() calls you might have in your application file are inside an if __name__ == __main__: block or moved to a separate file.
Just make sure its not called because this will always start a local WSGI server which
we do not want if we deploy that application to uWSGI.
The --manage-script-name will move the handling of SCRIPT_NAME to uwsgi, since its
smarter about that. It is used together with the --mount directive which will make
171
21.2.4 FastCGI
FastCGI is a deployment option on servers like nginx, lighttpd, and cherokee; see
uWSGI and Standalone WSGI Containers for other options. To use your WSGI application with any of them you will need a FastCGI server first. The most popular one is
flup which we will use for this guide. Make sure to have it installed to follow along.
Watch Out
Please make sure in advance that any app.run() calls you might have in your application file are inside an if __name__ == __main__: block or moved to a separate file.
Just make sure its not called because this will always start a local WSGI server which
we do not want if we deploy that application to FastCGI.
172
#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == '__main__':
WSGIServer(app).run()
This is enough for Apache to work, however nginx and older versions of lighttpd need
a socket to be explicitly passed to communicate with the FastCGI server. For that to
work you need to pass the path to the socket to the WSGIServer:
WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
The path has to be the exact same path you define in the server config.
Save the yourapplication.fcgi file somewhere you will find it again. It makes sense
to have that in /var/www/yourapplication or something similar.
Make sure to set the executable bit on that file so that the servers can execute it:
# chmod +x /var/www/yourapplication/yourapplication.fcgi
Configuring Apache
The example above is good enough for a basic Apache deployment but your .fcgi file
will appear in your application URL e.g. example.com/yourapplication.fcgi/news/.
There are few ways to configure your application so that yourapplication.fcgi does not
appear in the URL. A preferable way is to use the ScriptAlias and SetHandler configuration directives to route requests to the FastCGI server. The following example uses
FastCgiServer to start 5 instances of the application which will handle all incoming
requests:
LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so
FastCgiServer /var/www/html/yourapplication/app.fcgi -idle-timeout 300 -processes 5
<VirtualHost *>
ServerName webapp1.mydomain.com
DocumentRoot /var/www/html/yourapplication
AddHandler fastcgi-script fcgi
ScriptAlias / /var/www/html/yourapplication/app.fcgi/
<Location />
SetHandler fastcgi-script
</Location>
</VirtualHost>
173
lowing the path is not real, its simply used as an identifier to other directives such as
AliasMatch:
FastCgiServer /var/www/html/yourapplication -host 127.0.0.1:3000
If you cannot set ScriptAlias, for example on a shared web host, you can use WSGI
middleware to remove yourapplication.fcgi from the URLs. Set .htaccess:
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
<Files ~ (\.fcgi)>
SetHandler fcgid-script
Options +FollowSymLinks +ExecCGI
</Files>
</IfModule>
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L]
</IfModule>
Set yourapplication.fcgi:
#!/usr/bin/python
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, '<your_local_path>/lib/python2.6/site-packages')
from flup.server.fcgi import WSGIServer
from yourapplication import app
class ScriptNameStripper(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return self.app(environ, start_response)
app = ScriptNameStripper(app)
if __name__ == '__main__':
WSGIServer(app).run()
Configuring lighttpd
A basic FastCGI configuration for lighttpd looks like that:
174
Remember to enable the FastCGI, alias and rewrite modules. This configuration binds
the application to /yourapplication. If you want the application to work in the URL
root you have to work around a lighttpd bug with the LighttpdCGIRootFix middleware.
Make sure to apply it only if you are mounting the application the URL root. Also,
see the Lighty docs for more information on FastCGI and Python (note that explicitly
passing a socket to run() is no longer necessary).
Configuring nginx
Installing FastCGI applications on nginx is a bit different because by default no
FastCGI parameters are forwarded.
A basic Flask FastCGI configuration for nginx looks like this:
location = /yourapplication { rewrite ^ /yourapplication/ last; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
include fastcgi_params;
fastcgi_split_path_info ^(/yourapplication)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}
175
Debugging
FastCGI deployments tend to be hard to debug on most web servers. Very often the
only thing the server log tells you is something along the lines of premature end of
headers. In order to debug the application the only thing that can really give you
ideas why it breaks is switching to the correct user and executing the application by
hand.
This example assumes your application is called application.fcgi and that your web
server user is www-data:
$ su www-data
$ cd /var/www/yourapplication
$ python application.fcgi
Traceback (most recent call last):
File "yourapplication.fcgi", line 4, in <module>
ImportError: No module named yourapplication
In this case the error seems to be yourapplication not being on the python path.
Common problems are:
Relative paths being used. Dont rely on the current working directory.
The code depending on environment variables that are not set by the web server.
Different python interpreters being used.
21.2.5 CGI
If all other deployment methods do not work, CGI will work for sure. CGI is supported by all major servers but usually has a sub-optimal performance.
176
This is also the way you can use a Flask application on Googles App Engine, where
execution happens in a CGI-like environment.
Watch Out
Please make sure in advance that any app.run() calls you might have in your application file are inside an if __name__ == __main__: block or moved to a separate file.
Just make sure its not called because this will always start a local WSGI server which
we do not want if we deploy that application to CGI / app engine.
With CGI, you will also have to make sure that your code does not contain any print
statements, or that sys.stdout is overridden by something that doesnt write into the
HTTP response.
Server Setup
Usually there are two ways to configure the server. Either just copy the .cgi into
a cgi-bin (and use mod_rewrite or something similar to rewrite the URL) or let the
server point to the file directly.
In Apache for example you can put something like this into the config:
ScriptAlias /app /path/to/the/application.cgi
On shared webhosting, though, you might not have access to your Apache config. In
this case, a file called .htaccess, sitting in the public directory you want your app to
be available, works too but the ScriptAlias directive wont work in that case:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f # Don't interfere with static files
RewriteRule ^(.*)$ /path/to/the/application.cgi/$1 [L]
177
178
CHAPTER 22
Becoming Big
Here are your options when growing your codebase or scaling your application.
22.3 Subclass.
The Flask class has many methods designed for subclassing. You can quickly add or
customize behavior by subclassing Flask (see the linked method docs) and using that
subclass wherever you instantiate an application class. This works well with Application Factories.
179
22.5 Fork.
If none of the above options work, fork Flask. The majority of code of Flask is within
Werkzeug and Jinja2. These libraries do the majority of the work. Flask is just the paste
that glues those together. For every project there is the point where the underlying
framework gets in the way (due to assumptions the original developers had). This is
natural because if this would not be the case, the framework would be a very complex
system to begin with which causes a steep learning curve and a lot of user frustration.
This is not unique to Flask. Many people use patched and modified versions of their
framework to counter shortcomings. This idea is also reflected in the license of Flask.
You dont have to contribute any changes back if you decide to modify the framework.
The downside of forking is of course that Flask extensions will most likely break because the new framework has a different import name. Furthermore integrating upstream changes can be a complex process, depending on the number of changes. Because of that, forking should be the very last resort.
180
181
182
Part II
API REFERENCE
If you are looking for information on a specific function, class or method, this part of
the documentation is for you.
183
184
CHAPTER 23
API
This part of the documentation covers all the interfaces of Flask. For parts where Flask
depends on external libraries, we document the most important right here and provide
links to the canonical documentation.
185
So its important what you provide there. If you are using a single module,
__name__ is always the correct value. If you however are using a package, its
usually recommended to hardcode the name of your package there.
For example if your application is defined in yourapplication/app.py you
should create it with one of the two versions below:
app = Flask('yourapplication')
app = Flask(__name__.split('.')[0])
Why is that? The application will work even with __name__, thanks to how resources are looked up. However it will make debugging more painful. Certain
extensions can make assumptions based on the import name of your application.
For example the Flask-SQLAlchemy extension will look for the code in your application that triggered an SQL query in debug mode. If the import name is not
properly set up, that debugging information is lost. (For example it would only
pick up SQL queries in yourapplication.app and not yourapplication.views.frontend)
New in version 0.7: The static_url_path, static_folder, and template_folder parameters were added.
New in version 0.8: The instance_path and instance_relative_config parameters
were added.
New in version 1.0: The root_path parameter was added.
Parameters
import_name the name of the application package
static_url_path can be used to specify a different path
for the static files on the web. Defaults to the name of the
static_folder folder.
static_folder the folder with static files that should be
served at static_url_path. Defaults to the static folder in the
root path of the application.
template_folder the folder that contains the templates that
should be used by the application. Defaults to templates
folder in the root path of the application.
instance_path An alternative instance path for the application. By default the folder instance next to the package or
module is assumed to be the instance path.
instance_relative_config if set to True relative filenames
for loading the config are assumed to be relative to the instance
path instead of the application root.
root_path Flask by default will automatically calculate the
path to the root of the application. In certain situations this
cannot be achieved (for instance if the package is a Python 3
namespace package) and needs to be manually defined.
186
add_template_filter(f, name=None)
Register a custom template filter. Works exactly like the template_filter()
decorator.
Parameters name the optional name of the filter, otherwise the
function name will be used.
add_template_global(f, name=None)
Register a custom template global function.
template_global() decorator.
If a
If the view_func is not provided you will need to connect the endpoint to a
view function like so:
app.view_functions['index'] = index
187
In Flask 0.9 this property was called request_globals_class but it was changed
in 0.10 to app_ctx_globals_class because the flask.g object is now application context scoped.
New in version 0.10.
alias of _AppCtxGlobals
auto_find_instance_path()
Tries to locate the instance path if it was not provided to the constructor of
the application class. It will basically calculate the path to a folder named
instance next to your main file or the package.
New in version 0.8.
before_first_request(f )
Registers a function to be run before the first request to this instance of the
application.
The function will be called without any arguments and its return value is
ignored.
New in version 0.8.
before_first_request_funcs = None
A lists of functions that should be called at the beginning of the first request
to this instance. To register a function here, use the before_first_request()
decorator.
New in version 0.8.
before_request(f )
Registers a function to run before each request.
The function will be called without any arguments. If the function returns
a non-None value, its handled as if it was the return value from the view
and further request handling is stopped.
before_request_funcs = None
A dictionary with lists of functions that should be called at the beginning
of the request. The key of the dictionary is the name of the blueprint this
function is active for, None for all requests. This can for example be used to
open database connections or getting hold of the currently logged in user.
To register a function here, use the before_request() decorator.
blueprints = None
all the attached blueprints in a dictionary by name. Blueprints can be attached multiple times so this dictionary does not tell you how often they
got attached.
New in version 0.7.
cli = None
The click command line context for this application. Commands registered
189
here show up in the flask command once the application has been discovered. The default commands are provided by Flask itself and can be
overridden.
This is an instance of a click.Group object.
config = None
The configuration dictionary as Config. This behaves exactly like a regular
dictionary but supports additional methods to load a config from files.
config_class
The class that is used for the config attribute of this app. Defaults to Config.
Example use cases for a custom class:
1.Default values for certain config options.
2.Access to config values through attributes in addition to keys.
New in version 1.0.
alias of Config
context_processor(f )
Registers a template context processor function.
create_global_jinja_loader()
Creates the loader for the Jinja2 environment. Can be used to override just
the loader and keeping the rest unchanged. Its discouraged to override this
function. Instead one should override the jinja_loader() function instead.
The global loader dispatches between the loaders of the application and the
individual blueprints.
New in version 0.7.
create_jinja_environment()
Creates the Jinja2 environment based on jinja_options and
select_jinja_autoescape(). Since 0.7 this also adds the Jinja2 globals
and filters after initialization. Override this function to customize the
behavior.
New in version 0.5.
Changed in version 1.0: Environment.auto_reload set in accordance with
TEMPLATES_AUTO_RELOAD configuration option.
create_url_adapter(request)
Creates a URL adapter for the given request. The URL adapter is created at
a point where the request context is not yet set up so the request is passed
explicitly.
New in version 0.6.
Changed in version 0.9: This can now also be called without a request object
when the URL adapter is created for the application context.
190
debug
The debug flag. Set this to True to enable debugging of the application.
In debug mode the debugger will kick in when an unhandled exception
occurs and the integrated server will automatically reload the application if
changes in the code are detected.
This attribute can also be configured from the config with the DEBUG configuration key. Defaults to False.
You can also register a function as error handler without using the
errorhandler() decorator. The following example is equivalent to the one
above:
def page_not_found(error):
return 'This page does not exist', 404
app.error_handler_spec[None][404] = page_not_found
The key must match the name of the extension module. For example in case
of a Flask-Foo extension in flask_foo, the key would be foo.
New in version 0.7.
192
full_dispatch_request()
Dispatches the request and on top of that performs request pre and postprocessing as well as HTTP exception catching and error handling.
New in version 0.7.
get_send_file_max_age(filename)
Provides default cache_timeout for the send_file() functions.
By default, this function returns SEND_FILE_MAX_AGE_DEFAULT from the configuration of current_app.
Static file functions such as send_from_directory() use this function,
and send_file() calls this function on current_app when the given
cache_timeout is None. If a cache_timeout is given in send_file(), that timeout is used; otherwise, this method is called.
This allows subclasses to change the behavior when sending files based on
the filename. For example, to set the cache timeout for .js files to 60 seconds:
class MyFlask(flask.Flask):
def get_send_file_max_age(self, name):
if name.lower().endswith('.js'):
return 60
return flask.Flask.get_send_file_max_age(self, name)
194
alias of JSONDecoder
json_encoder
The JSON encoder class to use. Defaults to JSONEncoder.
New in version 0.10.
alias of JSONEncoder
log_exception(exc_info)
Logs an exception. This is called by handle_exception() if debugging is
disabled and right before the handler is called. The default implementation
logs the exception as error on the logger.
New in version 0.8.
logger
A logging.Logger object for this application. The default configuration is to
log to stderr if the application is in debug mode. This logger can be used to
(surprise) log messages. Here some examples:
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
is an instance of response_class.
The following types are allowed for rv:
response_class
str
unicode
a WSGI function
tuple
196
/style.css
/templates
/layout.html
/index.html
If you want to open the schema.sql file you would do the following:
with app.open_resource('schema.sql') as f:
contents = f.read()
do_something_with(contents)
Parameters
resource the name of the resource. To access resources
within subfolders use forward slashes as separator.
mode resource file opening mode, default is rb.
open_session(request)
Creates or opens a new session. Default implementation stores all session
data in a signed cookie. This requires that the secret_key is set. Instead of
overriding this method we recommend replacing the session_interface.
Parameters request an instance of request_class.
permanent_session_lifetime
A timedelta which is used to set the expiration date of a permanent session.
The default is 31 days which makes a permanent session survive for roughly
one month.
This attribute can also be configured from the config with the
PERMANENT_SESSION_LIFETIME configuration key.
Defaults to
timedelta(days=31)
preprocess_request()
Called before the actual request dispatching and will call each
before_request() decorated function, passing no arguments. If any of these
functions returns a value, its handled as if it was the return value from the
view and further request handling is stopped.
This also triggers the url_value_processor() functions before the actual
before_request() functions are called.
preserve_context_on_exception
Returns the value of the PRESERVE_CONTEXT_ON_EXCEPTION configuration
value in case its set, otherwise a sensible default is returned.
New in version 0.7.
process_response(response)
Can be overridden in order to modify the response object before its sent to
the WSGI server. By default this will call all the after_request() decorated
functions.
197
Changed in version 0.5: As of Flask 0.5 the functions registered for after
request execution are called in reverse order of registration.
Parameters response a response_class object.
Returns a new response object or the same, has to be an instance of
response_class.
propagate_exceptions
Returns the value of the PROPAGATE_EXCEPTIONS configuration value in case
its set, otherwise a sensible default is returned.
New in version 0.7.
register_blueprint(blueprint, **options)
Registers a blueprint on the application.
New in version 0.7.
register_error_handler(code_or_exception, f )
Alternative error attach function to the errorhandler() decorator that is
more straightforward to use for non decorator usage.
New in version 0.7.
request_class
The class that is used for request objects. See Request for more information.
alias of Request
request_context(environ)
Creates a RequestContext from the given environment and binds it to the
current context. This must be used in combination with the with statement
because the request is only bound to the current context for the duration of
the with block.
Example usage:
with app.request_context(environ):
do_something_with(request)
The object returned can also be used without the with statement which is
useful for working in the shell. The example above is doing exactly the
same as this code:
ctx = app.request_context(environ)
ctx.push()
try:
do_something_with(request)
finally:
ctx.pop()
Changed in version 0.3: Added support for non-with statement usage and
with statement is now passed the ctx object.
Parameters environ a WSGI environment
198
response_class
The class that is used for response objects. See Response for more information.
alias of Response
route(rule, **options)
A decorator that is used to register a view function for a given URL rule.
This does the same thing as add_url_rule() but is intended for decorator
usage:
@app.route('/')
def index():
return 'Hello World'
199
Parameters
host the hostname to listen on. Set this to 0.0.0.0 to
have the server available externally as well. Defaults to
127.0.0.1.
port the port of the webserver. Defaults to 5000 or the port
defined in the SERVER_NAME config variable if present.
debug if given, enable or disable debug mode. See debug.
options the options to be forwarded to the underlying
Werkzeug server. See werkzeug.serving.run_simple() for
more information.
save_session(session, response)
Saves the session if it needs updates. For the default implementation, check
open_session(). Instead of overriding this method we recommend replacing the session_interface.
Parameters
session the session to be saved (a SecureCookie object)
response an instance of response_class
secret_key
If a secret key is set, cryptographic components can use this to sign cookies
and other things. Set this to a complex random value when you want to use
the secure cookie for instance.
This attribute can also be configured from the config with the SECRET_KEY
configuration key. Defaults to None.
select_jinja_autoescape(filename)
Returns True if autoescaping should be active for the given template name.
If no template name is given, returns True.
New in version 0.5.
send_file_max_age_default
A timedelta which is used as default cache_timeout for the send_file()
functions. The default is 12 hours.
This attribute can also be configured from the config with the
SEND_FILE_MAX_AGE_DEFAULT configuration key. This configuration variable can also be set with an integer value used as seconds. Defaults to
timedelta(hours=12)
send_static_file(filename)
Function used internally to send static files from the static folder to the
browser.
200
202
template_context_processors = None
A dictionary with list of functions that are called without argument to populate the template context. The key of the dictionary is the name of the
blueprint this function is active for, None for all requests. Each returns a
dictionary that the template context is updated with. To register a function
here, use the context_processor() decorator.
template_filter(name=None)
A decorator that is used to register custom template filter. You can specify a
name for the filter, otherwise the function name will be used. Example:
@app.template_filter()
def reverse(s):
return s[::-1]
Note that if you are testing for assertions or exceptions in your application
code, you must set app.testing = True in order for the exceptions to propagate to the test client. Otherwise, the exception will be handled by the
application (not visible to the test client) and the only indication of an AssertionError or other exception will be a 500 status code response to the test
client. See the testing attribute. For example:
app.testing = True
client = app.test_client()
The test client can be used in a with block to defer the closing down of the
context until the end of the with block. This is useful if you want to access
the context locals for testing:
with app.test_client() as c:
rv = c.get('/?vodka=42')
assert request.args['vodka'] == '42'
Additionally, you may pass optional keyword arguments that will then be
passed to the applications test_client_class constructor. For example:
from flask.testing import FlaskClient
class CustomClient(FlaskClient):
def __init__(self, authentication=None, *args, **kwargs):
FlaskClient.__init__(*args, **kwargs)
self._authentication = authentication
app.test_client_class = CustomClient
client = app.test_client(authentication='Basic ....')
(and in the future probably also Flask itself). For example this might activate
unittest helpers that have an additional runtime cost which should not be
enabled by default.
If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the
default its implicitly enabled.
This attribute can also be configured from the config with the TESTING configuration key. Defaults to False.
trap_http_exception(e)
Checks if an HTTP exception should be trapped or not. By default
this will return False for all exceptions except for a bad request key error if TRAP_BAD_REQUEST_ERRORS is set to True. It also returns True if
TRAP_HTTP_EXCEPTIONS is set to True.
This is called for all HTTP exceptions raised by a view function. If it returns
True for any exception the error handler for this exception is not called and
it shows up as regular exception in the traceback. This is helpful for debugging implicitly raised HTTP exceptions.
New in version 0.8.
update_template_context(context)
Update the template context with some commonly used variables. This injects request, session, config and g into the template context as well as everything template context processors want to inject. Note that the as of Flask
0.6, the original values in the context will not be overridden if a context
processor decides to return a value with the same key.
Parameters context the context as a dictionary that is updated in
place to add extra variables.
url_build_error_handlers = None
A list of functions that are called when url_for() raises a BuildError. Each
function registered here is called with error, endpoint and values. If a function
returns None or raises a BuildError the next function is tried.
New in version 0.9.
url_default_functions = None
A dictionary with lists of functions that can be used as URL value preprocessors. The key None here is used for application wide callbacks, otherwise
the key is the name of the blueprint. Each of these functions has the chance
to modify the dictionary of URL values before they are used as the keyword arguments of the view function. For each function registered this one
should also provide a url_defaults() function that adds the parameters
automatically again that were removed that way.
New in version 0.7.
url_defaults(f )
Callback function for URL defaults for all view functions of the application. Its called with the endpoint and values and should update the values
205
passed in place.
url_map = None
The Map for this instance. You can use this to change the routing converters
after the class was created but before any routes are connected. Example:
from werkzeug.routing import BaseConverter
class ListConverter(BaseConverter):
def to_python(self, value):
return value.split(',')
def to_url(self, values):
return ','.join(BaseConverter.to_url(value)
for value in values)
app = Flask(__name__)
app.url_map.converters['list'] = ListConverter
url_rule_class
The rule object to use for URL rules created. This is used by add_url_rule().
Defaults to werkzeug.routing.Rule.
New in version 0.7.
alias of Rule
url_value_preprocessor(f )
Registers a function as URL value preprocessor for all view functions of the
application. Its called before the view functions are called and can modify
the url values provided.
url_value_preprocessors = None
A dictionary with lists of functions that can be used as URL value processor
functions. Whenever a URL is built these functions are called to modify
the dictionary of values in place. The key None here is used for application
wide callbacks, otherwise the key is the name of the blueprint. Each of these
functions has the chance to modify the dictionary
New in version 0.7.
use_x_sendfile
Enable this if you want to use the X-Sendfile feature. Keep in mind that the
server has to support this. This only affects files sent with the send_file()
method.
New in version 0.2.
This attribute can also be configured from the config with the
USE_X_SENDFILE configuration key. Defaults to False.
view_functions = None
A dictionary of all view functions registered. The keys will be function
names which are also used to generate URLs and the values are the function
objects themselves. To register a view function, use the route() decorator.
206
wsgi_app(environ, start_response)
The actual WSGI application. This is not implemented in __call__ so that
middlewares can be applied without losing a reference to the class. So instead of doing this:
app = MyMiddleware(app)
Then you still have the original application object around and can continue
to call methods on it.
Changed in version 0.7: The behavior of the before and after request callbacks was changed under error conditions and a new callback was added
that will always execute at the end of the request, independent on if an error
occurred or not. See Callbacks and Errors.
Parameters
environ a WSGI environment
start_response a callable accepting a status code, a list
of headers and an optional exception context to start the response
Like
Like
Like
209
class MyFlask(flask.Flask):
def get_send_file_max_age(self, name):
if name.lower().endswith('.js'):
return 60
return flask.Flask.get_send_file_max_age(self, name)
If you want to open the schema.sql file you would do the following:
with app.open_resource('schema.sql') as f:
contents = f.read()
do_something_with(contents)
Parameters
resource the name of the resource. To access resources
within subfolders use forward slashes as separator.
mode resource file opening mode, default is rb.
record(func)
Registers a function that is called when the blueprint is registered on the
application. This function is called with the state as argument as returned
by the make_setup_state() method.
210
record_once(func)
Works like record() but wraps the function in another function that will
ensure the function is only called once. If the blueprint is registered a second
time on the application, the function passed is not called.
register(app, options, first_registration=False)
Called by Flask.register_blueprint() to register a blueprint on the application. This can be overridden to customize the register behavior. Keyword arguments from register_blueprint() are directly forwarded to this
method in the options dictionary.
register_error_handler(code_or_exception, f )
Non-decorator version of the errorhandler() error attach function, akin to
the register_error_handler() application-wide function of the Flask object but for error handlers limited to this blueprint.
New in version 1.0.
route(rule, **options)
Like Flask.route() but for a blueprint. The endpoint for the url_for()
function is prefixed with the name of the blueprint.
send_static_file(filename)
Function used internally to send static files from the static folder to the
browser.
New in version 0.5.
static_folder
The absolute path to the configured static folder.
teardown_app_request(f )
Like Flask.teardown_request() but for a blueprint. Such a function is executed when tearing down each request, even if outside of the blueprint.
teardown_request(f )
Like Flask.teardown_request() but for a blueprint. This function is
only executed when tearing down requests handled by a function of that
blueprint. Teardown request functions are executed when the request context is popped, even when no actual request was performed.
url_defaults(f )
Callback function for URL defaults for this blueprint. Its called with the
endpoint and values and should update the values passed in place.
url_value_preprocessor(f )
Registers a function as URL value preprocessor for this blueprint. Its called
before the view functions are called and can modify the url values provided.
211
212
full_path
script_root
url
base_url
url_root
Provides different ways to look at the current IRI. Imagine your application
is listening on the following application root:
http://www.example.com/myapplication
In this case the values of the above mentioned attributes would be the following:
path
full_path
script_root
base_url
url
url_root
u//page.html
u//page.html?x=y
u/myapplication
uhttp://www.example.com/myapplication//page.html
uhttp://www.example.com/myapplication//page.html?x=y
uhttp://www.example.com/myapplication/
is_xhr
True if the request was triggered via a JavaScript XMLHttpRequest. This only
works with libraries that support the X-Requested-With header and set it to
XMLHttpRequest. Libraries that do that are prototype, jQuery and Mochikit
and probably some more.
blueprint
The name of the current blueprint
endpoint
The endpoint that matched the request. This in combination with view_args
can be used to reconstruct the same or a modified URL. If an exception
happened when matching, this will be None.
get_json(force=False, silent=False, cache=True)
Parses the incoming JSON request data and returns it. If parsing fails the
on_json_loading_failed() method on the request object will be invoked.
By default this function will only load the json data if the mimetype is
application/json but this can be overridden by the force parameter.
Parameters
force if set to True the mimetype is ignored.
silent if set to True this method will fail silently and return
None.
213
215
by the domain www.example.com, foo.example.com etc. Otherwise, a cookie will only be readable by the domain that set
it.
path limits the cookie to a given path, per default it will
span the whole domain.
23.5 Sessions
If you have the Flask.secret_key set you can use sessions in Flask applications. A
session basically makes it possible to remember information from one request to another. The way Flask does this is by using a signed cookie. So the user can look at the
session contents, but not modify it unless they know the secret key, so make sure to
set that to something complex and unguessable.
To access the current session you can use the session object:
class flask.session
The session object works pretty much like an ordinary dict, with the difference
that it keeps track on modifications.
This is a proxy. See Notes On Proxies for more information.
The following attributes are interesting:
new
True if the session is new, False otherwise.
modified
True if the session object detected a modification. Be advised that modifications on mutable structures are not picked up automatically, in that situation
you have to explicitly set the attribute to True yourself. Here an example:
# this change is not picked up because a mutable object (here
# a list) is changed.
session['objects'].append(42)
# so mark it as modified yourself
session.modified = True
permanent
If set to True the session lives for permanent_session_lifetime seconds. The
default is 31 days. If set to False (which is the default) the session will be
deleted when the user closes the browser.
class flask.sessions.SessionInterface
The basic interface you have to implement in order to replace the default session
interface which uses werkzeugs securecookie implementation. The only methods you have to implement are open_session() and save_session(), the others
have useful defaults which you dont need to change.
The session object returned by the open_session() method has to provide a dictionary like interface plus the properties and methods from the SessionMixin.
We recommend just subclassing a dict and adding that mixin:
class Session(dict, SessionMixin):
pass
217
make_null_session(app)
Creates a null session which acts as a replacement object if the real session
support could not be loaded due to a configuration error. This mainly aids
the user experience because the job of the null session is to still support
lookup without complaining but modifications are answered with a helpful
error message of what failed.
This creates an instance of null_session_class by default.
null_session_class
make_null_session() will look here for the class that should be created
when a null session is requested. Likewise the is_null_session() method
will perform a typecheck against this type.
alias of NullSession
open_session(app, request)
This method has to be implemented and must either return None in case
the loading failed because of a configuration error or an instance of a session object which implements a dictionary like interface + the methods and
attributes on SessionMixin.
pickle_based = False
A flag that indicates if the session interface is pickle based. This can be used
by flask extensions to make a decision in regards to how to deal with the
session object.
New in version 0.10.
save_session(app, session, response)
This is called for actual sessions returned by open_session() at the end of
the request. This is still called during a request context so if you absolutely
need access to the request you can do that.
should_set_cookie(app, session)
Indicates whether a cookie should be set now or not. This is used by session
backends to figure out if they should emit a set-cookie header or not. The
default behavior is controlled by the SESSION_REFRESH_EACH_REQUEST config
variable. If its set to False then a cookie is only set if the session is modified,
if set to True its always set if the session is permanent.
This check is usually skipped if sessions get deleted.
New in version 1.0.
class flask.sessions.SecureCookieSessionInterface
The default session interface that stores sessions in signed cookies through the
itsdangerous module.
static digest_method()
the hash function to use for the signature. The default is sha1
key_derivation = hmac
the name of the itsdangerous supported key derivation. The default is
218
hmac.
salt = cookie-session
the salt that should be applied on top of the secret key for the signing of
cookie based sessions.
serializer = <flask.sessions.TaggedJSONSerializer object>
A python serializer for the payload. The default is a compact JSON derived
serializer with support for some extra Python types such as datetime objects
or tuples.
session_class
alias of SecureCookieSession
class flask.sessions.SecureCookieSession(initial=None)
Base class for sessions based on signed cookies.
class flask.sessions.NullSession(initial=None)
Class used to generate nicer error messages if sessions are not available. Will still
allow read-only access to the empty session but fail on setting.
class flask.sessions.SessionMixin
Expands a basic dictionary with an accessors that are expected by Flask extensions and users for the session.
modified = True
for some backends this will always be True, but some backends will default
this to false and detect changes in the dictionary for as long as changes do
not happen on mutable structures in the session. The default mixin implementation just hardcodes True in.
new = False
some session backends can tell you if a session is new, but that is not necessarily guaranteed. Use with caution. The default mixin implementation
just hardcodes False in.
permanent
this reflects the _permanent key in the dict.
flask.sessions.session_json_serializer = <flask.sessions.TaggedJSONSerializer object>
A customized JSON serializer that supports a few extra types that we take for
granted when serializing (tuples, markup objects, datetime).
This object provides dumping and loading methods similar to simplejson but it
also tags certain builtin Python objects that commonly appear in sessions. Currently the following extended values are supported in the JSON it dumps:
Markup objects
UUID objects
datetime objects
tuples
219
Notice
The PERMANENT_SESSION_LIFETIME config key can also be an integer starting with Flask
0.8. Either catch this down yourself or use the permanent_session_lifetime attribute
on the app which converts the result to an integer automatically.
220
Additionally as of 0.10 you can use the get() method to get an attribute or None
(or the second argument) if its not set. These two usages are now equivalent:
user = getattr(flask.g, 'user', None)
user = flask.g.get('user', None)
Its now also possible to use the in operator on it to see if an attribute is defined
and it yields all keys on iteration.
As of 1.0 you can use pop() and setdefault() in the same way you would use
them on a dictionary.
This is a proxy. See Notes On Proxies for more information.
Alternatively you can also just test any of the context bound objects (such as
request or g for truthness):
class User(db.Model):
def __init__(self, username, remote_addr=None):
self.username = username
if remote_addr is None and request:
remote_addr = request.remote_addr
self.remote_addr = remote_addr
This is useful when working with greenlets. The moment the function is decorated a copy of the request context is created and then pushed when the function
is called.
Example:
import gevent
from flask import copy_current_request_context
@app.route('/')
def index():
@copy_current_request_context
def do_some_work():
# do some work here, it can access flask.request like you
# would otherwise in the view function.
...
gevent.spawn(do_some_work)
return 'Regular response'
222
if url is None:
# External lookup did not have a URL.
# Re-raise the BuildError, in context of original traceback.
exc_type, exc_value, tb = sys.exc_info()
if exc_value is error:
raise exc_type, exc_value, tb
else:
raise error
# url_for will use this result, instead of raising BuildError.
return url
app.url_build_error_handlers.append(external_url_handler)
Here, error is the instance of BuildError, and endpoint and values are the arguments passed into url_for. Note that this is for building URLs outside the current
application, and not for handling 404 NotFound errors.
New in version 0.10: The _scheme parameter was added.
New in version 0.9: The _anchor and _method parameters were added.
New in version 0.9: Calls Flask.handle_build_error() on BuildError.
Parameters
endpoint the endpoint of the URL (name of the function)
values the variable arguments of the URL rule
_external if set to True, an absolute URL is generated. Server
address can be changed via SERVER_NAME configuration variable
which defaults to localhost.
_scheme a string specifying the desired URL scheme. The _external parameter must be set to True or a ValueError is raised.
The default behavior uses the same scheme as the current request, or PREFERRED_URL_SCHEME from the app configuration if no
request context is available. As of Werkzeug 0.10, this also can
be set to an empty string to build protocol-relative URLs.
_anchor if provided this is added as anchor to the URL.
_method if provided this explicitly specifies an HTTP method.
flask.abort(code)
Raises an HTTPException for the given status code. For example to abort request
handling with a page not found exception, you would call abort(404).
Parameters code the HTTP error code.
flask.redirect(location, code=302, Response=None)
Returns a response object (a WSGI application) that, if called, redirects the client
to the target location. Supported codes are 301, 302, 303, 305, and 307. 300 is not
supported because its not a real redirect and 304 because its the answer for a
request with a request with defined If-Modified-Since headers.
223
New in version 0.6: The location can now be a unicode string that is encoded
using the iri_to_uri() function.
New in version 0.10: The class used for the Response object can now be passed
in.
Parameters
location the location the response should redirect to.
code the redirect status code. defaults to 302.
Response (class) a Response class to use when instantiating
a response. The default is werkzeug.wrappers.Response if unspecified.
flask.make_response(*args)
Sometimes it is necessary to set additional headers in a view. Because views
do not have to return response objects but can return a value that is converted
into a response object by Flask itself, it becomes tricky to add headers to it. This
function can be called instead of using a return and you will get a response object
which you can use to attach headers.
If view looked like this and you want to add a new header:
def index():
return render_template('index.html', foo=42)
This function accepts the very same arguments you can return from a view function. This for example creates a response with a 404 error code:
response = make_response(render_template('not_found.html'), 404)
The other use case of this function is to force the return value of a view function
into a response which is helpful with view decorators:
response = make_response(view_function())
response.headers['X-Parachutes'] = 'parachutes are cool'
224
This is more useful if a function other than the view function wants to modify
a response. For instance think of a decorator that wants to add some headers
without converting the return value into a response object.
New in version 0.9.
flask.send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=None, conditional=False)
Sends the contents of a file to the client. This will use the most efficient
method available and configured. By default it will try to use the WSGI
servers file_wrapper support. Alternatively you can set the applications
use_x_sendfile attribute to True to directly emit an X-Sendfile header. This
however requires support of the underlying webserver for X-Sendfile.
By default it will try to guess the mimetype for you, but you can also explicitly
provide one. For extra security you probably want to send certain files as attachment (HTML for instance). The mimetype guessing requires a filename or an
attachment_filename to be provided.
Please never pass filenames to this function from user sources; you should use
send_from_directory() instead.
New in version 0.2.
New in version 0.5: The add_etags, cache_timeout and conditional parameters were
added. The default behavior is now to attach etags.
Changed in version 0.7: mimetype guessing and etag support for file objects was
deprecated because it was unreliable. Pass a filename if you are able to, otherwise
attach an etag yourself. This functionality will be removed in Flask 1.0
Changed in version 0.9: cache_timeout pulls its default from application config,
when None.
Parameters
filename_or_fp the filename of the file to send in latin-1.
225
This is relative to the root_path if a relative path is specified. Alternatively a file object might be provided in which
case X-Sendfile might not work and fall back to the traditional
method. Make sure that the file pointer is positioned at the
start of data to send before calling send_file().
mimetype the mimetype of the file if provided, otherwise auto
detection happens.
as_attachment set to True if you want to send this file with a
Content-Disposition: attachment header.
attachment_filename the filename for the attachment if it differs from the files filename.
add_etags set to False to disable attaching of etags.
conditional set to True to enable conditional responses.
cache_timeout the timeout in seconds for the headers. When
None (default), this value is set by get_send_file_max_age() of
current_app.
flask.send_from_directory(directory, filename, **options)
Send a file from a given directory with send_file(). This is a secure way to
quickly expose static files from an upload folder or something similar.
Example usage:
@app.route('/uploads/<path:filename>')
def download_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename, as_attachment=True)
@app.route('/wiki/<path:filename>')
def wiki_page(filename):
filename = safe_join(app.config['WIKI_FOLDER'], filename)
with open(filename, 'rb') as fd:
content = fd.read() # Read and process the file content...
Parameters
directory the base directory.
filename the untrusted filename relative to that directory.
Raises NotFound if the resulting path would fall out of directory.
flask.escape(s) markup
Convert the characters &, <, >, , and in string s to HTML-safe sequences. Use
this if you need to display text that might contain such characters in HTML.
Marks return value as markup string.
class flask.Markup
Marks a string as being safe for inclusion in HTML/XML output without needing to be escaped. This implements the __html__ interface a couple of frameworks and web applications use. Markup is a direct subclass of unicode and provides all the methods of unicode just that it escapes arguments passed and always
returns Markup.
The escape function returns markup objects so that double escaping cant happen.
The constructor of the Markup class can be used for three different things: When
passed an unicode object its assumed to be safe, when passed an object with
an HTML representation (has an __html__ method) that representation is used,
otherwise the object passed is converted into a unicode string and then assumed
to be safe:
>>> Markup("Hello <em>World</em>!")
Markup(u'Hello <em>World</em>!')
>>> class Foo(object):
... def __html__(self):
... return '<a href="#">foo</a>'
...
>>> Markup(Foo())
Markup(u'<a href="#">foo</a>')
If you want object passed being always treated as unsafe you can use the
escape() classmethod to create a Markup object:
>>> Markup.escape("Hello <em>World</em>!")
Markup(u'Hello <em>World</em>!')
Operations on a markup string are markup aware which means that all arguments are passed through the escape() function:
227
>>> em = Markup("<em>%s</em>")
>>> em % "foo & bar"
Markup(u'<em>foo & bar</em>')
>>> strong = Markup("<strong>%(text)s</strong>")
>>> strong % {'text': '<blink>hacker here</blink>'}
Markup(u'<strong><blink>hacker here</blink></strong>')
>>> Markup("<em>Hello</em> ") + "<foo>"
Markup(u'<em>Hello</em> <foo>')
classmethod escape(s)
Escape the string. Works like escape() with the difference that for subclasses of Markup this function would return the correct subclass.
striptags()
Unescape markup into an text_type string and strip all tags. This also resolves known HTML4 and XHTML entities. Whitespace is normalized to
one:
>>> Markup("Main »
u'Main \xbb About'
<em>About</em>").striptags()
unescape()
Unescape markup again into an text_type string. This also resolves known
HTML4 and XHTML entities:
>>> Markup("Main » <em>About</em>").unescape()
u'Main \xbb <em>About</em>'
Filter the flashed messages to one or more categories by providing those categories in category_filter. This allows rendering categories in separate html blocks.
The with_categories and category_filter arguments are distinct:
with_categories controls whether categories are returned with message text
(True gives a tuple, where False gives just the message text).
category_filter filters the messages down to only those matching the provided categories.
See Message Flashing for examples.
Changed in version 0.3: with_categories parameter added.
Changed in version 0.9: category_filter parameter added.
Parameters
with_categories set to True to also receive categories.
category_filter whitelist of categories to limit return values
For usage examples, read the json documentation in the standard library. The following extensions are by default applied to the stdlibs JSON module:
1. datetime objects are serialized as RFC 822 strings.
2. Any object with an __html__ method (like Markup) will have that method called
and then the return value is serialized as string.
The htmlsafe_dumps() function of this json module is also available as filter called
|tojson in Jinja2. Note that inside script tags no escaping must take place, so make
sure to disable escaping with |safe if you intend to use it inside script tags unless
you are using Flask 0.10 which implies that:
229
<script type=text/javascript>
doSomethingWith({{ user.username|tojson|safe }});
</script>
For security reasons only objects are supported toplevel. For more information
about this, have a look at JSON Security.
This functions response will be pretty printed if it was not requested
with X-Requested-With: XMLHttpRequest to simplify debugging unless the
JSONIFY_PRETTYPRINT_REGULAR config parameter is set to false. Compressed (not
pretty) formatting currently means no indents and no spaces after separators.
New in version 0.2.
flask.json.dumps(obj, **kwargs)
Serialize obj to a JSON formatted str by using the applications configured encoder (json_encoder) if there is an application on the stack.
This function can return unicode strings or ascii-only bytestrings by default
which coerce into unicode strings automatically. That behavior by default is
230
class flask.json.JSONDecoder(encoding=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
strict=True,
object_pairs_hook=None)
The default JSON decoder. This one does not change the behavior from the default simplejson decoder. Consult the json documentation for more information. This decoder is not only used for the load functions of this module but also
Request.
Parameters
template_name_or_list the name of the template to be rendered, or an iterable with template names the first one existing
will be rendered
context the variables that should be available in the context
of the template.
flask.render_template_string(source, **context)
Renders a template from the given template source string with the given context.
Template variables will be autoescaped.
Parameters
source the source code of the template to be rendered
context the variables that should be available in the context
of the template.
flask.get_template_attribute(template_name, attribute)
Loads a macro (or variable) a template exports. This can be used to invoke a
macro from within Python code. If you for example have a template named
_cider.html with the following contents:
{% macro hello(name) %}Hello {{ name }}!{% endmacro %}
23.13 Configuration
class flask.Config(root_path, defaults=None)
Works exactly like a dict but provides ways to fill it from files or special dictionaries. There are two common patterns to populate the config.
Either you can fill the config from a config file:
app.config.from_pyfile('yourconfig.cfg')
Or alternatively you can define the configuration options in the module that calls
from_object() or provide an import path to a module that should be loaded.
It is also possible to tell it to use the same module and with that provide the
configuration values just before the call:
232
DEBUG = True
SECRET_KEY = 'development key'
app.config.from_object(__name__)
In both cases (loading from any Python file or loading from modules), only uppercase keys are added to the config. This makes it possible to use lowercase
values in the config file for temporary values that are not added to the config or
to define the config keys in the same file that implements the application.
Probably the most interesting way to load configurations is from an environment
variable pointing to a file:
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
In this case before launching the application you have to set this environment
variable to the file you want to use. On Linux and OS X use the export statement:
export YOURAPPLICATION_SETTINGS='/path/to/config/file'
Parameters
variable_name name of the environment variable
silent set to True if you want silent failure for missing files.
Returns bool. True if able to load config, False otherwise.
from_json(filename, silent=False)
Updates the values in the config from a JSON file. This function behaves
as if the JSON object was a dictionary and passed to the from_mapping()
function.
Parameters
filename the filename of the JSON file. This can either be
an absolute filename or a filename relative to the root path.
silent set to True if you want silent failure for missing files.
233
You should not use this function to load the actual configuration but
rather configuration defaults. The actual config should be loaded with
from_pyfile() and ideally from a location not within the package because
the package might be installed system wide.
Parameters obj an import name or object
from_pyfile(filename, silent=False)
Updates the values in the config from a Python file. This function behaves
as if the file was imported as module with the from_object() function.
Parameters
filename the filename of the config. This can either be an
absolute filename or a filename relative to the root path.
silent set to True if you want silent failure for missing files.
New in version 0.7: silent parameter.
get_namespace(namespace, lowercase=True, trim_namespace=True)
Returns a dictionary containing a subset of configuration options that match
the specified namespace/prefix. Example usage:
app.config['IMAGE_STORE_TYPE'] = 'fs'
app.config['IMAGE_STORE_PATH'] = '/var/app/images'
app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com'
image_store_config = app.config.get_namespace('IMAGE_STORE_')
234
'path': '/var/app/images',
'base_url': 'http://img.website.com'
}
23.14 Extensions
flask.ext
This module acts as redirect import module to Flask extensions. It was added in
0.8 as the canonical way to import Flask extensions and makes it possible for us
to have more flexibility in how we distribute extensions.
If you want to use an extension named Flask-Foo you would import it from
ext as follows:
from flask.ext import foo
235
def generate():
yield 'Hello '
yield request.args['name']
yield '!'
return Response(generate())
236
request object is the same this cannot be used to move a request context to
a different thread unless access to the request object is locked.
New in version 0.10.
match_request()
Can be overridden by a subclass to hook into the matching of the request.
pop(exc=<object object>)
Pops the request context and unbinds it by doing that. This will also trigger
the execution of functions registered by the teardown_request() decorator.
Changed in version 0.9: Added the exc argument.
push()
Binds the request context to the current context.
flask._request_ctx_stack
The internal LocalStack that is used to implement all the context local objects
used in Flask. This is a documented instance and can be used by extensions and
application code but the use is discouraged in general.
The following attributes are always present on each layer of the stack:
app the active Flask application.
url_adapter the URL adapter that was used to match the request.
request the current request object.
session the active session object.
g an object with all the attributes of the flask.g object.
flashes an internal cache for the flashed messages.
Example usage:
from flask import _request_ctx_stack
def get_session():
ctx = _request_ctx_stack.top
if ctx is not None:
return ctx.session
class flask.ctx.AppContext(app)
The application context binds an application object implicitly to the current
thread or greenlet, similar to how the RequestContext binds request information. The application context is also implicitly created if a request context is
created but the application is not on top of the individual application context.
pop(exc=<object object>)
Pops the app context.
push()
Binds the app context to the current context.
237
flask._app_ctx_stack
Works similar to the request context but only binds the application. This is
mainly there for extensions to store data.
New in version 0.9.
class flask.blueprints.BlueprintSetupState(blueprint,
app,
options,
first_registration)
Temporary holder object for registering a blueprint with the application. An instance of this class is created by the make_setup_state() method and later passed
to all register callback functions.
add_url_rule(rule, endpoint=None, view_func=None, **options)
A helper method to register a rule (and optionally a view function) to the
application. The endpoint is automatically prefixed with the blueprints
name.
app = None
a reference to the current application
blueprint = None
a reference to the blueprint that created this setup state.
first_registration = None
as blueprints can be registered multiple times with the application and not
everything wants to be registered multiple times on it, this attribute can be
used to figure out if the blueprint was registered in the past already.
options = None
a dictionary with all options that were passed to the register_blueprint()
method.
subdomain = None
The subdomain that the blueprint should be active for, None otherwise.
url_defaults = None
A dictionary with URL defaults that is added to each and every URL that
was defined with the blueprint.
url_prefix = None
The prefix that should be used for all URLs defined on the blueprint.
23.17 Signals
New in version 0.6.
signals.signals_available
True if the signaling system is available. This is the case when blinker is installed.
The following signals exist in Flask:
flask.template_rendered
This signal is sent when a template was successfully rendered. The signal is in238
voked with the instance of the template as template and the context as dictionary
(named context).
Example subscriber:
def log_template_renders(sender, template, context, **extra):
sender.logger.debug('Rendering template "%s" with context %s',
template.name or 'string template',
context)
from flask import template_rendered
template_rendered.connect(log_template_renders, app)
flask.before_render_template
This signal is sent before template rendering process. The signal is invoked with
the instance of the template as template and the context as dictionary (named
context).
Example subscriber:
def log_template_renders(sender, template, context, **extra):
sender.logger.debug('Rendering template "%s" with context %s',
template.name or 'string template',
context)
from flask import before_render_template
before_render_template.connect(log_template_renders, app)
flask.request_started
This signal is sent when the request context is set up, before any request processing happens. Because the request context is already bound, the subscriber can
access the request with the standard global proxies such as request.
Example subscriber:
def log_request(sender, **extra):
sender.logger.debug('Request context is set up')
from flask import request_started
request_started.connect(log_request, app)
flask.request_finished
This signal is sent right before the response is sent to the client. It is passed the
response to be sent named response.
Example subscriber:
def log_response(sender, response, **extra):
sender.logger.debug('Request context is about to close down. '
'Response: %s', response)
from flask import request_finished
request_finished.connect(log_response, app)
239
flask.got_request_exception
This signal is sent when an exception happens during request processing. It is
sent before the standard exception handling kicks in and even in debug mode,
where no exception handling happens. The exception itself is passed to the subscriber as exception.
Example subscriber:
def log_exception(sender, exception, **extra):
sender.logger.debug('Got exception during processing: %s', exception)
from flask import got_request_exception
got_request_exception.connect(log_exception, app)
flask.request_tearing_down
This signal is sent when the request is tearing down. This is always called, even
if an exception is caused. Currently functions listening to this signal are called
after the regular teardown handlers, but this is not something you can rely on.
Example subscriber:
def close_db_connection(sender, **extra):
session.close()
from flask import request_tearing_down
request_tearing_down.connect(close_db_connection, app)
As of Flask 0.9, this will also be passed an exc keyword argument that has a
reference to the exception that caused the teardown if there was one.
flask.appcontext_tearing_down
This signal is sent when the app context is tearing down. This is always called,
even if an exception is caused. Currently functions listening to this signal are
called after the regular teardown handlers, but this is not something you can
rely on.
Example subscriber:
def close_db_connection(sender, **extra):
session.close()
from flask import appcontext_tearing_down
appcontext_tearing_down.connect(close_db_connection, app)
This will also be passed an exc keyword argument that has a reference to the
exception that caused the teardown if there was one.
flask.appcontext_pushed
This signal is sent when an application context is pushed. The sender is the
application. This is usually useful for unittests in order to temporarily hook in
information. For instance it can be used to set a resource early onto the g object.
Example usage:
240
241
When you want to decorate a pluggable view you will have to either do that
when the view function is created (by wrapping the return value of as_view())
or you can use the decorators attribute:
class SecretView(View):
methods = ['GET']
decorators = [superuser_required]
def dispatch_request(self):
...
The decorators stored in the decorators list are applied one after another when
the view function is created. Note that you can not use the class based decorators
since those would decorate the view class and not the generated view function!
classmethod as_view(name, *class_args, **class_kwargs)
Converts the class into an actual view function that can be used with the
routing system. Internally this generates a function on the fly which will instantiate the View on each request and call the dispatch_request() method
on it.
The arguments passed to as_view() are forwarded to the constructor of the
class.
decorators = ()
The canonical way to decorate class-based views is to decorate the return
value of as_view(). However since this moves parts of the logic from the
class declaration to the place where its hooked into the routing system.
You can place one or more decorators in this list and whenever the view
function is created the result is automatically decorated.
New in version 0.8.
242
dispatch_request()
Subclasses have to override this method to implement the actual view function code. This method is called with all the arguments from the URL rule.
methods = None
A for which methods this pluggable view can handle.
class flask.views.MethodView
Like a regular class-based view but that dispatches requests to particular methods. For instance if you implement a method called get() it means you will
response to GET requests and the dispatch_request() implementation will automatically forward your request to that. Also options is set for you automatically:
class CounterAPI(MethodView):
def get(self):
return session.get('counter', 0)
def post(self):
session['counter'] = session.get('counter', 0) + 1
return 'OK'
app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter'))
@app.route('/')
def index():
pass
@app.route('/<username>')
def show_user(username):
pass
@app.route('/post/<int:post_id>')
def show_post(post_id):
pass
An important detail to keep in mind is how Flask deals with trailing slashes. The idea
is to keep each URL unique so the following rules apply:
1. If a rule ends with a slash and is requested without a slash by the user, the user
is automatically redirected to the same page with a trailing slash attached.
2. If a rule does not end with a trailing slash and the user requests the page with a
trailing slash, a 404 not found is raised.
This is consistent with how web servers deal with static files. This also makes it possible to use relative link targets safely.
You can also define multiple rules for the same function. They have to be unique
however. Defaults can also be specified. Here for example is a definition for a URL
that accepts an optional page:
@app.route('/users/', defaults={'page': 1})
@app.route('/users/page/<int:page>')
def show_users(page):
pass
This specifies that /users/ will be the URL for page one and /users/page/N will be the
URL for page N.
Here are the parameters that route() and add_url_rule() accept. The only difference
is that with the route parameter the view function is defined with the decorator instead
of the view_func parameter.
244
rule
the URL rule as string
endthe endpoint for the registered URL rule. Flask itself assumes that the name
point of the view function is the name of the endpoint if not explicitly stated.
view_func
the function to call when serving a request to the provided endpoint. If this
is not provided one can specify the function later by storing it in the
view_functions dictionary with the endpoint as key.
deA dictionary with defaults for this rule. See the example above for how
faults defaults work.
subspecifies the rule for the subdomain in case subdomain matching is in use.
doIf not specified the default subdomain is assumed.
main
**op- the options to be forwarded to the underlying Rule object. A change to
tions Werkzeug is handling of method options. methods is a list of methods this
rule should be limited to (GET, POST etc.). By default a rule just listens for
GET (and implicitly HEAD). Starting with Flask 0.6, OPTIONS is implicitly
added and handled by the standard request handling. They have to be
specified as keyword arguments.
245
app_import_path = None
The application import path
create_app = None
Optionally a function that is passed the script info to create the instance of
the application.
data = None
A dictionary with arbitrary data that can be associated with this script info.
debug = None
The debug flag. If this is not None, the application will automatically have
its debug flag overridden with this value.
load_app()
Loads the Flask app (if not yet loaded) and returns it. Calling this multiple
times will just result in the already loaded app to be returned.
flask.cli.with_appcontext(f )
Wraps a callback so that its guaranteed to be executed with the scripts application context. If callbacks are registered directly to the app.cli object then they
are wrapped with this function by default unless its disabled.
flask.cli.pass_script_info(f )
Marks a function so that an instance of ScriptInfo is passed as first argument to
the click callback.
flask.cli.script_info_option(*args, **kwargs)
This decorator works exactly like click.option() but is eager by default and
stores the value in the ScriptInfo.data. This is useful to further customize an
application factory in very complex situations.
Parameters script_info_key this is a mandatory keyword argument
which defines under which data key the value should be stored.
A special decorator that informs a click callback to be passed the script info object
as first argument. This is normally not useful unless you implement very special
commands like the run command which does not want the application to be
loaded yet.
flask.cli.run_command = <click.core.Command object>
Runs a local development server for the Flask application.
This local server is recommended for development purposes only but it can also
be used for simple intranet deployments. By default it will not support any sort
of concurrency at all to simplify debugging. This can be changed with the withthreads option which will enable basic multithreading.
The reloader and debugger are by default enabled if the debug flag of Flask is
enabled and disabled otherwise.
flask.cli.shell_command = <click.core.Command object>
Runs an interactive Python shell in the context of a given Flask application. The
247
application will populate the default namespace of this shell according to its
configuration.
This is useful for executing small snippets of management code without having
to manually configuring the application.
248
Part III
ADDITIONAL NOTES
Design notes, legal information and changelog are here for the interested.
249
250
CHAPTER 24
If you are curious why Flask does certain things the way it does and not differently,
this section is for you. This should give you an idea about some of the design decisions
that may appear arbitrary and surprising at first, especially in direct comparison with
other frameworks.
There are three major reasons for this. The most important one is that implicit application objects require that there may only be one instance at the time. There are ways
to fake multiple applications with a single application object, like maintaining a stack
of applications, but this causes some problems I wont outline here in detail. Now
the question is: when does a microframework need more than one application at the
251
same time? A good example for this is unittesting. When you want to test something
it can be very helpful to create a minimal application to test specific behavior. When
the application object is deleted everything it allocated will be freed again.
Another thing that becomes possible when you have an explicit object lying around in
your code is that you can subclass the base class (Flask) to alter specific behavior. This
would not be possible without hacks if the object were created ahead of time for you
based on a class that is not exposed to you.
But there is another very important reason why Flask depends on an explicit instantiation of that class: the package name. Whenever you create a Flask instance you usually
pass it __name__ as package name. Flask depends on that information to properly load
resources relative to your module. With Pythons outstanding support for reflection it
can then access the package to figure out where the templates and static files are stored
(see open_resource()). Now obviously there are frameworks around that do not need
any configuration and will still be able to load templates relative to your application
module. But they have to use the current working directory for that, which is a very
unreliable way to determine where the application is. The current working directory is
process-wide and if you are running multiple applications in one process (which could
happen in a webserver without you knowing) the paths will be off. Worse: many webservers do not set the working directory to the directory of your application but to the
document root which does not have to be the same folder.
The third reason is explicit is better than implicit. That object is your WSGI application, you dont have to remember anything else. If you want to apply a WSGI
middleware, just wrap it and youre done (though there are better ways to do that so
that you do not lose the reference to the application object wsgi_app()).
Furthermore this design makes it possible to use a factory function to create the application which is very helpful for unittesting and similar things (Application Factories).
will still configure Jinja2 for you. While that limitation that Jinja2 is always configured
will probably go away, the decision to bundle one template engine and use that will
not.
Template engines are like programming languages and each of those engines has a
certain understanding about how things work. On the surface they all work the same:
you tell the engine to evaluate a template with a set of variables and take the return
value as string.
But thats about where similarities end. Jinja2 for example has an extensive filter system, a certain way to do template inheritance, support for reusable blocks (macros)
that can be used from inside templates and also from Python code, uses Unicode for
all operations, supports iterative template rendering, configurable syntax and more.
On the other hand an engine like Genshi is based on XML stream evaluation, template
inheritance by taking the availability of XPath into account and more. Mako on the
other hand treats templates similar to Python modules.
When it comes to connecting a template engine with an application or framework
there is more than just rendering templates. For instance, Flask uses Jinja2s extensive
autoescaping support. Also it provides ways to access macros from Jinja2 templates.
A template abstraction layer that would not take the unique features of the template
engines away is a science on its own and a too large undertaking for a microframework
like Flask.
Furthermore extensions can then easily depend on one template language being
present. You can easily use your own templating language, but an extension could
still depend on Jinja itself.
253
254
CHAPTER 25
HTML/XHTML FAQ
The Flask documentation and example applications are using HTML5. You may notice that in many situations, when end tags are optional they are not used, so that
the HTML is cleaner and faster to load. Because there is much confusion about HTML
and XHTML among developers, this document tries to answer some of the major questions.
XHTML also changed the way JavaScript is used. To properly work with XHTML, programmers have to use the namespaced DOM interface with the XHTML namespace
to query for HTML elements.
256
HTML4.01
<tag/value/ == <tag>value</tag>
XHTML1.1
HTML5
<br/> supported
<script/> supported
should be served as text/html
257
<div class=header>
<h1>Hello HTML5</h1>
<p class=tagline>HTML5 is awesome
</div>
<ul class=nav>
<li><a href=/index>Index</a>
<li><a href=/downloads>Downloads</a>
<li><a href=/about>About</a>
</ul>
<div class=body>
<h2>HTML5 is probably the future</h2>
<p>
There might be some other things around but in terms of
browser vendor support, HTML5 is hard to beat.
<dl>
<dt>Key 1
<dd>Value 1
<dt>Key 2
<dd>Value 2
</dl>
</div>
258
259
260
CHAPTER 26
Security Considerations
Web applications usually face all kinds of security problems and its very hard to get
everything right. Flask tries to solve a few of these things for you, but there are a
couple more you have to take care of yourself.
use the
sending out textfiles from uploaded files. Some browsers are using content-type
guessing based on the first few bytes so users could trick a browser to execute
HTML.
Another thing that is very important are unquoted attributes. While Jinja2 can protect
you from XSS issues by escaping HTML, there is one thing it cannot protect you from:
XSS by attribute injection. To counter this possible attack vector, be sure to always
quote your attributes with either double or single quotes when using Jinja expressions
in them:
<a href="{{ href }}">the text</a>
261
Why is this necessary? Because if you would not be doing that, an attacker could easily
inject custom JavaScript handlers. For example an attacker could inject this piece of
HTML+JavaScript:
onmouseover=alert(document.cookie)
When the user would then move with the mouse over the link, the cookie would be
presented to the user in an alert window. But instead of showing the cookie to the
user, a good attacker might also execute any other JavaScript code. In combination
with CSS injections the attacker might even make the element fill out the entire page
so that the user would just have to have the mouse anywhere on the page to trigger
the attack.
JSON itself is a high-level serialization format, so there is barely anything that could
cause security problems, right? You cant declare recursive structures that could cause
problems and the only thing that could possibly break are very large responses that
can cause some kind of denial of service at the receivers side.
However there is a catch. Due to how browsers work the CSRF issue comes up with
JSON unfortunately. Fortunately there is also a weird part of the JavaScript specification that can be used to solve that problem easily and Flask is kinda doing that for you
by preventing you from doing dangerous stuff. Unfortunately that protection is only
there for jsonify() so you are still at risk when using other ways to generate JSON.
So what is the issue and how to avoid it? The problem are arrays at top-level in JSON.
Imagine you send the following data out in a JSON request. Say thats exporting the
names and email addresses of all your friends for a part of the user interface that is
written in JavaScript. Not very uncommon:
[
{"username": "admin",
"email": "admin@localhost"}
]
And it is doing that of course only as long as you are logged in and only for you. And
it is doing that for all GET requests to a certain URL, say the URL for that request is
http://example.com/api/get_friends.json.
So now what happens if a clever hacker is embedding this to his website and social
engineers a victim to visiting his site:
<script type=text/javascript>
var captured = [];
var oldArray = Array;
function Array() {
var obj = this, id = 0, capture = function(value) {
obj.__defineSetter__(id++, capture);
if (value)
captured.push(value);
};
capture();
}
</script>
<script type=text/javascript
src=http://example.com/api/get_friends.json></script>
<script type=text/javascript>
Array = oldArray;
// now we have all the data in the captured array.
</script>
If you know a bit of JavaScript internals you might know that its possible to patch
constructors and register callbacks for setters. An attacker can use this (like above)
to get all the data you exported in your JSON file. The browser will totally ignore
the application/json mimetype if text/javascript is defined as content type in the
263
script tag and evaluate that as JavaScript. Because top-level array elements are allowed
(albeit useless) and we hooked in our own constructor, after that page loaded the data
from the JSON response is in the captured array.
Because it is a syntax error in JavaScript to have an object literal ({...}) toplevel an
attacker could not just do a request to an external URL with the script tag to load up
the data. So what Flask does is to only allow objects as toplevel elements when using
jsonify(). Make sure to do the same when using an ordinary JSON generate function.
264
CHAPTER 27
Unicode in Flask
Flask, like Jinja2 and Werkzeug, is totally Unicode based when it comes to text. Not
only these libraries, also the majority of web related Python libraries that deal with
text. If you dont know Unicode so far, you should probably read The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode
and Character Sets. This part of the documentation just tries to cover the very basics
so that you have a pleasant experience with Unicode related things.
265
To go from Unicode into a specific charset such as UTF-8 you can use the
unicode.encode() method:
def write_file(filename, contents, charset='utf-8'):
with open(filename, 'w') as f:
f.write(contents.encode(charset))
Notepad++:
1. Go to Settings -> Preferences ...
2. Select the New Document/Default Directory tab
3. Select UTF-8 without BOM as encoding
It is also recommended to use the Unix newline format, you can select it in the
same panel but this is not a requirement.
267
268
CHAPTER 28
Flask, being a microframework, often requires some repetitive steps to get a third party
library working. Because very often these steps could be abstracted to support multiple projects the Flask Extension Registry was created.
If you want to create your own Flask extension for something that does not exist yet,
this guide to extension development will help you get your extension running in no
time and to feel like users would expect your extension to behave.
269
install the development version into their virtualenv without having to download the
library by hand.
Flask extensions must be licensed under a BSD, MIT or more liberal license to be able
to be enlisted in the Flask Extension Registry. Keep in mind that the Flask Extension
Registry is a moderated place and libraries will be reviewed upfront if they behave as
required.
28.2.1 setup.py
The next file that is absolutely required is the setup.py file which is used to install
your Flask extension. The following contents are something you can work with:
"""
Flask-SQLite3
------------This is the description for that library
"""
from setuptools import setup
setup(
name='Flask-SQLite3',
version='1.0',
url='http://example.com/flask-sqlite3/',
license='BSD',
author='Your Name',
author_email='your-email@example.com',
description='Very short description',
long_description=__doc__,
py_modules=['flask_sqlite3'],
# if you would be using a package instead use packages instead
# of py_modules:
# packages=['flask_sqlite3'],
270
zip_safe=False,
include_package_data=True,
platforms='any',
install_requires=[
'Flask'
],
classifiers=[
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development :: Libraries :: Python Modules'
]
)
Thats a lot of code but you can really just copy/paste that from existing extensions
and adapt.
28.2.2 flask_sqlite3.py
Now this is where your extension code goes. But how exactly should such an extension look like? What are the best practices? Continue reading for some insight.
What to use depends on what you have in mind. For the SQLite 3 extension we will
use the class-based approach because it will provide users with an object that handles
opening and closing database connections.
Whats important about classes is that they encourage to be shared around on module level. In that case, the object itself must not under any circumstances store any
application specific state and must be shareable between different application.
272
def connection(self):
ctx = stack.top
if ctx is not None:
if not hasattr(ctx, 'sqlite3_db'):
ctx.sqlite3_db = self.connect()
return ctx.sqlite3_db
You can then use the database from views like this:
@app.route('/')
def show_all():
cur = db.connection.cursor()
cur.execute(...)
Likewise if you are outside of a request but you are using Flask 0.9 or later with the
app context support, you can use the database in the same way:
273
with app.app_context():
cur = db.connection.cursor()
cur.execute(...)
At the end of the with block the teardown handles will be executed automatically.
Additionally, the init_app method is used to support the factory pattern for creating
apps:
db = Sqlite3()
# Then later on.
app = create_app('the-config.cfg')
db.init_app(app)
Keep in mind that supporting this factory pattern for creating apps is required for
approved flask extensions (described below).
Note on init_app
As you noticed, init_app does not assign app to self. This is intentional! Class based
Flask extensions must only store the application on the object when the application
was passed to the constructor. This tells the extension: I am not interested in using
multiple applications.
When the extension needs to find the current application and it does not have a reference to it, it must either use the current_app context local or change the API in a way
that you can pass the application explicitly.
274
def close_connection(response):
ctx = _request_ctx_stack.top
ctx.sqlite3_db.close()
return response
if hasattr(app, 'teardown_request'):
app.teardown_request(close_connection)
else:
app.after_request(close_connection)
Strictly speaking the above code is wrong, because teardown functions are passed the
exception and typically dont return anything. However because the return value is
discarded this will just work assuming that the code in between does not touch the
passed parameter.
275
2. It must ship a testing suite that can either be invoked with make test or python
setup.py test. For test suites invoked with make test the extension has to
ensure that all dependencies for the test are installed automatically. If tests are
invoked with python setup.py test, test dependencies can be specified in the
setup.py file. The test suite also has to be part of the distribution.
3. APIs of approved extensions will be checked for the following characteristics:
an approved extension has to support multiple applications running in the
same Python process.
it must be possible to use the factory pattern for creating applications.
4. The license must be BSD/MIT/WTFPL licensed.
5. The naming scheme for official extensions is Flask-ExtensionName or
ExtensionName-Flask.
6. Approved extensions must define all their dependencies in the setup.py file unless a dependency cannot be met because it is not available on PyPI.
7. The extension must have documentation that uses one of the two Flask themes
for Sphinx documentation.
8. The setup.py description (and thus the PyPI description) has to link to the documentation, website (if there is one) and there must be a link to automatically
install the development version (PackageName==dev).
9. The zip_safe flag in the setup script must be set to False, even if the extension
would be safe for zipping.
10. An extension currently has to support Python 2.6 as well as Python 2.7
276
CHAPTER 29
Pocoo Styleguide
The Pocoo styleguide is the styleguide for all Pocoo Projects, including Flask. This
styleguide is a requirement for Patches to Flask and a recommendation for Flask extensions.
In general the Pocoo Styleguide closely follows PEP 8 with some small differences and
extensions.
For lists or tuples with many items, break immediately after the opening brace:
277
items = [
'this is the first', 'set of items', 'with more items',
'to come in this line', 'like this'
]
Blank lines: Top level functions and classes are separated by two lines, everything
else by one. Do not use too many blank lines to separate logical segments in
code. Example:
def hello(name):
print 'Hello %s!' % name
def goodbye(name):
print 'See you %s.' % name
class MyClass(object):
"""This is a simple docstring"""
def __init__(self, name):
self.name = name
def get_annoying_name(self):
return self.name.upper() + '!!!!111'
-1.05
= (item_value / item_count) * offset / exp
= my_list[index]
= my_dict['key']
Bad:
exp = value =
value =
value=(
value =
value =
278
1.05
( item_value / item_count ) * offset / exp
(item_value/item_count)*offset/exp
item_value/item_count ) * offset/exp
my_list[ index ]
my_dict ['key']
Yoda statements are a no-go: Never compare constant with variable, always variable
with constant:
Good:
if method == 'md5':
pass
Bad:
if 'md5' == method:
pass
Comparisons:
against arbitrary types: == and !=
against singletons with is and is not (eg: foo is not None)
never compare something with True or False (for example never do foo ==
False, do not foo instead)
Negated containment checks: use foo not in bar instead of not foo in bar
Instance checks: isinstance(a, C) instead of type(A) is C, but try to avoid instance
checks in general. Check for features.
29.4 Docstrings
Docstring conventions: All docstrings are formatted with reStructuredText as understood by Sphinx. Depending on the number of lines in the docstring, they are
laid out differently. If its just one line, the closing triple quote is on the same line
as the opening, otherwise the text is on the same line as the opening quote and
the triple quote that closes the string on its own line:
def foo():
"""This is a simple docstring"""
def bar():
"""This is a longer docstring with so much information in there
that it spans three lines. In this case the closing triple quote
is on its own line.
"""
Module header: The module header consists of an utf-8 encoding declaration (if non
ASCII letters are used, but it is recommended all the time) and a standard docstring:
# -*- coding: utf-8 -*"""
package.module
~~~~~~~~~~~~~~
A brief description goes here.
"""
Please keep in mind that proper copyrights and license files are a requirement
for approved Flask extensions.
29.5 Comments
Rules for comments are similar to docstrings. Both are formatted with reStructuredText. If a comment is used to document an attribute, put a colon after the opening
pound sign (#):
class User(object):
#: the name of the user as unicode string
name = Column(String)
#: the sha1 hash of the password + inline salt
pw_hash = Column(String)
280
CHAPTER 30
Python 3 Support
Flask and all of its dependencies support Python 3 so you can in theory start working
on it already. There are however a few things you should be aware of before you start
using Python 3 for your next project.
If you want to use Flask with Python 3 you will need to use Python 3.3 or higher. 3.2
and older are not supported.
In addition to that you need to use the latest and greatest versions of itsdangerous,
Jinja2 and Werkzeug. Flask 0.10 and Werkzeug 0.9 were the first versions to introduce
Python 3 support.
Some of the decisions made in regards to unicode and byte utilization on Python 3
make it hard to write low level code. This mainly affects WSGI middlewares and interacting with the WSGI provided information. Werkzeug wraps all that information
in high-level helpers but some of those were specifically added for the Python 3 support and are quite new.
Unless you require absolute compatibility, you should be fine with Python 3 nowadays. Most libraries and Flask extensions have been ported by now and using Flask
with Python 3 is generally a smooth ride. However, keep in mind that most libraries
(including Werkzeug and Flask) might not quite as stable on Python 3 yet. You might
therefore sometimes run into bugs that are usually encoding-related.
The majority of the upgrade pain is in the lower-level libraries like Flask and Werkzeug
and not in the actual high-level application code. For instance all of the Flask examples
that are in the Flask repository work out of the box on both 2.x and 3.x and did not
require a single line of code changed.
281
282
CHAPTER 31
Flask itself is changing like any software is changing over time. Most of the changes
are the nice kind, the kind where you dont have to change anything in your code to
profit from a new release.
However every once in a while there are changes that do require some changes in
your code or there are changes that make it possible for you to improve your own
code quality by taking advantage of new features in Flask.
This section of the documentation enumerates all the changes in Flask from release to
release and how you can change your code to have a painless updating experience.
If you want to use the easy_install command to upgrade your Flask installation,
make sure to pass it the -U parameter:
$ easy_install -U Flask
283
the intended behavior of registering handlers only using exception classes and HTTP
error codes.
Trying to register a handler on an instance now raises ValueError.
If you maintain an extension that was using _request_ctx_stack before, please consider changing to _app_ctx_stack if it makes sense for your extension. For instance,
the app context stack makes sense for extensions which connect to databases. Using
the app context stack instead of the request context stack will make extensions more
readily handle use cases outside of requests.
284
285
5. If you were using per-module template folders you need to move some templates
around. Previously if you had a folder named templates next to a blueprint
named admin the implicit template path automatically was admin/index.html for
a template file called templates/index.html. This no longer is the case. Now you
need to name the template templates/admin/index.html. The tool will not detect
this so you will have to do that on your own.
Please note that deprecation warnings are disabled by default starting with Python 2.7.
In order to see the deprecation warnings that might be emitted you have to enabled
them with the warnings module.
If you are working with windows and you lack the patch command line utility you can
get it as part of various Unix runtime environments for windows including cygwin,
msysgit or ming32. Also source control systems like svn, hg or git have builtin support
for applying unified diffs as generated by the tool. Check the manual of your version
control system for more information.
New code:
return send_file(my_file_object, add_etags=False)
happen whereas previously it might have been called twice to ensure it is executed at
the end of the request.
If you have database connection code that looks like this:
@app.after_request
def after_request(response):
g.db.close()
return response
On the upside this change greatly improves the internal code flow and makes it easier
to customize the dispatching and error handling. This makes it now a lot easier to
write unit tests as you can prevent closing down of database connections for a while.
You can take advantage of the fact that the teardown callbacks are called when the response context is removed from the stack so a test can query the database after request
handling:
with app.test_client() as client:
resp = client.get('/')
# g.db is still bound if there is such a thing
# and here it's gone
Into this:
app.register_error_handler(403, handle_error)
289
app.debug = DEBUG
app.secret_key = SECRET_KEY
You no longer have to do that, instead you can just load a configuration into the config
object. How this works is outlined in Configuration Handling.
290
CHAPTER 32
Flask Changelog
Here you can see the full list of changes between each Flask release.
291
Added flask and the flask.cli module to start the local debug server through
the click CLI system. This is recommended over the old flask.run() method
as it works faster and more reliable due to a different design and also replaces
Flask-Script.
Error handlers that match specific classes are now checked first, thereby
allowing catching exceptions that are subclasses of HTTP exceptions (in
werkzeug.exceptions). This makes it possible for an extension author to create exceptions that will by default result in the HTTP error of their choosing, but
may be caught with a custom error handler if desired.
Added flask.Config.from_mapping().
Flask will now log by default even if debug is disabled. The log format
is now hardcoded but the default log handling can be disabled through the
LOGGER_HANDLER_POLICY configuration key.
Removed deprecated module functionality.
Added the EXPLAIN_TEMPLATE_LOADING config flag which when enabled will instruct Flask to explain how it locates templates. This should help users debug
when the wrong templates are loaded.
Enforce blueprint handling in the order they were registered for template loading.
Ported test suite to py.test.
Deprecated request.json in favour of request.get_json().
Add pretty and compressed separators definitions in jsonify() method. Reduces JSON response size when JSONIFY_PRETTYPRINT_REGULAR=False by
removing unnecessary white space included by default after separators.
JSON responses are now terminated with a newline character, because it is a convention that UNIX text files end with a newline
and some clients dont deal well when this newline is missing.
See
https://github.com/mitsuhiko/flask/pull/1262 this came up originally
as a part of https://github.com/kennethreitz/httpbin/issues/168
The automatically provided OPTIONS method is now correctly disabled if the user
registered an overriding rule with the lowercase-version options (issue #1288).
flask.json.jsonify now supports the datetime.date type (pull request #1326).
Dont leak exception info of already catched exceptions to context teardown handlers (pull request #1393).
Allow custom Jinja environment subclasses (pull request #1422).
flask.g now has pop() and setdefault methods.
Turn on autoescape for flask.templating.render_template_string by default
(pull request #1515).
292
293
Changed default cookie serialization format from pickle to JSON to limit the
impact an attacker can do if the secret key leaks. See Version 0.10 for more information.
Added template_test methods
template_filter method family.
in
addition
to
the
already
existing
294
Flask will no longer invoke the wrong error handlers if a proxy exception is
passed through.
Added a workaround for chromes cookies in localhost not working as intended
with domain names.
Changed logic for picking defaults for cookie values from sessions to work better
with Google Chrome.
Added message_flashed signal that simplifies flashing testing.
Added support for copying of request contexts for better working with greenlets.
Removed custom JSON HTTP exception subclasses. If you were relying on
them you can reintroduce them again yourself trivially. Using them however
is strongly discouraged as the interface was flawed.
Python requirements changed: requiring Python 2.6 or 2.7 now to prepare for
Python 3.3 port.
Changed how the teardown system is informed about exceptions. This is now
more reliable in case something handles an exception halfway through the error
handling process.
Request context preservation in debug mode now keeps the exception information around which means that teardown handlers are able to distinguish error
from success cases.
Added the JSONIFY_PRETTYPRINT_REGULAR configuration variable.
Flask now orders JSON keys by default to not trash HTTP caches due to different
hash seeds between different workers.
Added appcontext_pushed and appcontext_popped signals.
The builtin run method now takes the SERVER_NAME into account when picking
the default port to run on.
Added flask.request.get_json() as a replacement for the old flask.request.json property.
295
296
Changed the behavior of tuple return values from functions. They are no longer
arguments to the response object, they now have a defined meaning.
Added flask.Flask.request_globals_class to allow a specific class to be used
on creation of the g instance of each request.
Added required_methods attribute to view functions to force-add methods on registration.
Added flask.after_this_request().
Added flask.stream_with_context() and the ability to push contexts multiple
times without producing unexpected behavior.
297
Applications now not only have a root path where the resources and modules are
located but also an instance path which is the designated place to drop files that
are modified at runtime (uploads etc.). Also this is conceptionally only instance
depending and outside version control so its the perfect place to put configuration files etc. For more information see Instance Folders.
Added the APPLICATION_ROOT configuration variable.
Implemented session_transaction() to easily modify sessions from the test environment.
Refactored test client internally. The APPLICATION_ROOT configuration variable as
well as SERVER_NAME are now properly used by the test client as defaults.
Added flask.views.View.decorators to support simpler decorating of pluggable (class-based) views.
Fixed an issue where the test client if used with the with statement did not
trigger the execution of the teardown handlers.
Added finer control over the session cookie parameters.
HEAD requests to a method view now automatically dispatch to the get method
if no handler was implemented.
Implemented the virtual flask.ext package to import extensions from.
The context preservation on exceptions is now an integral component of Flask
itself and no longer of the test client. This cleaned up some internal logic and
lowers the odds of runaway request contexts in unittests.
299
Dont modify the session on flask.get_flashed_messages() if there are no messages in the session.
before_request handlers are now able to abort requests with errors.
it is not possible to define user exception handlers. That way you can provide
custom error messages from a central hub for certain errors that might occur during request processing (for instance database connection errors, timeouts from
remote resources etc.).
Blueprints can provide blueprint specific error handlers.
Implemented generic Pluggable Views (class-based views).
301
the request context is now available within the with statement making it possible
to further push the request context or pop it.
added support for configurations.
303
304
CHAPTER 33
License
Flask is licensed under a three clause BSD License. It basically means: do whatever
you want with it as long as the copyright in Flask sticks around, the conditions are not
modified and the disclaimer is present. Furthermore you must not use the names of
the authors to promote derivatives of the software without written consent.
The full license text can be found below (Flask License). For the documentation and
artwork different licenses apply.
33.1 Authors
Flask is written and maintained by Armin Ronacher and various contributors:
305
Georg Brandl
Justin Quick
Kenneth Reitz
Keyan Pishdadian
Marian Sigler
Martijn Pieters
Matt Campell
Matthew Frazier
Michael van Tellingen
Ron DuPlain
Sebastien Estienne
Simon Sapin
Stephane Wirtel
Thomas Schranz
Zhao Xiaohong
David Lord @davidism
306
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
The names of the contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
307
308
Index
Symbols
before_app_request()
(flask.Blueprint data (flask.Response attribute), 215
method), 209
debug (flask.cli.ScriptInfo attribute), 247
before_first_request()
(flask.Flask debug (flask.Flask attribute), 190
method), 189
decorators (flask.views.View attribute),
before_first_request_funcs (flask.Flask at242
default()
(flask.json.JSONEncoder
tribute), 189
before_request() (flask.Blueprint method),
method), 231
209
default_config (flask.Flask attribute), 191
before_request() (flask.Flask method), 189 digest_method()
before_request_funcs (flask.Flask at(flask.sessions.SecureCookieSessionInterface
tribute), 189
static method), 218
Blueprint (class in flask), 207
dispatch_request() (flask.Flask method),
blueprint (flask.blueprints.BlueprintSetupState
191
attribute), 238
dispatch_request()
(flask.views.View
blueprint (flask.Request attribute), 213
method), 242
blueprints (flask.Flask attribute), 189
do_teardown_appcontext() (flask.Flask
BlueprintSetupState
(class
in
method), 191
flask.blueprints), 238
do_teardown_request()
(flask.Flask
method), 191
C
dump() (in module flask.json), 231
dumps() (in module flask.json), 230
cli (flask.Flask attribute), 189
command() (flask.cli.AppGroup method),
E
246
Config (class in flask), 232
endpoint (flask.Request attribute), 213
config (flask.Flask attribute), 190
endpoint() (flask.Blueprint method), 209
config_class (flask.Flask attribute), 190
endpoint() (flask.Flask method), 191
context_processor()
(flask.Blueprint environ (flask.Request attribute), 212
method), 209
environment variable
context_processor() (flask.Flask method),
FLASKR_SETTINGS, 32
190
error_handler_spec (flask.Flask attribute),
cookies (flask.Request attribute), 212
191
copy() (flask.ctx.RequestContext method), errorhandler() (flask.Blueprint method),
236
209
copy_current_request_context() (in mod- errorhandler() (flask.Flask method), 192
ule flask), 221
escape() (flask.Markup class method), 228
create_app (flask.cli.ScriptInfo attribute), escape() (in module flask), 227
247
extensions (flask.Flask attribute), 192
create_global_jinja_loader() (flask.Flask
F
method), 190
create_jinja_environment()
(flask.Flask files (flask.Request attribute), 212
first_registration
method), 190
(flask.blueprints.BlueprintSetupState
create_url_adapter() (flask.Flask method),
attribute), 238
190
flash()
(in
module flask), 228
current_app (in module flask), 221
Flask (class in flask), 185
D
flask (module), 185
flask.ext (in module flask), 235
data (flask.cli.ScriptInfo attribute), 247
flask.json (module), 229
data (flask.Request attribute), 212
310
G
g (in module flask), 220
get_cookie_domain()
(flask.sessions.SessionInterface
method), 217
get_cookie_httponly()
(flask.sessions.SessionInterface
method), 217
get_cookie_path()
(flask.sessions.SessionInterface
method), 217
get_cookie_secure()
(flask.sessions.SessionInterface
method), 217
get_expiration_time()
(flask.sessions.SessionInterface
method), 217
get_flashed_messages() (in module flask),
228
get_json() (flask.Request method), 213
get_namespace() (flask.Config method),
234
get_send_file_max_age() (flask.Blueprint
method), 209
get_send_file_max_age()
(flask.Flask
method), 193
get_template_attribute()
(in
module
flask), 232
got_first_request (flask.Flask attribute),
193
got_request_exception (in module flask),
239
group() (flask.cli.AppGroup method), 246
H
handle_exception() (flask.Flask method),
193
handle_http_exception()
(flask.Flask
method), 193
handle_url_build_error()
(flask.Flask
method), 193
handle_user_exception()
(flask.Flask
method), 193
has_app_context() (in module flask), 222
has_request_context() (in module flask),
221
has_static_folder (flask.Blueprint attribute), 210
has_static_folder (flask.Flask attribute),
194
headers (flask.Request attribute), 212
headers (flask.Response attribute), 215
I
init_jinja_globals() (flask.Flask method),
194
inject_url_defaults() (flask.Flask method),
194
instance_path (flask.Flask attribute), 194
is_json (flask.Request attribute), 214
is_null_session()
(flask.sessions.SessionInterface
method), 217
is_xhr (flask.Request attribute), 213
iter_blueprints() (flask.Flask method), 194
J
jinja_env (flask.Flask attribute), 194
jinja_environment (flask.Flask attribute),
194
jinja_loader (flask.Blueprint attribute),
210
jinja_loader (flask.Flask attribute), 194
jinja_options (flask.Flask attribute), 194
json (flask.Request attribute), 214
json_decoder (flask.Flask attribute), 194
json_encoder (flask.Flask attribute), 195
JSONDecoder (class in flask.json), 231
JSONEncoder (class in flask.json), 231
jsonify() (in module flask.json), 230
311
push()
method), 218
U
signal()
(flask.signals.Namespace unescape() (flask.Markup method), 228
method), 241
update_template_context()
(flask.Flask
signals.Namespace (class in flask), 241
method), 205
signals.signals_available (in module url (flask.Request attribute), 213
flask), 238
url_build_error_handlers (flask.Flask atstatic_folder (flask.Blueprint attribute),
tribute), 205
211
url_default_functions (flask.Flask atstatic_folder (flask.Flask attribute), 201
tribute), 205
status (flask.Response attribute), 215
url_defaults (flask.blueprints.BlueprintSetupState
status_code (flask.Response attribute),
attribute), 238
215
url_defaults() (flask.Blueprint method),
stream (flask.Request attribute), 212
211
stream_with_context() (in module flask), url_defaults() (flask.Flask method), 205
235
url_for() (in module flask), 222
striptags() (flask.Markup method), 228
url_map (flask.Flask attribute), 206
subdomain (flask.blueprints.BlueprintSetupState
url_prefix (flask.blueprints.BlueprintSetupState
attribute), 238
attribute), 238
url_root (flask.Request attribute), 213
T
url_rule (flask.Request attribute), 214
teardown_app_request() (flask.Blueprint url_rule_class (flask.Flask attribute), 206
method), 211
url_value_preprocessor() (flask.Blueprint
teardown_appcontext()
(flask.Flask
method), 211
method), 201
url_value_preprocessor()
(flask.Flask
teardown_appcontext_funcs (flask.Flask
method), 206
attribute), 202
url_value_preprocessors (flask.Flask atteardown_request()
(flask.Blueprint
tribute), 206
method), 211
use_x_sendfile (flask.Flask attribute), 206
teardown_request() (flask.Flask method),
202
V
teardown_request_funcs (flask.Flask at- values (flask.Request attribute), 212
tribute), 202
View (class in flask.views), 242
template_context_processors (flask.Flask view_args (flask.Request attribute), 214
attribute), 202
view_functions (flask.Flask attribute), 206
template_filter() (flask.Flask method), 203
template_global() (flask.Flask method), W
203
with_appcontext() (in module flask.cli),
template_rendered (in module flask), 238
247
template_test() (flask.Flask method), 203 wsgi_app() (flask.Flask method), 206
test_client() (flask.Flask method), 203
test_client_class (flask.Flask attribute),
204
test_request_context()
(flask.Flask
method), 204
testing (flask.Flask attribute), 204
trap_http_exception()
(flask.Flask
method), 205
314