Heim >Backend-Entwicklung >Python-Tutorial >Verwenden Sie das Flask-Framework von Python, um Ihre erste Webanwendung zu erstellen
1. Initialisierung
In diesem Kapitel lernen Sie die verschiedenen Teile der Flask-Anwendung kennen. Gleichzeitig schreiben Sie Ihre erste Flask-Webanwendung und führen sie aus.
Alle Flask-Anwendungen müssen eine Anwendungsinstanz erstellen. Alle vom Client empfangenen Anfragen werden an dieses Objekt zur Verarbeitung mithilfe des Webserver-Gateway-Schnittstellenprotokolls weitergeleitet. Diese Anwendungsinstanz ist ein Objekt der Flask-Klasse, das normalerweise mit der folgenden Methode erstellt wird:
from flask import Flask app = Flask(__name__)
Der einzigartige Flask-Klassenkonstruktor Der erforderliche Parameter ist das Hauptmodul oder Paket der Anwendung. Für die meisten Anwendungen ist die Python-Variable __name__ der richtige Wert, den Sie übergeben müssen.
Hinweis: Für Flask-Entwickler kann der an den Flask-Anwendungskonstruktor übergebene Namensparameter verwirrend sein. Flask verwendet diesen Parameter, um das Stammverzeichnis der Anwendung zu bestimmen, sodass Ressourcendateien in Zukunft relativ zu diesem Pfad gefunden werden können.
Später können Sie komplexere Anwendungsinstanzinitialisierungen sehen, aber für einfache Anwendungen sind diese ausreichend.
2. Routing- und Ansichtsfunktionen
Clients wie Webbrowser senden Anfragen an den Webdienst und senden sie dann an die Flask-Anwendungsinstanz. Die Anwendungsinstanz muss wissen, welcher Code für jede URL-Anfrage ausgeführt werden muss, daher richtet sie eine Zuordnung von URLs zur Python-Funktion ein. Diese Vorgänge, die Verbindungen zwischen URLs und Funktionen herstellen, werden Routing genannt.
Die bequemste Möglichkeit, Routen in einer Flask-Anwendung zu definieren, besteht darin, die dekorierte Funktion als Route zu registrieren, indem der app.route-Dekorator explizit in der Anwendungsinstanz definiert wird. Das folgende Beispiel zeigt, wie Dekoratoren zum Deklarieren einer Route verwendet werden:
@app.route('/') def index(): return '<h1>Hello World!</h1>'
Hinweis: Dekoratoren sind ein Standard in der Python-Sprache Eigenschaften; sie können das Verhalten einer Funktion auf unterschiedliche Weise ändern. Ein gängiges Muster besteht darin, einen Dekorator zu verwenden, um eine Funktion als Ereignishandler zu registrieren.
Registrieren Sie im vorherigen Beispiel die Funktion index() als Ereignishandler für die Stamm-URL der Anwendung. Wenn diese Anwendung auf dem Server bereitgestellt und an den Domänennamen www.example.com gebunden ist, löst die Eingabe von http://www.php.cn/ in die Adressleiste Ihres Browsers index() aus, um den Dienst auszuführen. Der vom Client empfangene Rückgabewert dieser Funktion wird als Antwort bezeichnet. Wenn der Client ein Webbrowser ist, ist die Antwort das Dokument, das dem Benutzer angezeigt wird.
Funktionen, die index() ähneln, werden Ansichtsfunktionen genannt. Die von der Ansicht zurückgegebene Antwort kann eine einfache Zeichenfolge mit HTML-Inhalt sein, sie kann aber auch eine komplexere Form annehmen, wie Sie sehen werden.
Hinweis: Die Antwortzeichenfolge ist in den Python-Code eingebettet, was die Steuerung des Codes erschwert. Hier stellen wir nur das Konzept der Antwort vor. In Kapitel 3 erfahren Sie, wie Sie Antworten richtig generieren.
Wenn Sie bemerken, wie einige der Website-URLs, die Sie täglich verwenden, aufgebaut sind, werden Sie feststellen, dass es viele Variablen gibt. Die URL Ihrer Facebook-Profilseite lautet beispielsweise http://www.php.cn/;username>, Ihr Benutzername ist also Teil davon. Flask unterstützt diese Art von URLs mithilfe einer speziellen Syntax in Routendekoratoren. Das folgende Beispiel definiert eine Route mit einer dynamisch benannten Komponente:
@app.route('/user/<name>') def user(name): return '<h1>Hello, %s!</h1>' % name
Der in spitze Klammern eingeschlossene Teil ist ein dynamischer Abschnitt, also Alle URLs, die mit dem statischen Abschnitt übereinstimmen, werden dieser Route zugeordnet. Wenn die Ansichtsfunktion aufgerufen wird, sendet Flask die dynamische Komponente als Parameter. In der Ansichtsfunktion des vorherigen Beispiels wird dieser Parameter verwendet, um als Antwort eine personalisierte Begrüßung zu generieren.
Dynamische Komponenten im Routing sind standardmäßig Strings, können aber auch als andere Typen definiert werden. Beispielsweise stimmt die Route /user/
3. Dienststart
Die Anwendungsinstanz verfügt über eine Ausführungsmethode zum Starten des Flask-integrierten Webdienstes:
if __name__ == '__main__': app.run(debug=True)
__name__ == '__main__' wird hier verwendet, um sicherzustellen, dass der Webdienst gestartet wurde, wenn das Skript sofort ausgeführt wird. Wenn ein Skript von einem anderen Skript importiert wird, wird es als übergeordnetes Skript behandelt und startet einen anderen Dienst, sodass der Aufruf von app.run() übersprungen wird.
Sobald der Dienst startet, tritt er in eine Schleife ein und wartet auf Anfragen und bedient diese. Diese Schleife wird fortgesetzt, bis die Anwendung gestoppt wird, beispielsweise durch Drücken von Strg-C.
Es gibt mehrere Optionsparameter, mit denen der Betriebsmodus des Webdienstes für app.run() konfiguriert werden kann. Während der Entwicklung können Sie ganz einfach den Debug-Modus aktivieren, wodurch Debugger und Reloader aktiviert werden. Dies geschieht durch die Übergabe von debug als True.
Hinweis: Die von Flask bereitgestellten Webdienste werden nicht in Produktionsumgebungen verwendet. In Kapitel 17 erfahren Sie mehr über Webdienste in einer Produktionsumgebung.
Eine vollständige Anwendung
Im vorherigen Abschnitt haben Sie die verschiedenen Teile einer Flask-Webanwendung kennengelernt, jetzt ist es an der Zeit, eine zu schreiben. Das gesamte Anwendungsskript hello.py vereint einfach die drei zuvor beschriebenen Teile in einer Datei. Anwendungsbeispiel 2-1 wird gezeigt.
Beispiel hello.py: eine vollständige Flask-Anwendung
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello World!
' if __name__ == '__main__': app.run(debug=True)
建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 2a来切换到这个版本的应用程序。
运行应用程序之前,请确保你在之前创建的虚拟环境已经是激活状态且已安装Flask。现在打开你的web浏览器并在地址栏输入 http://www.php.cn/:5000/ 。下图显示连接到应用程序后的web浏览器。
然后输入以下命令启动应用程序:
(venv) $ python hello.py * Running on http://127.0.0.1:5000/ * Restarting with reloader
如果你输入任何其他URL,应用程序将不知道如何操作它并且将返回错误代码404给浏览器——当你访问一个不存在的网页也会得到该错误。
下面所示应用程序的增强版添加了第二个动态路由。当你访问这个URI,你应该可以看到一个个性的问候。
示例hello.py:带有动态路由的Flask应用程序
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello World!
' @app.route('/user/') def user(name): return ' Hello, %s!
' % name if __name__ == '__main__': app.run(debug=True)
建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 2b来切换到这个版本的应用程序。
测试动态路由,确保服务正在运行随后访问 http://localhost:5000/user/Dave 。生成的应用程序会使用动态参数名响应一个定制的问候。尝试不同的名称,看看视图函数总是生成响应基于给定的名称。
5.1、应用程序Context和请求Context
当Flask从客户端收到一个请求,它需要提供几个可用对象给视图函数处理。request对象是个不错的例子,它封装了客户端发送的HTTP请求。
Flask视图函数访问request对象的最好方式,就是作为一个参数发送它,但这需要每个单一视图函数在应用程序中有一个额外的参数。考虑一下,如果request对象不是唯一一个视图函数需要访问完成请求的对象,事情将会变得更加复杂。
为了避免弄乱视图函数那些可能需要或不需要的参数,Flask使用context来临时确定可访问的全局对象。也多亏了context,视图函数可以写成下面这样:
from flask import request @app.route('/') def index(): user_agent = request.headers.get('User-Agent') return ' <p>Your browser is %s</p> ' % user_agent
注意,在这个视图函数中,request是如何被作为一个全局变量来使用的。现实中,request是不能作为全局变量的,如果是多线程服务器,同一时间线程作用于不同客户端的不同请求,所以每一个线程需要看到request中的不同对象。contexts使得Flask确定可访问的全局变量而不干扰其他线程。
注:线程是可以独立管理的最小指令序列。一个进程中有多个活动的线程是非常常见的,有时分享内存或文件句柄资源。多线程web服务器会启动一个线程池并从池中选择一个线程来处理每个传入的请求。
Flask有两类context:应用级context 和 请求级context。表2-1展示了这些context提供的变量。
Flask激活(或压栈)应用级context和请求级context在调度请求之前,然后删除他们当请求被处理后。当应用程序context被压入栈,线程中current_app和g变量变得可用;同样的,当请求级context被压入栈,request和session变量也同样变得可用。如果这些变量中的任何一个不是由激活的应用级或请求级context访问,会产生错误。在后面的章节会详细讨论四个context变量,所以不要担心你不理解它们的用处。
下面的Python shell会话演示了应用级context是如何工作的:
>>> from hello import app >>> from flask import current_app >>> current_app.name Traceback (most recent call last): ... RuntimeError: working outside of the application context >>> app_ctx = app.app_context() >>> app_ctx.push() >>> current_app.name 'hello' >>> app_ctx.pop()
在这个示例中,当应用级context没有激活,但是却作为有效的context被压入栈中,current_app.name报错。注意在应用程序实例中一个应用级context是如何通过调用app.app_context()来获得的。
5.2、请求调度
当一个应用程序收到客户端的请求,它需要找到响应的视图函数为之服务。对于这个任务,Flask会在应用程序的URL映射中查找请求的URL,该映射包含URLs和操作它们的视图函数。Flask通过app.route装饰器或非装饰器版本app.add_url_rule()来建立这个映射。
看一下Flask应用程序中URL映射是怎样的,你可以在Python shell中检查hello.py创建的映射。测试中,请确保你的虚拟环境是激活状态:
(venv) % python >>> from hello import app >>> app.url_map Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>, <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>, <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])
URL映射中所示的HEAD、OPTIONS、GET元素为request方法,由路由处理。Flask连接方法到每个路由,这样不同的请求方法发送到相同的URL可以被不同的视图函数处理。HEAD和OPTIONS方法由Flask自动管理,所以实际上可以说,在这个应用程序中URL映射的三个路由都连接到GET方法了。在第四章你将学习为路由指定不同的请求方法。
5.3、请求Hooks
有些时候在每个请求处理之前或之后执行代码是非常有用的。例如,在开始每一个请求前可能有必要创建数据库连接,或对用户请求进行验证。为了避免复制处理这些操作的代码到每一个视图函数中,Flask给你选择注册相同函数来调用,在请求被分配给视图函数之前或之后。
请求hooks由装饰器实现。下面是四个Flask支持的hooks:
(1)before_first_request:在第一个请求被处理前注册一个函数运行。
(2)before_request:在每一个请求前注册一个函数运行。
(3)after_request:如果没有未处理的异常发生,在每一个请求后注册一个函数运行。
(4)teardown_request:即使未处理的异常发生,在每一个请求后注册一个函数运行。
在请求hook函数和视图函数之间共享数据的惯用方法就是使用g全局context。例如,before_request处理程序可以从数据库加载已登录的用户并保存在g.user中。之后,当视图函数被调用,可以从那访问用户。
请求hooks的示例会在未来的章节中展示给大家,所以不用担心,
5.4、响应
当Flask调用一个视图函数,并期望它的返回值去响应该请求。大多数的响应是将简单字符串构成的HTML页面发回给客户端。
但是HTTP协议需要比字符串更多的信息作为请求的响应。一个HTTP响应中非常重要的部分是状态码,Flask默认设置200来指示请求已经成功处理。
当视图函数需要用不同的状态码响应,可以在响应文本后添加数字码作为第二个返回值。例如,下面的视图函数返回400错误状态码的请求:
@app.route('/') def index(): return '<h1>Bad Request</h1>', 400
视图函数返回的响应还可以携带第三个参数,添加一个头部字典给HTTP响应。通常很少用到,但是你可以在第十四章看到示例。
除了返回一个、两个或三个值的元组,Flask视图函数可以选择返回response对象。make_response()函数可携带一个、两个或三个参数,和视图函数返回的值一样,并返回一个response对象。有时候在视图函数中执行这个转换是非常有用的,然后使用response对象中的方法进一步配置响应。下面的示例创建response对象并设置cookie:
from flask import make_response @app.route('/') def index(): response = make_response(' <h1>This document carries a cookie!</h1> ') response.set_cookie('answer', '42') return response
有一类特殊的响应称作重定向。这类响应不包含页面文档;只是给浏览器一个新的URL去加载新的页面。重定向通常和web表单一起使用,你将在第四章学习。
重定向通常由302响应状态码注明并且重定向的URL由头部的Location给出。重定向响应可以使用三个值的返回生成,也可通过响应对象生成,但是鉴于它频繁的使用,Flask提供redirect()函数来创建这样的响应:
from flask import redirect @app.route('/') def index(): return redirect('http://www.example.com')
另一个具有中断功能的特殊响应用来错误处理。下面的示例,当URL给出的id动态参数不是一个合法的用户时返回状态码404:
from flask import abort @app.route('/user/<id>') def get_user(id): user = load_user(id) if not user: abort(404) return ' <h1>Hello, %s</h1> ' % user.name
注意终止不是指将控制权返回给调用它的函数,而是指通过抛出异常将控制权返回给web服务。
6、Flask扩展
Flask是可扩展的。它故意腾出地给重要的功能,例如数据库和用户授权,给你自由去选择最适合你的应用程序的包,或写一个自己想要的。
社区开发了非常多的扩展用于各种用途,如果这还不够,可以使用任何Python标准包和库。为了让你了解一个扩展是如何并入一个应用程序的,下面的章节给hello.py添加一个扩展,增加应用程序的命令行参数。
6.1、Flask-Script命令行选项
Flask开发,其web服务器支持一系列的启动配置选项,但是配置它们的唯一方式只有在脚本中传递参数给app.run()并调用。这不是非常的方便,理想方法是通过命令行参数传递配置选项。
Flask-Script是给你的Flask应用程序添加命令行解释的扩展。它打包了一组通用的选项,还支持自定义命令。
使用pip安装扩展:
(venv) $ pip install flask-script
下面展示了在 hello.py 应用程序中添加命令行解释的变化。
示例. hello.py:使用Flask-Script
from flask.ext.script import Manager manager = Manager(app) # ... if __name__ == '__main__': manager.run()
专为Flask开发的扩展暴露在flask.ext命名空间下。Flask-Script从flask.ext.script中导出一个名为Manager的类。
初始化这个扩展的方法和其他许多扩展一样:主类实例的初始化是通过将应用程序实例作为参数传递给构造函数实现的。创建的对象适当的用于每一个扩展。在这个示例中,服务器启动通过manager.run()来路由,且命令行在这被解析。
建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 2c来切换到这个版本的应用程序。
因为这些变化,应用程序获得一组基本的命令行选项。运行hello.py显示可用信息:
$ python hello.py
usage: hello.py [-h] {shell, runserver} ... positional arguments: {shell, runserver} shell 在Flask应用程序上下文的内部运行一个Python Shell。 runserver 运行Flask开发服务器,例如:app.run() optional arguments: -h, --help 显示这个帮助信息并退出
shell命令用于在应用程序上下文中启动一个Python shell会话。你可以使用这个会话去运行维护任务,或测试,或调试错误。
runserver命令,就像它的名称一样,启动web服务。运行python hello.py runserver在调试模式下启动web服务,还有更多的选项:
(venv) $ python hello.py runserver --help usage: hello.py runserver [-h] [-t HOST] [-p PORT] [--threaded] [--processes PROCESSES] [--passthrough-errors] [-d] [-r]
运行Flask开发服务器,例如:app.run()
optional arguments: -h, --help 显示这个帮助信息并退出 -t HOST, --host HOST -p PORT, --port PORT --threaded --processes PROCESSES --passthrough-errors -d, --no-debug -r, --no-reload
--host参数是一个非常有用的选项,因为它能告诉web服务器监听哪个网络接口的客户端连接。默认,Flask开发的web服务器监听localhost的连接,所以只有来自内部计算机运行的服务器可以接收。下面的命令使得web服务器监听公网接口,其他网络上的计算机可以连接:
(venv) $ python hello.py runserver --host 0.0.0.0 * Running on http://0.0.0.0:5000/ * Restarting with reload
现在web服务器应该可以从网络中的任何一台计算机访问 http://a.b.c.d:5000 ,“a.b.c.d”是运行服务的计算机的外部IP地址。
更多用Verwenden Sie das Flask-Framework von Python, um Ihre erste Webanwendung zu erstellen相关文章请关注PHP中文网!