Flask Tutorial For Beginners 2020. Here Coding compiler sharing a Flask Quick Start Tutorial for beginners. Flask is a lightweight web application framework. The WSGI toolkit uses Werkzeug and the template engine uses Jinja2. Let’s start learning Flask.
Flask Tutorial For Beginners – Quick Start
This article provides a good introduction to Flask.
Flask Tutorial For Beginners |
|
A minimal application | Request object |
Debug mode | File Upload |
routing | Cookies |
Variable rules | Redirection and errors |
Build URL | About response |
HTTP method | Conversation |
Static files | Flashing message |
Rendering template | Logs |
Receive request data | Integrate WSGI middleware |
Local context | Conclusion |
Flask Tutorial – A minimum application
A minimal application looks like this:
From flask import Flask
app = Flask ( __name__ )
@app.route ( '/' )
def hello_world ():
return 'Hello World!'
If __name__ == '__main__' :
app . run ()
Save it as hello.py (or a similar file) and run it with the Python interpreter. Make sure your application is not called flask.py, because of this conflicts with Flask itself.
$ python hello.py
* Running on https://127.0.0.1:5000/
Now browse https://127.0.0.1:5000/ and you will see your Hello World greeting.
So what did this piece of code do?
- First we imported the class
Flask
. The instantiation of this class will be our WSGI application. The first parameter is the name of the application module. If you are using a single module (as in this example), the first parameter should use __name__ . - Because it depends on if it is started as a separate application or imported as a module, the name will be different (
'__main__'
corresponding to the actual imported name). For more information, please readFlask
the document. - Next, we create an instance of this class. We pass it the name of the module or package. This way Flask will know where to look for templates, static files, and so on.
- We use the decorator
route()
to tell Flask what URL to trigger our function. - Define a function that is also used to generate URLs for a particular function and return information that we want to display on the user’s browser.
- Finally, we use the function
run()
to start a local server to run our application. Make sure that the server will only run when the script is executed directly by the Python interpreter, not when imported as a module.if __name__ =='__main__':
Press Control-C to stop the server.
Externally visible server
When you run the server, you will notice that it can only be accessed from your own computer, and it cannot be accessed anywhere else on the network. This is because, by default, in debug mode, a user in the application can execute arbitrary Python code on your computer.
If you turn off debug or trust your users on your network, you can make your server available outside, simply changing the method run()
calls like this are as follows:
App . run ( host = '0.0.0.0' )
This lets your operating system listen to all public IPs.
Flask Tutorial – Debug Mode
run()
The method is very suitable for starting a local development server, but you need to restart the server manually after modifying the code. This is not a good thing. Flask can do better. If debugging support is enabled, the server will automatically load when the code is modified, and it will provide a useful debugger if an error occurs.
There are two ways to turn on the tuning mode. One is to set the flag on the application object:
App . debug = True
app . run ()
Or passed as a parameter to run:
App . run ( debug = True )
The effect of the two methods is the same.
Attention
Although the interactive debugger cannot work in a forking environment (which makes it almost impossible to use on a production server), it still allows execution of arbitrary code. This makes it a huge security risk, so it must not be used to generate environment.
Screenshot of the running debugger:
Routing
Modern Web applications have elegant URLs. This helps people remember URLs, which is useful for applications that use slow-networking mobile devices. If the user does not have to directly access the desired page by clicking on the home page, it is likely that they will like this page and visit again the next time.
As mentioned above, route()
decorators are 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'
But not only that! You can construct a specific part of a URL dynamically, or you can attach multiple rules to a function.
Variable rules
In order to add the variable part of the URL, you need to mark some specific fields <variable_name>
. These specific fields will be passed as arguments to your function. Of course, you can also specify an optional converter pass rule <converter:variable_name>
. Here are some good examples:
@app.route ( '/user/<username>' )
def show_user_profile ( username ):
# show the user profile for that user
return 'User %s ' % username
@app.route ( '/post/<int:post_id>' )
def show_post ( post_id ):
# show the post with the given id, the id is an integer
return 'Post %d ' % post_id
There are the following converters:
Int | Accept the integer |
Float | Same as int but accepts floating point |
Path | Similar to the default, but also accepts slashes |
Unique URLs / redirect behavior
Flask’s URL rules are based on Werkzeug’s routing module. The idea behind this module is to set precedence based on Apache and earlier HTTP servers to ensure elegant and unique URLs.
Take these two rules as an example:
@app.route ( '/projects/' )
def projects ():
return 'The project page'
@app.route ( '/about' )
def about ():
return 'The about page'
Although they do look similar, the use of their trailing slashes is different in the URL definition. In the first case, the canonical URL points to the end of projects with a slash. This feels a lot like folders in the file system. Accessing a URL without a trailing slash is redirected by Flask to a canonical URL with slashes.
However, in the second case, the URL ends with no slash, similar to the pathname of a file under a UNIX-like system. Accessing a trailing slashed URL results in a 404 “Not Found” error.
When the user forgets to end the slash when accessing the page, this behavior allows the associated URL to continue working and is consistent with the behavior of Apache and other servers. In addition, the URL will remain unique, helping to prevent search engines from indexing the same page twice.
Build URL
If it can match URLs, can Flask generate them? Of course, Flask can do it. You can use the function url_for()
to construct a URL for a particular function. It can accept the function name as the first parameter, as well as some keyword parameters. Each keyword parameter corresponds to the variable part of the URL rule. The unknown variable part is inserted into the URL as a query parameter. Here are some examples:
>>> from flask import Flask , url_for
>>> app = Flask ( __name__ )
>>> @app.route ( '/' )
... def index (): pass
...
>>> @app.route ( '/login' )
... def login (): pass
...
>>> @app.route ( '/user/<username>' )
... def profile ( username ): pass
...
>>> with app . test_request_context ():
... print url_for ( 'index' )
... print url_for ( 'login' )
... print url_for ( 'login' , next = '/' )
... print Url_for ( 'profile' , username = 'John Doe' )
...
/
/login
/login?next=/
/user/John%20Doe
(There is also the use of test_request_context()
the method, the following explanation is given. This method tells Flask to behave like dealing with a request, even though we are. Look at the following interactive Python shell by explanation. Local context ).
Why are you willing to build URLs instead of hardcoding in templates? Here are three good reasons:
- Reverse-building is usually more descriptive than hard-coding. More importantly, it allows you to modify URLs at once, instead of looking for URL changes everywhere.
- The build URL can handle special characters and Unicode escapes explicitly, so you don’t have to deal with them.
- If your application is not in the URL root directory (for example, in
/myapplication
not in/
),url_for()
it will properly handle for you.
HTTP method
HTTP (also known as web application protocol) has different ways to access URLs. By default, only the routing response GET request, but able to route()
provides decorator methods to change the parameters. Here are some examples:
@app.route ( '/login' , methods = [ 'GET' , 'POST' ])
def login ():
if request . method == 'POST' :
do_the_login ()
else :
show_the_login_form ()
If you use the GET method, the HEAD method will be added automatically. You don’t have to deal with them. It also ensures that HEAD requests are handled according to the HTTP RFC (documents described in the HTTP protocol) requirements, so you can completely ignore this part of the HTTP specification. Similarly, OPTIONS can automatically handle it for you since Flask 0.6 .
Maybe you are not clear about the HTTP method? Don’t worry, here’s a quick start for HTTP methods and why they are important:
HTTP method (also commonly referred to as “verb”) tells the server that the client wants a page request to do anything. The following methods are more common:
- GET
- Browser notifies the server only to obtain information on the page and send it back. This may be the most common method.
- HEAD
- Browser tells the server to get information, but only the header information of interest, do not need the entire page content. The application should process it like it receives a GET request but does not pass the actual content. In Flask you don’t need to deal with it at all. The underlying Werkzeug library will handle it for you.
- POST
- It is to inform the server browser in the URL to submit some of the information, the server must ensure that data is stored and stored only once. This is how HTML forms typically send data to the server.
- PUT
- Similar to POST , but the server may trigger multiple stored procedures, overwriting old values multiple times. Now you will ask what is the use of this. There are many reasons for doing so. Consider losing the connection during the transmission: in this case the system between the browser and the server may safely receive the request a second time without breaking anything else. This is not possible for POSTbecause it will only be triggered once.
- DELETE
- Remove information for a given location.
- OPTIONS
- Give the client a quick way to indicate which HTTP methods this URL supports. Starting from Flask 0.6, it is automatically implemented.
Now more interesting is that in HTML4 and XHTML1, forms can only be submitted to the server using the GET and POST methods. Other methods can also be used in JavaScript and later HTML standards. At the same time, HTTP has become very popular recently, and browsers are no longer the only clients that use HTTP. For example, many version control systems use HTTP.
Static files
Dynamic web applications also require static files. CSS and JavaScript files usually come from this. Ideally, your web server is already configured to serve them, but Flask can do it during development. Simply create a folder named static in your package or next to the module, and use /static in your application to access it.
To generate static files URL, use a special 'static'
endpoint name:
Url_for ( 'static' , filename = 'style.css' )
This file should be stored on the file system called.static/style.css
Rendering template
Generating HTML in Python is not fun, and it’s actually quite cumbersome because you have to make HTML escape yourself to keep your application safe. For this reason, Flask automatically configures the Jinja2 template for you.
You can use the method render_template()
to render the template. All you need to do is provide the name of the template and the variables you want to pass into the template as keyword arguments. Here is a simple example of rendering a template:
From flask import render_template
@app.route ( '/hello/' )
@app.route ( '/hello/<name>' )
def hello ( name = None ):
return render_template ( 'hello.html' , name = name )
Flask will look for templates in the templates folder. So if your application is a module, this folder is next to the module. If it is a package, then this folder is in your package:
Case 1 : One module:
/application.py
/templates
/hello.html
Case 2 : A package:
/application
/__init__.py
/templates
/hello.html
For templates, you can use the full functionality of the Jinja2 template. See the official Jinja2 Template Documentation for details.
Here is an example of a template:
<!doctype html>
<title> Hello from Flask </title>
{% if name %}
<h1> Hello {{ name }} ! </h1>
{% else %}
<h1> Hello World! </h1>
{% endif %}
You can also use templates,request
session
and objects, as well as functions.g
get_flashed_messages()
Template inheritance is very useful. If you want to know how to work the inherited template, please read the document template inheritance. Basic template inheritance makes certain specific elements (such as titles, navigation, and footers) possible on each page.
Auto-escaping is turned on, so if the name contains HTML, it will be automatically escaped. If you trust a variable, and you know it is secure (for example, a module to convert wiki markup to HTML), you can use Markup
the class or |safe
filter tags it is safe in the template. In the Jinja 2 document, you will see more examples.
This is a Markup
basic introduction to what type of work:
>>> 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: Auto-escaping is no longer enabled in all templates. The following template file with the extension triggers an automatic escape: .html
, .htm
,.xml
, .xhtml
. A template loaded from a string disables automatic escaping.
Receiving a request data
For web applications, it is important to respond to the data sent from the client to the server. In Flask by the global object request
to provide such information. If you have some Python experience, you will wonder how this object may be global, and how Flask can also guarantee thread safety. The answer is the context scope:
Local context
Insider information
If you want to understand how it works and how to use it for testing, read this section, otherwise skip this section.
Some objects in Flask are global objects, but not the usual types. These objects are actually agents of the local object of a given context. Although it is a mouthful, it is actually easy to understand.
Imagine the thread processing context. When a request comes in, the web server decides to spawn a new thread (or something else; the underlying object is more capable of handling concurrent systems than threads).
When Flask starts its internal request processing, it determines that the current thread is the active context and binds the current application and WSGI environment to that context (thread). It is implemented in an intelligent way so that one application can call another application without interruption.
So what does this mean to you? If you are doing something like unit testing, otherwise you can basically ignore this situation. You will find that the code that depends on the request object suddenly breaks because there is no request object. The solution is to create a request yourself and bind it to the context.
For the first unit, the test solution is to use test_request_context()
context managers. In conjunction with the statement, it will bind a test request to interact. Here is an example:
From flask import request
With app . test_request_context ( '/hello' , method = 'POST' ):
# now you can do something with the request until the
# end of the with block, such as basic assertions:
assert request . path == '/hello'
Assert request . method == 'POST'
Another possibility is to pass the entire WSGI environment request_context()
Method:
From flask import request
With app . request_context ( environ ):
assert request . method == 'POST'
Request object
The request object is described in the API section, and we will not discuss it in detail here (please see request
). Here’s an overview of some of the most common operations. First, you need to import it from the flask module:
From flask import request
The method of the current request can be method
property to access. You can use the form
property to access the form data (data in the POST or PUT transmission). Here is a complete 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 this is executed if the request method
# was GET or the credentials were invalid
return render_template ( 'login.html' , error = error )
What happens if the above key value does not exist in the form attribute? In this case triggers a special one KeyError
. You can capture standard as KeyError
to capture it, if you do not do so, it will display a HTTP 400 Bad Request error page. So in many cases you don’t need to deal with this problem.
You can use the args
property to receive (the URL ?key=value
parameter) submitted:
Searchword = request . args . get ( 'key' , '' )
We recommend using get to access URL parameters or capture KeyError , because users may modify the URL and show them a 400 bad request page is not user friendly.
I want to get a complete list of the request object methods and properties, see request
the documentation.
File upload
You can easily handle file uploads with Flask. Just make sure you don’t forget to set the properties in your HTML form enctype="multipart/form-data"
, otherwise the browser will not send the file.
The uploaded file is stored in a temporary location in memory or on the file system. You can request object files
property access these files. Each uploaded file is stored in this attribute dictionary. It behaves like a standard Python file
objects, but it also has asave()
method that allows you to store files on the server’s file system. Here is a simple example showing how to work:
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 before you upload it to your application in the file name of the client, you can access the filename
property. But remember to never trust this value, because this value can be forged. If you want to use the file name of the client to store files on the server, pass it to Werkzeug available to your secure_filename()
function:
From flask import request
from werkzeug 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 ))
...
Some better examples, see upload files.
Flask – Redirection and error
You can use redirect()
the function to redirect users elsewhere. It can be used abort()
in advance function and an interrupt request with an error code. Here is an example of how they work:
From flask import abort , redirect , url_for
@app.route ( '/' )
def index ():
return redirect ( url_for ( 'login' ))
@app.route ( '/login' )
def login ():
abort ( 401 )
this_is_never_executed ()
This is a rather pointless example because the user will be redirected from the home page to an inaccessible page (401 means no access), but it shows how the redirection works.
By default, each error code displays a black and white error page. If you want to customize error pages, 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
Notice 404
is render_template()
after the call. Tell Flask that the error code for this page should be 404, ie not found. The default 200 is assumed to be: Everything is OK.
About response
The return value of a view function is automatically converted to a response object. If the return value is a string, it is converted into a string of the subject is a response with the error code, the media type of the response object. Flask converts the return value into the response object’s logic as follows:200 OK
text/html
- If it returns a valid response object, it will be returned directly from the view.
- If a string is returned, the response object is created with string data and default parameters.
- If you return a tuple and the elements in the tuple provide additional information. Such tuple must form and contain at least one element. The status value will override the status code, headers can be a list or an additional header value dictionary.
(response, status, headers)
- If none of the above conditions are met, Flask assumes that the return value is a valid WSGI application and converts it to a request object.
If you want to get the response object you get in the view, you can use functionmake_response()
Imagine you have a view like this:
@app.errorhandler ( 404 )
def not_found ( error ):
return render_template ( 'error.html' ), 404
You only need to make_response()
package the return expression, get the results and modify the object, and 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
Session
In addition to the request object, there is referred to a second session
object allows you to store requests between different user-specific information. This is based on cookies and uses encrypted signatures in cookies. This means that the user can view the contents of the cookie but cannot modify it unless it knows the key of the signature.
To use the session, you need to set a key. Here’s how the session works:
From flask import Flask , session , redirect , url_for , escape , request
App = Flask ( __name__ )
@app.route ( '/' )
def index ():
if 'username' in session :
return 'Logged in as %s ' % escape ( session [ 'username' ])
return 'You are not logged in'
@app.route ( '/login' , methods = [ 'GET' , 'POST' ])
def login ():
if request . method == 'POST' :
session [ 'username' ] = request . form [ 'username ' ]
return redirect ( url_for ( 'index' ))
return '''
<form action="" method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route ( '/logout' )
def logout ():
# remove the username from the session if it's there
session . pop ( 'username' , None )
return redirect ( url_for ( 'index' ))
# set the secret key. keep this really secret:
app . secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
It mentioned herein escape()
may be escaped (as in this case) when you are not using a template engine.
How to generate a good key
The random problem is that it is difficult to determine what is truly random. A key should be random enough. Your operating system can generate a nice random value based on a random password generator. This value can be used as a key:
>>> import os
>>> os . urandom ( 24 )
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\ Xa8'
Copy and paste this value into your code and you’re done with the key.
Note the use of cookie-based sessions: Flask serializes the values you place in the session object into cookies. If you try to find a value that does not persist across requests, cookies are enabled, and you do not get explicit error messages. Check the size of the cookies in your page request and compare them with the size supported by your web browser.
Message flashes
Good apps and user interfaces are all about feedback. If users do not receive enough feedback, they may become annoying about the application. Flask provides a really simple way to give users feedback via the message flash system. The message flashing system basically causes the information to be logged at the end of the request and is accessed in the next (and only next) request. Messages are usually displayed in conjunction with the template layout.
Using the flash()
method to flash a message, use get_flashed_messages()
can be obtained message, get_flashed_messages()
it can also be used in the template. For a complete example please refer to the news flash.
Log
New in version 0.3. Sometimes you will be in a situation where the data you are dealing with should be correct, but in fact, it is not the right situation. For example, you may have some client-side code. The code sends an HTTP request to the server but obviously, it is malformed. This may be due to the user tampering with the data, or the client code failed. Most of the time return for this situation can be but sometimes does not work because the code must continue to work.400 Bad Request
You may still want to record what is happening abnormally. At this time, the log is useful. Log records starting from Flask 0.3 are pre-configured.
Here are some examples of log calls:
App . logger . debug ( 'A value for debugging' )
app . logger . warning ( 'A warning occurred ( %d apples)' , 42 )
app . logger . error ( 'An error occurred' )
WSGI middleware integration
If you want to add WSGI middleware to your application, you can encapsulate internal WSGI applications. For example, if you want to use one of the middleware in the Werkzeug package to handle bugs in Lighttpd, you can do this:
From werkzeug.contrib.fixers import LighttpdCGIRootFix
app . wsgi_app = LighttpdCGIRootFix ( app . wsgi_app )