本 blog 不再更新

时间精力有限,本 blog 不再更新了。创意纪这个域名这个 blog 从2004年陪伴我到今天,和我一起经历了人生的很多风风雨雨。

到了这个岁数,要会做减法,所以不更新那么多内容了。

所有内容迁移到 明日会, 明日会的服务器也在国内,访问也会好很多。

昨日之不忘,明日之师也。

井底之蛙

回看十年前的自己,像个井底之蛙。

当时比较空,也自认为很懂互联网,写了不少 blog,包括讨论淘宝有没有盈利模式,支付宝水平如何之类。

今天“蚂蚁金服”一书的作者来公司沙龙交流,我也看了这本书大部分的内容。

我觉得在2005-2009年看淘宝、支付宝很多观点没有错,但是万万没想到的是,阿里巴巴这么厉害,具有极强的创造力、执行力、自我修复的能力。

我们boss周说得好,阿里绝对不是只会卖假货。所以,此刻它是一家伟大的世界级的公司。

金融工作会议之后,监管更严,然后 AT 这两个公司已经大的没边了, 那么是不是没有机会呢,绝对不会。

或许这真的是一次更好的机会,伟大的公司都不是一天建成的。

必须放下所有没有必要的矜持,虚心学习,这样才不会太差。这几年的改变已经让我隐隐感觉到当年的自己其实是多么无知和自大。

还好现在有些意识到了,敬畏之心,好奇之心,刻苦之心。不能再做井底之蛙。

七月流火

上海,昨天,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很早就开始筹划,然后拍照、打印、在昨天晚上放到每个女员工的桌子上,还要放上小礼物,在公共区域还有照片墙,效果很棒。

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