python|web应用框架|增加动态路由

简介: python|web应用框架|增加动态路由

昨天我们已经已经修改了web路由注册,将其从函数方式注册,修改为类装饰器注册,如果你还没有看过此前那篇文章,建议你先看下,以便做到承上启下:

python|web应用框架|使用类装饰器注册路由:juejin.cn/post/722879…



今天我们将继续对该框架进行路由添加正则表达式。

本篇文章所依赖的python环境为:


image.png



路由添加正则表达式有什么用?


在介绍之前,我们首先要介绍一下Get获取资源的时候,有如下几种传参方式:


上述的第二种以路径参数的方式传参,就是我们这边文章所描述的点。


为什么需要这样做呢?


假设我们现在正在写一个功能,他需要返回传上来的用户信息,接口为:

/userInfo/userid/infos,其中userid是动态的,所以接口可以是/userInfo/c12345/infos,也可以是/userInfo/d33456/infos等等。


如果是这种情况,我们应该怎么样样定义路由呢? 是在项目中给每个人都定义一个路由信息么?

很显然不是的,如果这个时候,注册的路由恰恰好是正则的,可以获取客户端传上来的参数,例如:/userInfo/pdudo/info,函数将会获取pdudo,这样不是很好么?


这就需要用到正则了。



如何定义动态路由


由于我们此前已经写好了定义静态路由的相关方法,所以我们在定义动态路由的时候,最好加一个识别参数,告诉框架,这个路由是静态的 还是 动态的。


由于是动态路由,所以在路由url中,有些值肯定是动态的,如何在区别于静态的值和动态的值呢? 在该框架中,我们将动态值用大括号括起来,比如: /userInfo/{userID}/infos,其中userID是动态的,可以是任何值组成,但是/userInfo/infos必须是静态的,而且先后顺序也是固定的。

所以说,我们可以约束一下,在定义动态路由的时候,需要告诉框架,我这个是动态路由,以及动态url


所以我们准备将动态路由定义规划如下:

@myWeb.routes(path="/jobs/{jobID}/startd",methods="post",regular=True)
def startJobs(r,cData):
    print("cData: " ,cData)

上述代码,是我们即将完善功能后的代码案例,其中regularTrue代表该路由是动态的,path的值为/jobs/{jobID}/startd,其中jobID也是动态的,可以被任何值代替。


最后是函数将接收2个参数,r的值代表wsgi中的environ信息。 而cData则代表从客户端上报的值,即:jobID的替代值。



注册动态路由


如上我们已经约束好了一个动态路由的添加规则,那么我们如何注册动态路由呢?

首先肯定的是,动态路由肯定不能和静态路由放在一起,所以我们定义了新的字典用于存放动态路由的信息,如:

mapGetRegularRouting = {}
mapPostRegularRouting = {}


而后则是我们需要将注册的路由信息转换为正则表达式,这里举个例子:

我们注册的路由是这样的: /jobs/{jobID}/startd,我们需要将其转换为正则表达式,正则表达式的值是这样的: ^/jobs/(.*?)/startd$


关于这段正则表达式,它的含义是 匹配以/jobs/开头和/startd结尾的字符串,并且将匹配到的信息(.*的值)存储到元组中。

注意这里.*后面的问号?代表不启用贪婪匹配,也就是最小化匹配。


现在的问题是,如何将{jobsID}给转换为(.*?)呢? 在python中,可以使用re.sub进行替换操作,我们可以使用如下语句,将{jobsID}给替换为(.*?),代码如下:

import re
print(re.sub("{.*?}","(.*?)","/jobs/{jobID}/startd"))

如上代码执行的结果为:

image.png


最后将该路由信息存储到上述定义好的字典中即可,代码片段如下:

reFindall = re.compile(r"{(.*?)}")
reSubAll = re.compile(r"{.*?}")
parameter = re.findall(reFindall,self.path)
reText = re.sub(reSubAll,"(.*?)",self.path)
reText = f"{reText}$"
regular = {
    "original": self.path,
    "reText": reText,
    "parameter": parameter,
    "func": func
}
# ...
if self.re:
    mapPostRegularRouting[regular["reText"]] = regular

至此,我们的动态路由就已经注册好了。




匹配动态路由


相比于注册动态路由,当客户端请求来了之后,匹配动态路由会很麻烦,因为没有请求报文不是告诉你,这是动态路由还是静态路由,所以说,匹配动态路由很麻烦。


我们匹配动态路由想到的时候笨办法,即: 先匹配静态路由,若静态路由匹配不到,则再匹配动态路由,若动态路由都匹配不到的话,则选用默认路由。


匹配静态路由和动态路由,前面篇章已经介绍过了,所以这里不再赘述,这里就介绍如何匹配动态路由。

所谓的动态路由规则匹配,实际上就是拿着客户端上传的url,挨个对我们已有的正则表达式做轮训,若匹配成功则退出循环,若匹配失败,最后就返回一个默认路由即可,匹配正则表达式代码如下:

for key in RegularRouting.keys():
    if re.match(key, path):
        isRegular = True
        collText = re.findall(key, path)
        func = RegularRouting[key]["func"]
        break
else:
    func = Route["/*"]



框架运行效果展示


关于myWeb.py由于很长,有100多行,不好截图,也不好纯复制代码了,所以放到了gitee上面:gitee.com/pdudo/golea…

我们简单写几个demo测试一下web框架,代码如下:

import myWeb
import wsgiref.simple_server
@myWeb.routes(path="/ip",methods="all")
def indx(r):
    print(r["REMOTE_ADDR"])
    return (200,r["REMOTE_ADDR"])
@myWeb.routes(path="/hello/{name}",methods="get",regular=True)
def helloWold(r,cData):
    name = cData[0]
    return (200,"hello %s" % (name))
def main():
    s = wsgiref.simple_server.make_server('', 8888, myWeb.application)
    s.serve_forever()
if __name__ == '__main__':
    main()


上述代码,我们首先引入了myWebwsgiref模块,前置是我们自己写的,后则是一个满足wsgi服务器框架,在代码中,我们定义了2个路由信息,一个是静态路由,一个是动态路由,其中静态路由的函数是indx,路由信息是/ip,匹配的客户端请求方法为get或者post,该方法主要返回ip地址。


动态路由的函数则是helloWold,它将匹配到以/hello/为首的路由信息,匹配客户端请求方法为get,还函数主要获取用户发送的动态值,并且以hello 等返回给客户端。


在主函数中,我们启动一个简单的wsgi服务器,入口为myWebapplication方法 。


代码运行效果如下:

image.png

我们分别使用getpost方法,请求本地/ip路由,可见都回复回来了,而后我们访问/hello/pdudo/hello/juejin,他们也分别回复了hello pdudohello juejin



总结


本篇文件介绍了将此前的web框架,路由修改为正则表达式形式,具体添加方式为: 在进行路由注册的时候,将其路由信息转换为正则表达式,而在进行路由匹配的时候,先匹配静态服务器,若静态服务器没有,再进行正则匹配,若正则匹配依然不行,则返回最后的默认页面。



相关文章
|
6天前
|
安全 前端开发 数据库
Python 语言结合 Flask 框架来实现一个基础的代购商品管理、用户下单等功能的简易系统
这是一个使用 Python 和 Flask 框架实现的简易代购系统示例,涵盖商品管理、用户注册登录、订单创建及查看等功能。通过 SQLAlchemy 进行数据库操作,支持添加商品、展示详情、库存管理等。用户可注册登录并下单,系统会检查库存并记录订单。此代码仅为参考,实际应用需进一步完善,如增强安全性、集成支付接口、优化界面等。
|
23天前
|
JSON 数据可视化 测试技术
python+requests接口自动化框架的实现
通过以上步骤,我们构建了一个基本的Python+Requests接口自动化测试框架。这个框架具有良好的扩展性,可以根据实际需求进行功能扩展和优化。它不仅能提高测试效率,还能保证接口的稳定性和可靠性,为软件质量提供有力保障。
55 7
|
21天前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
57 2
|
1月前
|
敏捷开发 测试技术 持续交付
自动化测试之美:从零开始搭建你的Python测试框架
在软件开发的马拉松赛道上,自动化测试是那个能让你保持节奏、避免跌宕起伏的神奇小助手。本文将带你走进自动化测试的世界,用Python这把钥匙,解锁高效、可靠的测试框架之门。你将学会如何步步为营,构建属于自己的测试庇护所,让代码质量成为晨跑时清新的空气,而不是雾霾中的忧虑。让我们一起摆脱手动测试的繁琐枷锁,拥抱自动化带来的自由吧!
|
2月前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
|
2月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
49 2
|
2月前
|
缓存 API 数据库
Python哪个框架合适开发速卖通商品详情api?
在跨境电商平台速卖通的商品详情数据获取与整合中,Python 语言及其多种框架(如 Flask、Django、Tornado 和 FastAPI)提供了高效解决方案。Flask 简洁灵活,适合快速开发;Django 功能全面,适用于大型项目;Tornado 性能卓越,擅长处理高并发;FastAPI 结合类型提示和异步编程,开发体验优秀。选择合适的框架需综合考虑项目规模、性能要求和团队技术栈。
33 2
|
2月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
142 1
|
1月前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
1月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
下一篇
开通oss服务