Service

Service类常用于封装与上下文有关的逻辑。

如果dealer的参数类型继承自Service类,框架会对这个参数进行实例化。对Service类的参数进行实例化时,会递归地实例化它的__init__方法中的各个Context, Request, Response, Service类型的参数。

示例

下面这段代码可以实现10秒内只允许一个用户最多访问3次。

from lessweb import Service, Context, HttpStatus, interceptor, Application
from lessweb.plugin import redis
from lessweb.plugin.redis import RedisServ


class LimitServ(Service):
    def __init__(self, redisServ: RedisServ, ctx: Context):
        self.redis = redisServ.redis
        self.ctx = ctx

    @property
    def key(self):
        return f'count/{self.ctx.ip}'

    def touch(self) -> int:
        count = self.redis.get(self.key)
        if count is None:
            count = b'0'
            self.redis.set(self.key, value=count, ex=10)

        self.redis.incr(self.key)
        return int(count.decode())


def limit_checker(ctx: Context, limitServ: LimitServ):
    count = limitServ.touch()
    print(count)
    if count >= 3:
        ctx.response.set_status(HttpStatus.Forbidden)
        return 'Forbidden'
    else:
        return ctx()


@interceptor(redis.processor)  # 获取请求级redis连接
@interceptor(limit_checker)
def hello():
    return 'hello'


redis.init(host='127.0.0.1')  # redis初始化
app = Application()
app.add_get_mapping('/hello', hello)

if __name__ == '__main__':
    app.run()

请求1:curl -L "http://localhost:8080/hello"
返回:hello

请求2:curl -L "http://localhost:8080/hello"
返回:hello

请求3:curl -L "http://localhost:8080/hello"
返回:hello

请求4:curl -L "http://localhost:8080/hello" (10秒内访问)
返回:Forbidden