7 min read

Pythonista的Web开发指南

Pythonista的Web开发指南

我有一点Pyhton的使用经验,当我决定使用它进行Web开发的时候,Web框架,Web应用程序,Web服务器等具有混淆性的名词让我措手不及。让我在学习Flask和他的兄弟Quart还有FastAPI时候非常混乱。

为什么用Flask开发的程序在部署时要使用Gunicorn运行,使用FastAPI开发的程序运行的时候要启动uvcorin?WSGI,ASGI的意义在哪里?

我选择了一条“笨”的路径把他们连起来。

HTML,HTTP和静态网站

一个用HTML语法书写的文件就可以成为一个网页,这是因为浏览器(Chrome,Firefox等)会翻译HTML语法,这个过程被我们称为渲染(rendering)。

与这个渲染过程类似的例子是Markdown和Markdown编辑器(编辑器会渲染用Markdown书写的文件),LaTex和LaTex编辑器。

从这一点上看用HTML语法书写的文件和用其他语法(Markdown,LaTex等)书写的文件没有什么特别之处,都是文本文件。

超文本(Hyper Text)

虽然现在我们对HTML里的超链接习以为常,但是我们也需要知道这个特点同样是超文本文件(HyperText)的定义

Hypertext is text which contains links to other texts.

超文本标记语言(HTML)

现在你应该明白超文本(HyperText,HT)和标记语言(Markup Language,ML)是什么意思了。

超文本传输协议(HTTP)

HTTP起初就是为了传输超文本而设计的协议,通过HTTP我们就可以把一台电脑上的HTML文件发送到另外一台电脑上。

提供HTML文件的整台电脑被我们称作Web服务器(Web Server)。另一台电脑上对HTML进行翻译的浏览器被称作客户端。

Web服务器和HTTP服务器

在Web服务器上除了需要有要传输的HTML文件,还需要有一个实现了HTTP协议的软件,这样才能与实现了HTTP协议的浏览器进行交流,这个软件就是HTTP服务器。

常见的HTTP服务器有

静态站点

静态的意思是指将存放在Web服务器上的网页文件(HTML,CSS,JavaScript,图片等)内容原封不动的通过HTTP服务器传输给浏览器。

静态站点并不意味和服务器没有交互。看看MDN关于静态站点的描述

静态站点Web服务器做的事情和FTP服务器非常相似,然而不同的协议是让他们成为两种不同服务器类别的根本。

一切都很美好,网站结构也很清晰,这对我们理解Web的运作方式起来是一件好事情。

动态站点,WSGI和ASGI

静态站点对我们理解Web运作很有帮助,一个HTML文件就是一个页面。

但是想象一下如果Google的搜索结果是静态站点的话,那么每一个搜索页面都将作为一个HTML页面存放在Google的Web服务器上。这将大大的提高网站的管理难度。

搜索的结果具有类似的网页结构和布局,不同的只是HTML标签中的内容。相同结构的HTML文件被称作HTML模板,而展示在模板中的内容会根据客户端的请求“动态”的填充在HTML模板上,这样我们就“动态”的组装了一个HTML文件。

具备“动态”组装HTML文件的站点,被称作动态站点。

动态站点让真正让事情变的复杂起来,但是了解它非常必要,因为现在绝大部分的站点都是动态的。

如何动态组装--CGI

别忘了,我们现在还是处于静态站点时期。我们的Web服务器具有:

  • 一些精心准备的HTML文件
  • 一个HTTP服务器用于和浏览器通信,以便把我们网页发送过去

为了让HTTP服务器具有除了传输网页的功能(响应HTTP请求)外,要扩展它具备其他功能(例如“组装”HTML文件)从我的理解来说有两种办法。

  1. 直接扩展HTTP服务器本身,给它加入更多的功能
  2. 把HTTP服务器作为“中转站”中转客户端的HTTP请求,让其他程序做更多功能

通用网关接口(CGI)就是为了第二种方式(第一种我没有找到相关的例子,如果你知道,欢迎通过社交媒体或邮件方式告诉我)而推出的规范。

有了CGI之后,我们的Web服务器就可以转发客户端的HTTP请求到另外的程序中(例如Lua程序)进行响应生成HTML文件,然后将结果返回给HTTP服务器。

Python世界中的CGI--WSGI

WSGI是Python领域中面相HTTP服务器和Python应用程序之间的接口规范,从主要功能上它和CGI完成一样的事情。

来看看Flask官方的小片段:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

Flask内置了一个用于开发调试的HTTP服务器,所以当我们访问http://localhost:5000(Flask默认的端口)时浏览器会显示我们期望的HTML页面。

内置的HTTP服务器向浏览器返回的一个完整的HTML文件,因为Jinja2为我们生成 了HTML文件的其他部分。

WSGI Application和WSGI HTTP Server(WSGI服务器)

Gunicorn是部署Flask应用程序到生产环境中推荐的HTTP服务器之一。Gunicorn和Flask应用通过WSGI协议约定的方式进行交互。所以Gunicorn自己也称自己为WSGI HTTP Server,Flask应用程序叫也做WSGI Application。

ASGI

ASGI在功能上是WSGI的扩展,并且被设计为兼容WSGI,ASGI HTTP Server和WSGI HTTP Server在Web开发中的位置相同。

Web Server和Application Server

Web服务器和App服务器的概念之间的界限非常模糊,他们之间的区别也有很多中说法。

IBM对此的解释是:

Web Server:

  • 主要响应来自浏览器的HTTP请求

Application Server:

  • 除了响应来自浏览器的HTTP请求之外还允许其他类型的协议进行通信(例如WebSocket,RPC)

结尾

从重新理解HTML,HTTP到静态网站的基本逻辑,从动态网站到WSGI和ASGI是一个逐步前进的过程。

关于静态网站和动态网站的优缺点,推荐阅读Tatiana Mac的文章://www.tatianamac.com/posts/beginner-eleventy-tutorial-parti/

关于应用服务器和Web服务器之间区别的讨论推荐浏览Stackoverflow上的贴子:https://stackoverflow.com/questions/936197/what-is-the-difference-between-application-server-and-web-server