socketio与apscheduler并用

2019年4月28日 10:16

 

 说明

 
flask项目引入了flask-socketio提供websocket通信,同时需要flask-apscheduler完成定时任务。
 
 

 问题描述

 
项目初期只有socketio,并且以gunicron运行
 
gunicorn --worker-class eventlet -w 1 zhima_chat:app -b 0.0.0.0:5000 --access-logfile -
 
后来要引入apscheduler
 
以上面的方式运行,出现了问题。该如何将socketio与apschedeuler结合呢?
 
 

Tags: flask apscheduler python socketio
评论(0) 阅读(937)

使用numba的姿势不正确反而导致性能下降

2019年1月20日 09:24

numba能够极大的提高python在计算方面的性能。是不是所有的python代码上,都可以加上numba.jit装饰器?答案是否定的。
 
 

Tags: python 性能
评论(0) 阅读(1740)

用最简单方法解决api接口安全问题,几乎无法破解

2019年1月01日 11:45

 

 场景描述

 
项目需要为第三方提供api服务接口。接口涉及到核心功能,如何保证接口安全。防止伪造身份、篡改数据?
 

思路

 
保障数据安全最好的方法,当然是加密了。无法解析内容,自然无法伪造,篡改。

可是使用https证书需要收费的。有其它方法么?

有的。

消息哈希认证(hmac)。
 
 

 算法描述

 
*  访问者
 
1. 当访问接口时, 将参数按key值排序,组成key1=value1&key2=value2&....&secret_key=...
2. 然后对上面结果做md5,生成签名sign
3. 将sign放到加入请求的参数
 
* 被访问者
 
密钥是被访问者提供了,它也有访问者的secret_key.
1.根据app_id查到secret_key
2.处理请求参数,按规则组成key1=value1&key2=value2....&secret_key=...
3.对上一步结果做md5,生成sign。比较两个sign,相等则身份验证通过
 

效果

 
1. 密钥只存在双方机器上,不可能被截取
2. 签名无法伪造,同样身份无法伪造、消息无法被篡改
 
使用了hmac认证,接口被破解基本是不可能的
 

python实现

 
import md5

app_id=123
secret_key="xxxxxxxx"

request_param = dict(
    key1="value1",
    key2="value2",
    key3="value3"
)

def sign():
    params = ["%s=%s" % (key, value) for key, value in sorted(request_param.items(), key=lambda item: item[0])]
    params.append("secret_key=%s" % secret_key)
    str_param = "&".join(params)
    print str_param
    md = md5.md5()
    md.update(str_param)
    return md.hexdigest()

if __name__ == '__main__':
    print(sign())
 
 
来源
 

 

Tags: web python
评论(0) 阅读(1969)

快速生成千万条mysql数据

2018年9月06日 05:33

目的

学习、测试mysql大数据场景,需要先生成大量数据。
 

思路

mysql官方文档说得很清楚。"load data infile"导入数据比insert要快20倍。所以我们先生成一千万条数据的文件。
然后将数据导入表中。
 
## 生成数据
假如有个用户表(id, username,password, age, sex),id是自动增长,我们现在需要生成username等信息
生成一千万条数据,速度还能接受,耗时236秒,文件大小315M。
 
import string
import random

def random_str(length=1):
    template = string.letters + string.digits
    chars = random.sample(template, length)
    return "".join(chars)

def generate_record():
    """
    username/password/age/sex
    """
    length = random.randint(6, 20)
    username = random_str(length)

    length = random.randint(6, 20)
    password = random_str(length)

    age = random.randint(10, 100)
    sex = random.choice([0, 1])
    return [username, password, age, sex]

def create_file(num=10000000):
    with open("user_data.txt", "w") as f:
        for i in range(num):
            row = generate_record()
            f.write(",".join(map(str, row))+"\n")

if __name__ == '__main__':
    import datetime
    start = datetime.datetime.now()
    create_file()
    end = datetime.datetime.now()
    cost = (end -start).total_seconds()
    print("cost: %s" % cost)
#一千万条,耗时236s,文件315M
 

导入

load data infile命令有安全限制,最好是把数据拿到mysql server端,再通过mysql -uxxx -pxxx进入命令,再导入。
我的虚拟机导入耗时57秒
 
load data infile "/user_data.txt" into table user
fields terminated by ','
lines terminated by '\n'
(username, password, age, sex);
 
 

其它方式

  • 测试工具sysbench
sysbench是批量insert,性能比不上导入。但是它更接近实际场景
 
  • 存储过程
速度很快,但是不如用熟悉的脚本方便
 
此生必看的科学实验-水知道答案
《了凡四训》详解之改过之法
印光大师十念法(胡小林主讲第1集)
 

Tags: python
评论(0) 阅读(486)

python2字符串在内存中如何存放

2018年5月14日 14:07

  • str类型
存在磁盘上的格式与存在内存中格式一致,例如ascii编码占一个字节,utf-8编码中文3个字节,英文1个字节
gbk编码中文2个字节,英文一个字节
 
注意python2是不会自动转换成unicode格式
 
  • unicode类型
python2用来支持多语言,不同编码类型的str转换需要通过它
unicode表示字符串属于逻辑层面,字节串(str)表示存放格式属于物理层面,如ascii,utf-8,gbk属于字节串
 
  • ascii在内存中字节数(utf-8/gbk同样1个字节)
>>> sys.getsizeof("a")       #pyton做了包装,包含了其它数据内容
38
>>> sys.getsizeof("aa") - sys.getsizeof("a")   # 将字符重复一个求差值,可知单个字符长度
1
 
  • unicode在内存中长度(python2中4个字节)
>>> sys.getsizeof(u"aa") - sys.getsizeof(u"a")   #python2中4个字节、python3中2个字节
4
>>> sys.getsizeof(u"你你") - sys.getsizeof(u"你")
4
 
  • utf-8长度(3个字节)
>>> a1,a2="a".encode("utf-8"),"aa".encode("utf-8")
>>> sys.getsizeof(a2) - sys.getsizeof(a1)  #英文一个字节
1

>>> b1,b2="你".decode("utf-8").encode("utf-8"),"你你".decode("utf-8").encode("utf-8")
>>> sys.getsizeof(b2) - sys.getsizeof(b1)   #中文三个字节
3
同样的方法可以知道gbk英文一个字节,中文2个字节
 
 
印光大师十念法(胡小林主讲第1集)

 

Tags: python
评论(0) 阅读(546)

gbk英文字符占几个字节

2018年5月14日 12:24

  • gbk英文字符占几个字节
➜  ~ python3
>>> bytes("你", "gbk")
b'\xc4\xe3'
>>> bytes("a", "gbk")
b'a'
>>> bytes("你", "utf-8")
b'\xe4\xbd\xa0'
>>> bytes("a", "utf-8")
b'a'
gbk中文2个字节,英文1个字节;utf-8中文3个字节,英文1个字节
 
  • 字符占几个字节
英文字母:
字节数 : 1;编码:GB2312
字节数 : 1;编码:GBK
字节数 : 1;编码:GB18030
字节数 : 1;编码:ISO-8859-1(latin-1)
字节数 : 1;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE


中文汉字:
字节数 : 2;编码:GB2312
字节数 : 2;编码:GBK
字节数 : 2;编码:GB18030
字节数 : 1;编码:ISO-8859-1(latin-1)
字节数 : 3;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE
 
 
印光大师十念法(胡小林主讲第1集)

 

Tags: python
评论(0) 阅读(561)

32位python的bug:os.system返回码一直为0

2016年9月26日 20:33

32位python在windows上调用命令行(os.system或subprocess.Popen)。执行后,如果返回码太大,python取得的返回值也是0。此时无法判断执行成功还是失败,这个是32位python的bug。
 
以时间同步命令w32tm位例子

在cmd上执行

C:\WINDOWS\system32>w32tm /resync
发生下列错误: 服务尚未启动。 (0x80070426)

C:\WINDOWS\system32>echo %errorlevel%
-2147023834

在64位python上执行

>>> os.system("w32tm /resync")
发生下列错误: 服务尚未启动。 (0x80070426)
-2147023834

在32位python上执行

>>> os.system("w32tm /resync")
发生下列错误: 服务尚未启动。 (0x80070426)
0
注意:此时命令执行错误的返回码也是0。
通常成功返回码才是0,这里执行错误,返回码却是也0。当要判断执行成功还失败时,这里便是个坑。
  • os.system文档
https://docs.python.org/2/library/os.html
 

Tags: popen system python
评论(0) 阅读(1382)

django如何使用restful风格

2015年6月06日 15:24

个人比较喜欢restful风格,以为django要安装rest framework才支持restful. 偶然发现只需继承View类即可.
 
from django.views.generic import View

class TaskView(View):
    # 获取
    def get(self, request, *args, **kwargs):
        print request.GET
    # 新建
    def post(self, request, *args, **kwargs):
        print request.POST
    # 更新
    def put(self, request, *args, **kwargs):
        print request.body
    # 删除
    def delete(self, request, *args, **kwargs):
        print request.body

# 路径配置
#url(r'task/$', TaskView.as_view())
 

Tags: python
评论(0) 阅读(1502)

基于python的最简单jQuery File Upload示例

2015年3月27日 13:42

找到个很不错的文件上传插件jQuery File Upload. 资料太少. 只能自己搭个环境,照着例子摸索. 奈何最简单的例子是基于php的, 不熟. 弄了个基于python的例子.
  • github
https://github.com/blueimp/jQuery-File-Upload
  • 目录
使用flask做了个简单web服务器,接收上传请求. 目录结构如下
https://github.c➜  flask-demo  tree
.
├── app.py
├── static
│   ├── 123.txt
│   └── file-upload
│       ├── angularjs.html
│       ├── basic.html
│       ├── basic-plus.html
│       ├── blueimp-file-upload.jquery.json
│       ├── bower.json
│       ├── CONTRIBUTING.md
│       ├── cors
│       │   ├── postmessage.html
│       │   └── result.html
│       ├── css
│       │   ├── demo.css
│       │   ├── demo-ie8.css
│       │   ├── jquery.fileupload.css
│       │   ├── jquery.fileupload-noscript.css
│       │   ├── jquery.fileupload-ui.css
│       │   ├── jquery.fileupload-ui-noscript.css
│       │   └── style.css
│       ├── Gruntfile.js
│       ├── img
│       │   ├── loading.gif
│       │   └── progressbar.gif
│       ├── index.html
│       ├── jquery-ui.html
│       ├── js
│       │   ├── app.js
│       │   ├── cors
│       │   │   ├── jquery.postmessage-transport.js
│       │   │   └── jquery.xdr-transport.js
│       │   ├── jquery.fileupload-angular.js
│       │   ├── jquery.fileupload-audio.js
│       │   ├── jquery.fileupload-image.js
│       │   ├── jquery.fileupload-jquery-ui.js
│       │   ├── jquery.fileupload.js
│       │   ├── jquery.fileupload-process.js
│       │   ├── jquery.fileupload-ui.js
│       │   ├── jquery.fileupload-validate.js
│       │   ├── jquery.fileupload-video.js
│       │   ├── jquery.iframe-transport.js
│       │   ├── jquery.min.js
│       │   ├── main.js
│       │   └── vendor
│       │       └── jquery.ui.widget.js
│       ├── package.json
│       ├── README.md
│       ├── server
│       │   ├── gae-go
│       │   │   ├── app
│       │   │   │   └── main.go
│       │   │   ├── app.yaml
│       │   │   └── static
│       │   │       ├── favicon.ico
│       │   │       └── robots.txt
│       │   ├── gae-python
│       │   │   ├── app.yaml
│       │   │   ├── main.py
│       │   │   └── static
│       │   │       ├── favicon.ico
│       │   │       └── robots.txt
│       │   ├── node
│       │   │   ├── package.json
│       │   │   ├── public
│       │   │   │   └── files
│       │   │   │       └── thumbnail
│       │   │   ├── server.js
│       │   │   └── tmp
│       │   └── php
│       │       ├── files
│       │       ├── index.php
│       │       └── UploadHandler.php
│       ├── test
│       │   ├── index.html
│       │   └── test.js
│       └── test.html
└── templates
    └── index.html

23 directories, 57 filesom/blueimp/jQuery-File-Upload
  • app.py
#encoding=utf-8
from flask import Flask
from flask import request
from flask import abort, redirect, url_for
from flask import render_template
import json

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['files[]']
        filename = f.filename
        minetype = f.content_type
        f.save('static/' + filename)
    return json.dumps({"files": [{"name": filename, "minetype": minetype}]})


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=7000, debug=True)
  • demo.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jQuery File Upload 示例</title>
</head>
<body>
<input id="fileupload" type="file" name="files[]" data-url="/upload" multiple>
<script src="/static/file-upload/js/jquery.min.js"></script>
<script src="/static/file-upload/js/vendor/jquery.ui.widget.js"></script>
<script src="/static/file-upload/js/jquery.iframe-transport.js"></script>
<script src="/static/file-upload/js/jquery.fileupload.js"></script>
<script>
$(function () {
    $('#fileupload').fileupload({
        dataType: 'json',
        done: function (e, data) {
            $.each(data.result.files, function (index, file) {
                $('<p/>').text(file.name).appendTo(document.body);
            });
        }
    });
});
</script>
</body> 
</html>
试了之后,确实很不错.
 

Tags: python flask jquery
评论(8) 阅读(8386)

理解select模块--等待IO完成

2014年1月26日 17:24

Tags: 非阻塞 python
评论(0) 阅读(1565)