江湖儿女:WSGI

江湖外传

互联网飞速发展,在web开发的江湖中,除了武林盟主Java以外,许多脚本语言都参与进来分一杯羹。花开花落,花落花开,无数少年侠士在Web江湖演绎着自己的传说,不不负少年游。


含着金汤匙出生的PHP自不必说,Ruby与Python也加入这场混战。诞生于日出之国的Ruby起初并未在江湖上掀起波浪,直到丹麦少年为其诞下一子——Ruby On Rails后,才母以子贵,为世人所熟知。

既生瑜,何生亮。Python与Ruby总是那么纠缠不清,在多个领域,Python声名显赫,为世人所青睐。唯独在Web开发领域难以望Ruby之项背。但这本身并不妨碍,Python在Web开发领域的不断的努力。从web.py、Flask、Django之中,可见一斑。

今天,我们简单聊一聊在这些框架背后共同使用的网关通信技术——WSGI。

WSGI

WSGI即 Web Server Gateway Interface,看名字与CGI类似。没错,Python同样支持CGI接口编程,但如前文所述CGI之某些缺点,Python开发了自己的网关通信技术(当然Python本身也支持CGI)。

顾名思义,在职能上来说,WSGI和CGI确实是同样的东西,都是网关的一种实现,是连接Web服务器与Web应用之间的桥梁。因此理解了前文我对CGI的描述,对于理解WSGI是大有裨益的(和CGI重合的内容我就不提了)。当然就具体接口协议而言,他们是不同的。

WSGI不是库,也是框架。

Django、Flask可以被称为使用(支持)了WSGI的Web框架。

应用皆回调

收益于Python这门脚本语言。我们在编写WSGI程序的时候,只将具体的处理逻辑def成函数,然后将该函数作为回调(callback)传入WSGI的server循环程序之中即可。此时该函数称之为WSGI Application。

看一下最简单的应用回调函数:

def application(environ, start_response):	
    start_response('200 OK', [('Content-Type', 'text/html')])	
    return '<h1>Hello WSGI</h1>'

应用的回调函数都有两个参数,environ和start_response。

第一个参数environ就是一个字典,里面存着环境变量,里面的内容和CGI的环境变量基本一致。

第二个参数start_response是一个函数,用于输出HTTP的响应头,start_response一般有两个参数:第一个参数是就是状态码,比如200 OK,302 Found之类的。和CGI一样,通常情况下我们需要显示控制的HTTP头部的输出,就是200(正常返回)和301/302(重定向)这两种情况。因为类似404或者502之类的异常错误码,Web服务器肯定会自动抛出的。第二个参数则是HTTP首部的其他信息,是一个多个元组构成的list。每个首部字段,都放置到一个元组之中。

然后return出来的字符串,就是HTTP响应的实体部分了。看出来了吧,这是和CGI的一大不同:CGI是将所有响应内容(头部和实体)都作为标准输出,通过web服务器的重定向返回给客户端。而WSGI的做法,头部响应和实体响应分离,并且不需要向标准输出去输出内容。在WSGI中标准输出,就是普通的标准输出,会打印到终端控制台上,而不会作为内容返回。

wsgiref

wsgiref模块是python官方库针对wsgi协议的一个参考实现,虽然与工业界标准或有差距,但用来学习基本够用。同时该模块实现了一个简单的wsgi协议的HTTP服务器。

from wsgiref.simple_server import make_server	
......	

	
httpd = make_server('', 8000, application)	
    print 'Serving HTTP on port %d' % port	
    httpd.serve_forever()

放心,如前文所言,这个print语句,只会输出到终端,作为log之用,不会发送给客户端哒

这段代码比较简单,调用了wsgiref.simple_server的make_server函数构造了一个HTTP Server的对象(明显是个工厂模式)。该函数接收3个固定参数(其实有5个参数,另外两个有默认值):

  1. ip;可以为空,表示0.0.0.0(0.0.0.0即绑定该服务器的任何ip地址)

  2. 端口号;

  3. 回调函数(上上文def的application函数)

接着,开始循环(httpd.serve_forever())就启动了一个简单的HTTP Server啦。可以看出编写wsgi web应用的关键,就是回调函数的编写啦。

虽然前面说wsgiref基本够用,但是有个问题,就是不支持HTTPS啊。要弄个支持HTTPS的Web Server,就要用到一些第三方的组件了。

eventlet

gevent和eventlet都可以完成,以eventlet举例:

from eventlet import wsgi	
import eventlet	

	
wsgi.server(eventlet.wrap_ssl(eventlet.listen(('', 8443)),	
                              certfile='cert.crt',	
                              keyfile='private.key',	
                              server_side=True),	
            application)

其中certfile和keyfile是服务端的证书和私钥文件,可用openssl命令生成自签名的证书和私钥。关于eventlet的详细介绍不在本文讨论范围内,大家可以自行百度谷歌。我们需要聚焦的是,虽然使用了一个第三方库,启动server的代码与wsgiref模块不太相同,但是我们之前编写的application回调函数可以直接在这里使用。也就是说我们的回调是与具体server无关的,更换另一个支持wsgi协议的server,只是在启动的代码做些修改,而我们所关心的业务逻辑则丝毫无需改动。

做个简单的URL路由

之前CGI的文章中有指出,CGI程序只能交由Web服务器去配置出十分简单的路由功能。而受益于Python语言之利,WSGI程序自制一个URL路由的功能十分简单。

为了解耦,我们可以单写一个URL路由的脚本,作为配置文件之用。比如urls.py

... 	

	
urls = [	
    (r'^$', index),	
    (r'hello/?$', hello),	
    (r'world/?$', world),	
    (r'good/boy?$', boy)	
]

r开头的字符串表示正则表达式,通过正则实际可以更为灵活的配置URL路由。另外需确保urls.py文件中import了index、hello、world、boy这些函数的定义。

然后在之前的启动脚本中,引入这个文件,并且解析路由:

from urls import urls	

	
def application(environ, start_response):	
    path = environ.get('PATH_INFO', '').lstrip('/')	
    for regex, callback in urls:	
        match = re.search(regex, path)	
        if match is not None:	
            return callback(environ, start_response)

这样一个简单的URL路由功能就实现了。

参考资料

  • PEP 3333

  • wsgiref

  • eventlet wsgi

在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

果冻虾仁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值