七月流火

上海,昨天,40.9度,据说143年历史最高温度。我们这代人见识了太多的百年一遇,千年一遇,这方面已经习惯了,麻木了。

这两个月,是到汇付以来最忙的日子,各种压力和煎熬,而且还不是那么有把握和信心。

也是习惯了,当然不麻木。

记上一笔,未来的时候,回顾此刻。

ps

刚从青浦朱家角回来,集团的年中会,开了两年会,很累。做的事情得到别人认可,而各种修为又要提升。好奇心,专注,也算我的特点。真的很感谢当年的自己,以及父亲,让我从小喜欢了电脑,如今,可以沉浸其中的快乐!

看见从前的自己 感觉真好

在强大的却不太能访问的 fb 上发现了自己2008-2010之间800多篇 blog,于是“那年今天”就真的成了一个很有趣的功能。下面这篇发表于 2008年6月10日。

iPhone 3G来了,好戏又要开始了
看到“随着苹果发布3G版本的iPhone,AT&T;也正是发布了新的用户协议,目的就是同苹果公司一道,遏制客户对于iPhone解锁使用其他运营商的行为.Gizmodo表示,AT&T;的国内销售部总裁曾经说过,iPhone的激活将会在店内进行.而这同现在客户在家通过iTunes进行激活的方式不同.另外,路透社报道,AT&T;曾表示,购买了iPhone以后,30天还不激活将会面临惩罚.目前更多的细节尚未公布.”呵呵,的确,在聪明的hacker这里,这些应该不是问题。非常高兴看到iphone固件2.0版本肯定带中文界面和支持中文手写输入,加上待机时间长了,到时候,很多商务人士也会首选iphone了,而目前已经被iphone攻占的mac fans将继续扩大影响力。iphone一年前上市,一年里面,moto手机部已经被整地七零八落了,下一个会是谁,nokia,还是索爱?

iphone 1 出来的时候,谢谢 Brad 当时从美国托人帮我带回来,比较后悔的是没有收藏好这个第一代。当时我就坚定的认为这将是未来手机的代表。

彼时,nokia 还是老大,黑莓还是商务机的几乎唯一选择。

果然,nokia 手机后来在两年里面迅速倒闭,索爱现在还算在苦苦支撑,不过已经是很小众了,周围几乎没有人用,偶尔看到一些评论。

这几年越来越多的管理工作,让我喜欢也必须去预测一些事情,以及拥有远见。

可惜没有在2008年买 apple 的股票,而国内的股票市场太不正规,我的这个科技预见能力只能用在工作和业余兴趣了。

书写一月

从2017.3.7 开始在简书上第一篇,到今天,差不多1个月,24篇文章,覆盖随笔、摄影和编程,字数:6885,收获喜欢 11,粉丝 7。

公众号目前是104位订阅者。

blog 这里没有办法统计具体的人数,但从每篇 blog 的访问来看,是最多的,不过我估计绝大多数是各类 bot。

书写一月,感觉简书平台还是挺有趣的,体验也是做得最好,比用了十几年的 wp 还好。

互联网时代了,手机时代了,必须要改变一些思维方式了。

未来总是挑战重重。

又是清明

清明天气很好,难得出去逛街的我,到了港汇一游。

以前好像还是经常去港汇的,包括百脑汇和太平洋,后者现在已经几乎没有了,港汇还是很热闹。在肇嘉浜路上班的时候,特别是后期,经常中午走几个街口到港汇吃饭小聚。

景物都在,物是人非。烦恼果然是时时刻刻都有,放得下就是一天,放不下也是一天。

python 中使用装饰器来统一检查 flask 用户权限

最近在一个项目中,需要判断 restful 接口函数传入的时候,是否之前已经登录状态是某个特定用户,以及该用户有没有指定的权限。检查下来如果没有的话,立刻返回错误,中断功能。

遮掩的场景虽然也可以通过标准的调用函数来操作,但都不如用装饰器来得简单。都知道装饰器好用不好写,废话不说,先来看看这个场景怎么实现,还是有一定的通用性的。

def validate_current_is_admin(f):
    @functools.wraps(f)
    def decorated_function(*args, **kws):
        # 需要在登录状态调用, 检查是否为有admin权限的用户登录,
        # 如果不是,返回错误码;
        if g.user.user_name != 'admin':
            raise CustomFlaskErr(USER_MUST_HAS_ADMIN_PRIVILEGE, status_code=401)

        # 验证权限是否为 admin, 不是的话,返回401错误
        if g.user.role_id != Permission.ADMIN:
            raise CustomFlaskErr(USER_MUST_HAS_ADMIN_PRIVILEGE, status_code=401)

        return f(*args, **kws)

    return decorated_function

 

这是一个标准的装饰器的写法,如果你要写一个简单的装饰器,整个框架可以参考。

装饰器调用举例:

@app.route('/api/create_user', methods=['POST'])
@auth.login_required
@validate_current_is_admin
def create_user():

    # 获得参数
    user_name = request.json.get('user_name')
    password = request.json.get('password')
......

 

核心代码的业务逻辑也不复杂,根据 flask 的 g 对象中预存的用户 user 进行检查处理,flask 的这些定义非常灵活,flask.g 怎么使用可以查看 flask 的文档。

这里的user以及相关的属性属于具体业务逻辑,就不展开解释了,可以望文生义。

如果检查下来不符合的话,会调用自定义的 flask 错误,这部分内容可以查看之前写的 python flask 写 api 如何返回自定义错误

因为不对args和kws这些参数进行解析和处理,所处理的是 flask 全局对象。最后将参数都原路打包返回即可,没有问题的话交给使用装饰器的代码继续处理。

这个例子比较简单,主要还是熟悉装饰器的基本用法。

(首发简书

python flask 写 api 如何返回自定义错误

在 python 开发中,利用 flask 写 restful api 函数的时候,除了标准的400、500等这些返回码通过 abort() 返回以外,怎么另外返回自定义的错误代码和信息呢?

我们碰到的业务场景是对于api 输入参数的各类校验以及在业务逻辑执行的时候,都会返回统一的400代码,同时也会返回我们约定的描述详细错误的代码以及描述字符串,提供给调用方来处理,这样可以让其用户体验做得更好,同时详细错误代码和描述字符串也会自动打印在 log 日志中。

flask 的官方文档中告诉我们:

默认情况下,错误代码会显示一个黑白的错误页面。如果你要定制错误页面, 可以使用 errorhandler() 装饰器

在写 restful api 的时候,并没有页面可以返回,我们可以在 flask 提供的代码基础上稍加改造如下。

在你的初始化 flask app 的相关代码中加入下面两个函数:

@app.errorhandler(CustomFlaskErr)
def handle_flask_error(error):

    # response 的 json 内容为自定义错误代码和错误信息
    response = jsonify(error.to_dict())

    # response 返回 error 发生时定义的标准错误代码
    response.status_code = error.status_code

    return response

 

class CustomFlaskErr(Exception):

    # 默认的返回码
    status_code = 400

    # 自己定义了一个 return_code,作为更细颗粒度的错误代码
    def __init__(self, return_code=None, status_code=None, payload=None):
        Exception.__init__(self)
        self.return_code = return_code
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

    # 构造要返回的错误代码和错误信息的 dict
    def to_dict(self):
        rv = dict(self.payload or ())

        # 增加 dict key: return code
        rv['return_code'] = self.return_code

        # 增加 dict key: message, 具体内容由常量定义文件中通过 return_code 转化而来
        rv['message'] = J_MSG[self.return_code]

        # 日志打印
        logger.warning(J_MSG[self.return_code])

        return rv

 

CustomFlaskErr 是我们自己写的处理错误的类,然后通过 @app.errorhandler(CustomFlaskErr) 这个装饰器在 flask 中注册。

具体功能在注释里基本都写了,我们看一下怎么使用这个自定义错误处理器。

# 用户名输入为空
    if user_name is None:
        raise CustomFlaskErr(USER_NAME_ILLEGAL, status_code=400)

 

当需要处理某个错误的时候,rasie 刚才的 CustomFlaskErr,传递另外定义好的自己的错误代码,以及标准的返回代码;

上面说的常量定义文件可以参考如下:

USER_ALREADY_EXISTS = 20001  # 用户已经存在
J_MSG = {USER_ALREADY_EXISTS: 'user already exists'}

 

通过这样的机制,就做到了在具体 restful api 的业务逻辑代码中简单的进行各类自定义错误的处理,所有的错误处理是集中的,细颗粒度的错误代码和消息也是集中维护,便于扩展。

flask 官方文档和一些网上的资料都说比较简单,实践中摸索了这样的实现方式供参考。

(首发简书

女神节

(首发简书

公司从去年开始非常重视文化细节,很多地方可以和优秀外企媲美,企业文化只是口号怎么行,当然要落地,各类节日对员工的关心肯定需要。

员工也不傻,企业是真用心,还是走走形式,也分得清。

女神节,hr很早就开始筹划,然后拍照、打印、在昨天晚上放到每个女员工的桌子上,还要放上小礼物,在公共区域还有照片墙,效果很棒。

企业文化已经谈了几十年,说简单也简单,用不用心自己知道,员工也知道。走形式,哪怕花费再多金钱,不走心,没用。

简书-简单书写,目标之一

自己维护一个blog的成本不低,主要是时间上的。虽然wordpress是越做越好,让人感叹!

比大多数人,我还是愿意写作和分享。

今年的突破还是继续在公众号实践,估计下半年和同事们会建立一个关于机器学习人工智能方面的公众号。

基本决定隔了20年之后,再写一些书,作为小结。

简书也是这两年观察下来做的不错现代媒体,尝试快速发表一些东西。与时俱进。

我在简书的文章入口

三月早春

突然发现2月没有在这里写啥文字。一年年时间的确飞快。1月底又去了台北,阳明山、台北故宫、101,或熟悉,或陌生。

第一次去故宫和101,还是2013年11月,记得一行人在垦丁闲逛,当时其实住在新北,现在新北好像算并入台北了。颇为窘迫的是从台北回来的时候,由于一些阴差阳错,差点住的地方都没有。往事虽然略心酸,苦中作乐。

勇于挑战自己,以前有一段时间老想着要留些什么给以后,现在方觉得这样活岂不太累。人生要写意一些,每一刻努力,自然有沉淀,以后的事情想太多也未必有用。

今年春节早,工作上已经进入了忙碌,诸多挑战,压力大,也有趣。琢磨着今年是否要写一本书作为这几年工作的记录,大数据、机器学习、python,似乎都不错。写书的确比较难,选题、文字功力、坚持诸多种种,似乎平时还是积累的略少了一些。