跳至主要内容

从一条简单的 URL 开始


从代码开始

先来看一段代码
from flask import Flask, g, request
from functools import wraps
app = Flask(__name__)


def set_g(f):
    @wraps(f)
    def decorator(*args, **kwargs):
        g.auth = 'zadmin'
        g.scope = 5
        g.num = 0
        return f(*args, **kwargs)
    return decorator


def check_auth(f):
    @wraps(f)
    def decorator(*args, **kwargs):
        auth = g.auth
        if auth != "admin":
            print "Failed in auth"
        g.num = 20
        return f(*args, **kwargs)
    return decorator


def check_scope(f):
    #@wraps(f)
    def decorator(*args, **kwargs):
        ''' This check scope docker string '''
        scope = g.scope
        if scope not in [1, 2, 3]:
            print "Failed in scope"
        g.num = 10
        return f(*args, **kwargs)
    return decorator


@app.route('/test')
@set_g
@check_auth
@check_scope
def test():
    ''' This is function test'''
    print request.path
    print g.auth, g.scope
    print "g.num:{}".format(g.num)
    print test.__doc__
    return "test"

app.run(debug=True)
如果我访问这个 API 会在 terminal 打印什么呢?
Failed in auth
Failed in scope
/test
zadmin 5
g.num:10
This check scope docker string
装饰器会在下面的 blog 中专门说一下
这一篇只说 flask 的 route
从结果来推断,访问 API 之后函数的执行顺序是这样的:
app.route()=>set_g()=>check_auth()=>chek_scope()=>test()

flask 中的 route 到底做了什么

route

@setupmethod def route(self, rule, options): def decorator(f): endpoint = options.pop(‘endpoint’, None) self.add_url_rule(rule, endpoint, f, options) return f return decorator ​
route 是一个装饰器,负责将 URL 与 OPTION 传到 add_url_rule 这个函数中
这样的代码会更美观

add_url_rule

 def add_url_rule(self, rule, endpoint=None, view_func=None, provide_automatic_options=None, **options):
        if endpoint is None:
            endpoint = _endpoint_from_view_func(view_func)
        options['endpoint'] = endpoint
        methods = options.pop('methods', None)

        if methods is None:
            methods = getattr(view_func, 'methods', None) or ('GET',)
        if isinstance(methods, string_types):
            raise TypeError('Allowed methods have to be iterables of strings, '
                            'for example: @app.route(..., methods=["POST"])')
        methods = set(item.upper() for item in methods)


        required_methods = set(getattr(view_func, 'required_methods', ()))


        if provide_automatic_options is None:
            provide_automatic_options = getattr(view_func,
                'provide_automatic_options', None)

        if provide_automatic_options is None:
            if 'OPTIONS' not in methods:
                provide_automatic_options = True
                required_methods.add('OPTIONS')
            else:
                provide_automatic_options = False


        methods |= required_methods

        rule = self.url_rule_class(rule, methods=methods, **options)
        rule.provide_automatic_options = provide_automatic_options

        self.url_map.add(rule)
        if view_func is not None:
            old_func = self.view_functions.get(endpoint)
            if old_func is not None and old_func != view_func:
                raise AssertionError('View function mapping is overwriting an '
                                     'existing endpoint function: %s' % endpoint)
            self.view_functions[endpoint] = view_func
add_url_rule 处理传来的参数然后将符合规则的 url 与 method 生成一个 rule 对象
再将 rule 加到 Map() 对象中存储起来
这也是 flask 中 url 与 method 全局唯一的保证
这样看来
完整的过程是这样的:
route()=>add_url_rule()=>RULE()=>url_map.add()=>set_g()=>check_auth()=>chek_scope()=>test()

评论

此博客中的热门博文

在 LSF 中使用 docker 运行任务

LSF + Docker Table of Contents 1. 环境信息 2. 修改配置文件在 lsf 上启用 docker 3. 验证 4. 部署常见问题 5. 部署参考链接 1  环境信息 docker 18.09.5 Kernel Version: 3.10.0-862.11.6.el7.x86_64 lsf 10.1.0.6 OS CentOs 7.6.1810 2  修改配置文件在 lsf 上启用 docker 1.conf/lsf.conf 添加/修改 LSF_PROCESS_TRACKING=Y LSF_LINUX_CGROUP_ACCT=Y LSB_RESOURCE_ENFORCE="cpu memory" 2.conf/lsf.shared 添加 docker Boolean () () (Docker container) 3.conf/lsf.cluster 添加 $your-host-name ! ! 1 3.5 () () (docker) 4./conf/lsbatch/$clustername/configdir/lsb.applications 添加 Begin Application NAME = app1 CONTAINER = docker[image(ubuntu:latest) options(--rm --network=host --ipc=host -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group) starter(root)] DESCRIPTION = Test Docker Application Profile 1 End Application 5.badmin reconfig 验证是否可用 3  验证 在非 root 用户下, bsub -app app1 -I cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DES

Python 中的 UUID

python 中的 uuid 代码参考 cpython/Lib/uuid.py 版本 3.7 什么是 UUID UUID 的全称是 Universal Unique Identifier,中文名是 通用唯一标识符; wikipedia 上 UUID 的定义是 a 128-bit number used to identify information in computer systems UUID 需要满足两个条件: 128 bit 具有标识别计算机系统的能力 UUID 的规则 格式 将 16 个 8 位字节表示成 32 个十六进制数 按照 8-4-4-4-12 的格式加上 4 个连字符 “-‘ 版本 UUID 应该是下面的这种格式 xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 其中 M 开始的 4 位表示版本,N 开始的 4 位表示变种 Name                        Length(bytes)    Length(hex digits)                       Contents time_low                         4                             8                  integer giving the low 32 bits of the time time_mid                         2                             4                  integer giving the middle 16 bits of the time| time_hi_and_version      2                              4                  4-bit “version” in the most significant bits,                                                                                               fol

k8s 源码阅读 -- eviction

Table of Contents 1. 前言 2. 资料 3. 代码详解 3.1. 代码参考 3.2. 详细 1  前言 在某些情况下 k8s 会出现 evicted 的 pod, 然而这并不在  pod 的生命周期 中.这就是 k8s 的驱逐机制。 当机器的一些资源(内存、磁盘)过小时,为了保证 node 不会受到影响,会将 pod 驱逐至其他的机器上 2  资料 可以在  这里看到相关资料 来看一下代码中,驱逐策略是怎样实现的 3  代码详解 3.1  代码参考 kubernetes release-1.10 3.2  详细 pkg/kubelet/apis/kubeletconfig/v1beta/default.go 定义了这几个默认值作为阈值 pkg/kubelet/kubelet.go kubelte 初始化了 eviction manager 在 runtime 相关模块被加载时,eviction manager 被加载进来 开始了 evict 相关的控制循环 接下来是 evict 真正工作的代码 代码目录是 pkg/kubelet/eviction/ 主要看该目录下的两个文件 eviction manager.go  helpers.go pkg/kubelet/eviction/eviction manager.go Start 是 evict manager 的入口 这里是一个死循环 循环中的主要函数是 synchronize 用来清理 pod、同步信息。这个就是今天的主角 先看一下 synchronize 的参数 diskInfoProvider podFunc diskInfoProvider 是一个接口,用来提供磁盘的信息,作为是否发生驱逐的依据。实际函数在  pkg/kubelet/stats/  下 synchronize 中仅用到了 HasDedicatedImageFs podFunc 用来获取一个待检查的 pod 列表,实际函数在 pkg/kubelet/kubelet pods.go 首先检查 imagesfs, 数据从 cadvisor 中获取 获得容器