基于uwsgi的Web服务路由功能升级

手上一个基于uwsgi开发的后台服务,接收GET请求,使用QUERY_STRING作为参数。

最开始的时候,路由功能使用的是if else的结构,大致如下

path = env["PATH_INFO"]
param = parse_query_string(env["QUERY_STRING"])
if path == "foo1/bar1":
    fooBar1(param)
elif path == "foo2/bar2":
    fooBar2(param)

为了方便管理并且美化代码,调整为使用路由字典的形式

funcion = {"foo/bar":fooBar}

functions[path](params)

def fooBar(params):
    param1 = params.get("p")

经过一段时间的使用后发现,在这种形式下每个函数的参数unpack与必要参数判断都需要独立进行,产生了很多重复代码

并且,在参考了flask等框架的装饰器形式之后,对路由部分进行了重构

def route(path="", required=None):
    def route_func(func):
        def params_check_func(params):
            args = inspect.getargspec(func)
            for required_param in (var_required if required else []):
                if required_param not in params:
                    raise ParamsError("%s is required" % required_param)
            return func(**params)
        global functions
        functions[path] = params_check_func
        return params_check_func
    return route_func

@route("foo/bar", ["p"])
def fooBar(p, *args, **kwargs):
    return do_sth(p)

其中因为参数利用了Python的可变变量功能,直接从QUERY_STRING解析获得,为了避免输入参数中附加了不必要的参数,所以使用*args, **kwargs的结构将多余的参数存储并忽略掉

以避免多余的参数使函数因参数数量不符造成报错

每个函数都增加*args, **kwargs的参数显得多余,同时发现,每个函数的必须参数在函数定义的参数列表中已经可以体现,

具体思路是:

使用 inspect.getargspec(func)获得参数的具体参数列表

则其中的args.defaults即为有默认值参数的默认值,使用len(args.defaults)获取有默认值参数的个数

那么args.args[:-len(args.defaults)]就是必须参数的列表,因为在定义中,有默认值的参数必须在无默认值参数的后面

进一步,如果没有args.varargs和not args.keywords即可变参数,则将所有多余的参数过滤

同时经过统一格式化的参数名,也可以直接映射到相应的路径

那么在改进之后的代码则如下

def route(path="", required=None):
    def route_func(func):
        def params_check_func(params):
            args = inspect.getargspec(func)
            var_required = required
            if not var_required:
                var_required = [arg for arg in args.args[:-len(args.defaults)]]
            for required_param in (var_required if var_required else []):
                if required_param not in params:
                    raise ParamsError("%s is required" % required_param)
            if not args.varargs and not args.keywords:
                for param_key in params.keys():
                    if param_key not in args.args:
                        params.pop(param_key)
            return func(**params)
        global functions
        var_path = path
        if not var_path:
            var_path = "/%s/" % func.func_name.replace("__", "/")
        functions[var_path] = params_check_func
        return params_check_func
    return route_func

@route()
def foo__bar(p1, p2=1):
    return do_sth(p1, p2)
时间: 2024-08-05 07:05:05

基于uwsgi的Web服务路由功能升级的相关文章

基于 REST 的 Web 服务:基础

基础 REST 定义了一组体系架构原则,您可以根据这些原则设计以系统资源为中心的 Web 服务,包括使用不同语言编写的客户端如何通过 HTTP 处理和传输资源状态. 如果考虑使用它的 Web 服务的数量,REST 近年来已经成为最主要的 Web 服务设计模型. 事实上,REST 对 Web 的影响非常大,由于其使用相当方便,已经普遍地取代了基于 SOAP 和 WSDL 的接口设计. REST 这个概念于 2000 年由 Roy Fielding 在就读加州大学欧文分校期间在学术论文“Archit

基于Socket创建Web服务

基于Socket创建Web服务 为什么要使用Socket呢,我们来看下图 Socket原理图回顾: -------------------编写SocketService,完成字母小写转大写功能----------------------------- ServerSocket服务器端代码如下: public static void main(String[] args) throws IOException { // 1:建立服务器端的tcp socket服务,必须监听一个端口 ServerSo

建立基于https的web服务

先安装openssl [[email protected] ~]# yum install openssl 搭建私有CA服务器 修改openssl.cnf配置文件 [[email protected] ~]# vim /etc/pki/tls/openssl.cnf dir=/etc/pki/CA 创建相关的文件 [[email protected] ~]# cd /etc/pki/CA [[email protected] ~]# makdir certs newcerts crl [[ema

python3.x +django + nginx + uwsgi 搭建web服务

最近一直在用django开发自己的网站.在开发和线上环境的对接过程中遇到了许多的坑.所以想以一个老鸟的经历来写一下怎么 搭建web服务 一.python3.x .django .nginx .uwsgi 的介绍: 哈哈自己baidu吧 二.安装python3环境 ----

Spring boot构建基于rest的Web服务

一.介绍:使用Spring Boot我们可以很容易的创建一个可独立运行的Rest web服务,其中内嵌tomact,我们只需“run”就可以查看效果了. Spring Boot利用Gradle或Maven构建引入第三方库的方式,所以我么不需要去担心我们改引入哪些库,而且使用Spring Boot省去了很多繁琐的配置. 接下来,我们将用Spring Boot实现和c# mvc一样的Rest Web服务. 二.效果:经典的Hello World. 这将是我么最终的效果,毋须配置部署tomact,我们

应用NuSoap构建新型的基于PHP的Web服务

一个例子便能说明一切,让我们先看一个例子 为了说明如何应用nusoap和php来构建web services,我们将举一个简单的例子.这个例子应用程序由一个php web services的服务器端和客户端组成.他将实现两个功能:颠倒一个字符串字符的顺序,求两个数的和. php soap服务器用php和nusoap来建立soap服务器非常容易.基本上,你只要写出你想要暴露给你的web services的函数,然后用nusoap去注册它们就可以了. ok,另外还需要两步才能完成php soap服务

web服务器之nginx和apache的区别

① apache属于重量级的服务器,nginx属于轻量级的服务器; 区别在于对一些功能的支持,比如:  pathinfo,php模块方面 ② nginx抗高并发能力强. 由于nginx采用的是异步非阻塞模式,而apache是阻塞模式; ③ nginx采用的是异步固定进程,而apache是同步多进程,一个连接对应一个进程; ④ nginx适合处理静态资源和反向代理,apache适合处理动态资源; ⑤ apache的重写模块比nginx要强大; ⑥ nginx支持平滑操作,在线升级; 扩展:常见的w

Web 服务编程,REST 与 SOAP

REST 简介 在开始我们的正式讨论之前,让我们简单看一下 REST 的定义. REST(Representational State Transfer)是 Roy Fielding 提出的一个描述互联系统架构风格的名词.为什么称为 REST?Web 本质上由各种各样的资源组成,资源由 URI 唯一标识.浏览器(或者任何其它类似于浏览器的应用程序)将展示出该资源的一种表现方式,或者一种表现状态.如果用户在该页面中定向到指向其它资源的链接,则将访问该资源,并表现出它的状态.这意味着客户端应用程序随

用 Java 技术创建 RESTful Web 服务--转载

简介 JAX-RS (JSR-311) 是为 Java EE 环境下的 RESTful 服务能力提供的一种规范.它能提供对传统的基于 SOAP 的 Web 服务的一种可行替代. 在本文中,了解 JAX-RS 的主要组件.本文用一个例子展示了一个企业如何使用 JAX-RS 内的功能以一种 Restful 的方式公开员工的联系信息. 背景 多年来,开发人员使用各种工具在其 Java 应用程序内创建 RESTful 服务.由于 REST 架构的简单性,主要需求 — 接收 HTTP 消息和头部的能力 —