menu Chancel's Blog
rss_feed lightbulb_outline

我的笔记

Python3 - Flask-Caching的过期时间设置(Flask缓存插件)

Flask-Caching是一个用于Flask框架的缓存插件,既支持高度的自定义继承开发,也支持简单的缓存存取,简单的缓存存取如下

from flask import Flask
from flask_caching import Cache

app = Flask(__name__)
app_cache = Cache(config={'CACHE_TYPE': 'filesystem', "CACHE_DEFAULT_TIMEOUT": 10, 'CACHE_DIR': '/tmp'})
app_cache.init_app(app)

@app.route("/")
def index():
    code = random.randint(0,9)
    if code is not None:
        cache.set("code", code)
    return render_templete_striing("<html><body>your code is {{code}}</body></html>")

@app.route("/login/<code>")
def login(code):
    cache_code = cache.get("code")
    if code == cache_code
        return render_templete_striing("<html><body>valid {{code}} !</body></html>")
    return render_templete_striing("<html><body>invalid {{code}} !</body></html>")

然而当我需要持久化缓存的时候,却发现Flask-Caching - 文档里对缓存过期参数 CACHEDEFAULTTIMEOUT 的描述只有

The default timeout that is used if no timeout is specified. Unit of time is seconds.

经过一番查找,在How can I configure Flask-Cache with infinite timeout -- stack overflow看到比较靠谱的答案

当使用 cache.set()的时候,如不传入timeout参数,则默认使用 CACHEDEFAULTTIMEOUT 参数的过期时间,如需持久化该缓存,则使用 timeout=0 即可

如下

from flask import Flask
from flask_caching import Cache

app = Flask(__name__)
app_cache = Cache(config={'CACHE_TYPE': 'filesystem', "CACHE_DEFAULT_TIMEOUT": 10, 'CACHE_DIR': '/tmp'})
app_cache.init_app(app)

cache.set("key", "value", timeout=0)

Develop Technology Python 2021-02-08 18:46:47

Python - 缓存字典到本地(支持多线程写入/读取)

缓存字典到本地(支持多线程写入/读取)

def GetIDTagDictByLocalTMP(id_tag: str):
    if ID_TAG_CACHE.get(id_tag):
        return ID_TAG_CACHE.get(id_tag)
    id_tag_dict = {'id': id_tag}
    SetIDTagDictToLocalTMP(id_tag, id_tag_dict)
    return id_tag_dict


def SetIDTagDictToLocalTMP(id_tag: str, id_tag_dict: dict):
    if not os.path.exists('tmp'):
        os.mkdir('tmp')
    ID_TAG_CACHE[id_tag] = id_tag_dict
    with open('cache/ID-TAG.json', 'w') as f:
        f.write(json.dumps(ID_TAG_CACHE, ensure_ascii=False))

def BuildIDTagCacheByLocalTmp():
    global ID_TAG_CACHE
    if not os.path.exists('cache'):
        os.mkdir('cache')
    if not os.path.exists('cache/ID-TAG.json'):
        return
    with open('cache/ID-TAG.json', 'r') as f:
        ID_TAG_CACHE = json.loads(f.read())

Develop Technology Python 2021-02-04 11:26:59

Python - 导出MySQL视图

import pymysql

'''
请按规则补充以下信息,并运行该脚本,即可获取按顺序导出的视图
    HOST:数据库IP地址
    PORT:数据库端口
    USER:用户名称
    PASSWD:用户密码
    DB_NAME:数据库名称
    CHARSET:编码格式(中文可默认 utf8mb4 )
'''

HOST = '192.168.11.214'
PORT = 3306
USER = 'root'
PASSWD = 'wosyangshu'
DB_NAME = 'syncthing_manage'
CHARSET = 'utf8mb4'


conn = pymysql.connect(host=HOST, port=PORT, user=USER,
                       passwd=PASSWD, db=DB_NAME, charset=CHARSET)


def process_rely(parmas={}, rely_old=[]):
    _rely = []
    _keys = list(parmas.keys())
    for k in rely_old:
        for bl in _keys:
            if str(parmas[k]).find(bl) > -1:
                if bl not in _rely:
                    if k not in _rely:
                        _rely.append(bl)
                    else:
                        i = _rely.index(k)
                        _rely.insert(i, bl)
                else:
                    if k in _rely:
                        i = _rely.index(k)
                        j = _rely.index(bl)
                        if i < j:
                            del _rely[j]
                            _rely.insert(i, bl)
        if k not in _rely:
            _rely.append(k)
    return _rely


cur = conn.cursor()
cur.execute('select TABLE_NAME, VIEW_DEFINITION from  information_schema.VIEWS where TABLE_SCHEMA = %s ', DB_NAME)
rs = cur.fetchall()
cur.close()
conn.close()

ps = {}
for al in rs:
    ps['`' + al[0] + '`'] = al[1]

rely = process_rely(ps, list(ps.keys()))
# rely = process_rely(ps, rely1)

file_object = open('view.sql', 'w')
for al in rely:
    file_object.write('DROP VIEW IF EXISTS ' + al + ';\n')
    file_object.write('CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW ' + al +
                      ' AS ' + ps[al] + ';\n\n')

file_object.close()

Develop Technology Python 2021-02-04 11:25:17

Python - 登录二次验证实现

Python二次登录验证的实现,依赖于pyotp包

import pyotp

sec = pyotp.random_base32()
totp = pyotp.totp.TOTP(sec,interval=60)
qr_code_text = totp.provisioning_uri(name='Chancel.Yang', issuer_name='Secure App')
print('登录二次验证器创建成功,二维码数据->%s' % qr_code_text)

# 可选:生成验证码步骤
import qrcode
img = qrcode.make(qr_uri)
img.get_image().show()

```

Develop Technology Python 2021-02-04 11:19:20

Python - 命令行参数解析

命令行参数有两种

# 参数一
python3 main.py agrs1 agrs2 agrs3
# 参数二
python3 main.py -a aaa -b bbb

参数一的识别获取

import sys

print('输出的参数个数为:%d个参数' % len(sys.argv))
print('输出参数列表%s' % str(sys.argv))

调用输出如下

❯ python3 test.py a b c                                                    
输出的参数个数为:4个参数
输出参数列表['test.py', 'a', 'b', 'c']


参数二的识别获取

import argparse

parser = argpaimport argparse
rse.ArgumentParser(description='Test for argparse')
parser.add_argument('--port', '-p', help='端口参数', default='8220')
parser.add_argument('--config', '-c', help='配置文件路径', default='config.ini')
args = parser.parse_args()

print('port参数:%s,config参数:%s' % (args.port,agrs.config))

调用输出如下

❯ python3 test.py -p 20931 -c /home/apps/fuck                              
port参数:20931,config参数:/home/apps/fuck

Develop Technology Python 2021-02-01 17:17:10

Python3 - python-markdown2 代码颜色渲染

python-markdown2是Python一个将Markdown文本翻译成HTML文档的第三方库,仓库传送门:trentm/python-markdown2

Markdown is a light text markup format and a processor to convert that to HTML.

访问文档的扩展插件部分说明页面(Extras provided by markdown2.py

可以看code-color扩展插件部分,按照作者的说法,这部分已经在1.3.0版本之后废弃不用了,改用 fenced-code-blocks扩展插件

使用扩展插件方法,只需要在执行转换的方法时候添加扩展插件参数

import markdown2

markdown_extras = ['fenced-code-blocks']
html_content = markdown2.markdown(article_content.a_content, extras=g.markdown_extras)

可以看到生成的 html_content文档的div节点class属性是codehilite,其子元素的class也标记上了

最后一步我们只需要引入pygments-css的CSS文件,将引入的CSS文件class类名从highlight 修改成 codehilite,就可以将代码颜色渲染了

Develop Technology Python 2021-01-20 15:23:42

Python3 - 复制文件到别的文件夹下

Python3复制文件

import os
import shutil

def copy_file(src_file_path:str,target_file_path:str):
    if not os.path.isfile(src_file_path):
        return False
    file_path=os.path.split(target_file_path)[0]
    if not os.path.exists(file_path):
        os.makedirs(file_path)            
    shutil.copyfile(src_file_path,target_file_path)  

if __name__ == '__main__':
    copy_file('C:\\A\\fuck.txt','c:\\B\\fuck.txt')

Develop Technology Python 2021-01-18 14:56:14

Python3 - 递归获取目录下的所有文件(含子目录内文件)

Python3递归获取目录下的所有文件(含子目录内文件)

测试版本:Python3.6.9

import os

def get_list_by_folder(path):
    list_name = []
    for file in os.listdir(path):
        file_path = os.path.join(path, file)
        if not os.path.isdir(file_path):
            list_name.append(file_path)
        else:
            list_name.extend(GetListByFolder(file_path))
    return list_name

if __name__=='__main__':
    file_list = get_list_by_folder("./")
    print(file_list)

Develop Technology Python 2021-01-18 14:48:07

Python - ConfigParser 键值大小写转换

在Windows中,INI文件默认不区别大小写,所以ConfigParser在读取INI文件时将丢失大小写信息

这一点,在文末的官方附录上有说明,修改也非常简单,ConfigParser允许传递一个返回字符串函数作为替换自带的解析字符串函数

to a function that takes a string argument and returns a string

实际例子如下

app_config_parser = ConfigParser()
app_config_parser.optionxform = str

参考资料

Develop Technology Python 2020-11-16 04:10:45

Python - No module name 'Crypto'

在Windows上使用pip安装 crypto

pip3 install crypto

尝试导入crypto的对象时候出现错误

>>> from Crypto.Cipher import AES
Traceback (most recent call last):
    File "<stdin>" , line 1, in <module>
NoduleNotFoundError: No module name 'Crypto'

原因:crypto在python上面的名字是pycrypto,它是一个第三方库,但是已经停止更新三年了

分2步解决这个问题

  1. 卸载crypto然后安装pycryptodome Shell pip3 uninstall crypto pip3 install pycryptodome
  2. 定位到Python的安装目录,找到Libsite-packages,将crypto文件夹的首字母改成大写就可以了,crypto->Crypto

Linux只需要第一步

Develop Technology Python 2020-11-14 03:46:06

1 of 2 | A total of 14