落花流水对《Flask Web Development》的笔记(4)

Flask Web Development
  • 书名: Flask Web Development
  • 作者: Miguel Grinberg
  • 副标题: Developing Web Applications with Python
  • 页数: 225
  • 出版社: O'Reilly Media
  • 出版年: 2014-5-25
  • 第6页
    # 虚拟环境
    #### 使用虚拟环境的好处
    - 避免包的混乱和版本的冲突
    - 不需要管理员权限
    ### 安装
    虚拟环境曾使用第三方实用工具 [virtualenv](https://virtualenv.pypa.io/en/stable/#) 创建,但 Python 3.3 开始通过 [venv模块](https://docs.python.org/3/library/venv.html) 原生支持虚拟环境,可以完全代替 virtualenv 。
    ### 创建和激活
    参见Python 官方文档中 [Virtual Environments and Packages](https://docs.python.org/3/tutorial/venv.html#virtual-environments-and-packages) 和 [venv模块](https://docs.python.org/3/library/venv.html) 的说明。
    #### 在当前目录创建
    `$ pyvenv venv`
    `$ python -m venv venv` (Windows下有效)
    #### 激活
    `$ source venv/bin/activate`
    `$ venv/Scripts/activate`
    #### 使用 pip
    - 安装:
    `$ pip install <package_name>`
    - 特定版本的安装
    `$ pip install <package_name>==<package_version>`
    - 升级
    `$ pip install --upgrade <package_name>`
    - 卸载
    `$ pipuninstall <package_name>`
    - 显示包信息
    `$ pip show <package_name>`
    - 显示所有安装的包
    `$ pip list`
    - 导出所有安装包的信息
    `$ pip freeze > requirements.txt`
    - 安装需求文件中的所有包
    `$ pip install -r requirements.txt`
    #### 关于 [Pycharm](https://www.jetbrains.com/pycharm/)
    若使用Pycharm管理项目,也可以方便地[创建虚拟环境](https://www.jetbrains.com/help/pycharm/2016.1/creating-virtual-environment.html) 。
    若要在 Pycharm 的命令行中直接激活虚拟环境,可参考 stackoverflow 上的[这个问题的答案](http://stackoverflow.com/questions/22288569/how-do-i-activate-a-virtualenv-inside-pycharms-terminal):
    PyCharm 2016.1 or 2016.2:Settings,Tools,Terminal, and add""/K <path-to-your-activate.bat>""toShell path and add (mind the quotes). Also add quotes around cmd.exe, resulting in: `"cmd.exe" /k ""C:\mypath\my-venv\Scripts\activate.bat""`
    2016-10-22 08:39:50 回应
  • 第7页
    #WSGI
    [WSGI](https://wsgi.readthedocs.io/en/latest/)(Web Server Gateway Interface, Web服务器网关接口)
    Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。WSGI是作为Web服务器与Web应用程序或应用框架之间的一种低级别的接口,以提升可移植Web应用开发的共同点。WSGI是基于现存的CGI标准而设计的。 WSGI区分为两个部份:一为“服务器”或“网关”,另一为“应用程序”或“应用框架”。在处理一个WSGI请求时,服务器会为应用程序提供环境资讯及一个回呼函数(Callback Function)。当应用程序完成处理请求后,透过前述的回呼函数,将结果回传给服务器。所谓的 WSGI 中间件同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用:从WSGI服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。“中间件”组件可以执行以下功能: 重写环境变量后,根据目标URL,将请求消息路由到不同的应用对象。 允许在一个进程中同时运行多个应用程序或应用框架。 负载均衡和远程处理,通过在网络上转发请求和响应消息。 进行内容后处理,例如应用XSLT样式表。
    *参考资料*:
    1. [网关协议学习:CGI、FastCGI、WSGI](http://www.biaodianfu.com/cgi-fastcgi-wsgi.html)
    2. [Wsgi研究](http://blog.kenshinx.me/blog/wsgi-research/)
    3. [化整為零的次世代網頁開發標準: WSGI](http://blog.ez2learn.com/2010/01/27/introduction-to-wsgi/)
    ---
    #Flask类
    class flask.Flask(import_name, static_path=None, static_url_path=None, static_folder='static', template_folder='templates', instance_path=None, instance_relative_config=False)
    一般FLASK类创建程序实例的方法如下:
    from flask import Flask
    app = Flask(__name__)
    
    ##import_name
    这是Flask类唯一一个必须指定的参数,Flask用该参数决定程序的根目录,以便稍后能够找到相对于程序根目录的资源文件位置。
    该参数一般用“\_\_name\_\_”,但更推荐使用程序主模块或包的名字,因为这样更便于调试debug。
    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)
    因此如果你的程序是在 *yourapplication/app.py* 中定义的,那么你最好从以下方法中选择一种来创建你的程序实例:
    app = Flask('yourapplication')
    app = Flask(__name__.split('.')[0])
    
    ##其他参数
    其他参数用于指定模板和资源的路径,默认为程序根目录下的 *template* 和 *static* 文件夹。因此为了避免不必要的麻烦,这两个文件夹的名称注意不要取错。
    ###*参考资料:*
    [Flask API 应用对象](http://docs.jinkan.org/docs/flask/api.html#id2)
    2016-10-22 08:41:32 回应
  • 第12页
    #路由和视图函数
    ##概念
    - 客户端发送URL请求给Web服务器,服务器再通过WSGI协议将请求发送给Flask程序实例。
    - Flask程序实例使用请求的URL所映射的**路由**来处理相应的请求。
    - 一旦路由收到请求,就会执行其中的**视图函数**,而且路由中的变量部分可以以关键字参数传递给视图函数。
    - 视图函数执行后会将返回值反馈给客户端,这个返回值就是**响应**。
    ##URL路由的注册
    在路由系统中定义规则可以的方法可以概括为三种:
    1. 使用 flask.Flask.route() 装饰器
    2. 使用 flask.Flask.add_url_rule() 函数
    3. 直接访问暴露为 flask.Flask.url_map 的底层的 Werkzeug 路由系统
    ##路由的变量
    前面提到变量部分可以以关键字参数传递给视图函数。
    路由中的变量部分用尖括号指定( `/user/<username>`),默认使用不带斜线的字符串,不过也可使用类型定义。
    Flask支持在路由中使用的变量类型有:
    | 类型 | 说明 |
    | ------ | ---------------------------------- |
    | string| 接受任何不带斜线的字符串 |
    | int | 接受整数 |
    |float | 同 int ,但是接受浮点数 |
    |path | 和默认的相似,但也接受斜线|
    ###*参考资料:*
    [Flask API URL路由注册](http://docs.jinkan.org/docs/flask/api.html#url)
    2016-10-22 08:43:14 回应
  • Chap.2-The Request-Response Cycle
    ## 1. 请求对象##
    ###需求###
    虽然通过路由可以建立起URL请求和视图函数的映射关系,在客户端发起请求时调用对应的视图函数(其中路由中的动态变量还可以传递给视图函数),但这还不够。为了让视图函数能够处理客户端发来的请求,它还必须要能够访问客户端发来的数据信息。
    ###作用###
    Flask使用**上下文**中临时的** request**[ (API)][1] 对象向视图函数提供必要的信息,它的作用有:
    - 封装客户端发来的 HTTP 请求
    - 作为全局可访问的对象,向视图函数统一地提供请求数据
    - 得益于上下文,在多线程环境中,Flask可以保证[总会在当前线程上获取正确的数据][4]
    ##2. 上下文##
    ###概念###
    [@vczh](https://www.zhihu.com/question/26387327/answer/32611575)在知乎回答“什么是上下文”提到:
    每一段程序都有很多外部变量。只有像Add这种简单的函数才是没有外部变量的。一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行。你为了使他们运行,就要给所有的外部变量一个一个写一些值进去。这些值的集合就叫上下文。
    从这个角度理解,上下文并非天然存在的,而是类似于某种特定环境。**当你使用了“外部变量”与一个应用或一段程序发生交互,也就产生了相应的上下文;或者说,只有在特定的上下文中,这些“外部变量”才有意义。**
    ###上下文变量
    Flask中存在两种上下文:[应用上下文][2]和[请求上下文][3],这可以通过相应上下文提供的变量类型来区分判断。
    需要注意的是,如上文“请求对象”中所讲,这里的变量都是被封装成对象来使用的。
    应用上下文的变量有:
    - **current_app** 当前活动应用的实例对象
    - **g** 应用在处理请求时用来储存临时信息的对象
    请求上下文的变量有:
    - **request** 封装了客户端发来的 HTTP 请求的请求对象
    - **session** 一个形式为字典的用户会话对象,储存不同请求间需要“记住”的值
    ###应用状态和上下文的激活###
    可以认为,Flask对象在实例化后在模块层次上应用有[两个状态][2]。
    第一个状态为“休息”状态,该状态的情况是:
    - 目前没处理任何请求
    - 可以安全地修改应用对象
    - 必须得有一个指向对象的引用来修改它,因为不会有某个神奇的代理变量(
    *current_app*)指向你刚创建的或者正在修改的应用对象
    当激活一个请求前,应用开始进入“待命”状态,激活上下文:
    - 激活应用上下文:
    *current_app* 指向实例化的应用对象,线程中开始可以
    - 激活请求上下文:
    *request* 和 *session* 指向当前的请求
    此时,视图函数就可以一边从请求上下文中获取请求,一边从应用上下文中与实例对象进行交互,从而给出正确的响应。
    ###[请求上下文][3]###
    ###[代理对象][5]###
    需要注意的是,Flask实际提供的
    [1]: http://docs.jinkan.org/docs/flask/api.html#id4 [2]: http://docs.jinkan.org/docs/flask/appcontext.html#app-context [3]: http://docs.jinkan.org/docs/flask/reqcontext.html?highlight=%E8%AF%B7%E6%B1%82%E4%B8%8A%E4%B8%8B%E6%96%87#request-context [4]: http://docs.jinkan.org/docs/flask/api.html#flask.request [5]: http://docs.jinkan.org/docs/flask/reqcontext.html#notes-on-proxies
    2016-10-22 10:29:48 回应