Python 全栈系列241 GFGo Lite迭代

news2024/9/28 7:23:56

说明

随着整个算网开发逐渐深入,各个组件、微服务的数量、深度在不断增加。由于算网是个人项目,我一直按照MVP(Minimum Viable Product )的原则在推进。由于最初的时候对架构、算法和业务的理解并没有那么深刻,所以MVP的内容还是在不断变化(增加)的。比较幸运的是,中间走的弯路比较少,整体方向上一直没有大偏差,应该可以在预期的时间内达到目标。

从工具和使用的角度来看,我一边在算网的概念下构造工具,一边在尝试使用这些工具提高我的效率/能力上限。过去,由于已知的、明确要实现的功能就很多,所以一直是不断急速前进,常见的一种情况是:工具开发好了,测试也好用,但是就扔在一边,继续开发别的新工具去了。

现在的情况是:完成一个MVP所需要新开发的功能几乎没有了,反而是将已有的工具用起来比较重要。

今年做的比较重要的改变是使用streamlit、gradio将微服务前后端一体化。这种方式最初是大语言模型广泛采用的,的确非常方便。对算网而言,大量的已开发组件和功能,将通过这种方式进行文档、测试和使用的一体化。

在这里插入图片描述

总之,现在的重点是实现(Realization)。

内容

1 GlobalFunc更新

1.1 程序

目前仍然采用vscode代码开发的方式,创建一个个新的py文件。

1.2 推送更新

步骤如下:

  • 1 切到项目路径下cd .../m4git/GlobalFunc
  • 2 导入操作对象
from op044_GlobalFunc_01BaseOpt import gfbase

# 1 查看当前分枝
gfbase._get_current_branch()
# 2 扫描所有文件的信息
scan_dict = gfbase._get_scan_files()
# 3 提交git项目
gfbase._simple_commit_git()
# 4 刷新一个包的初始化文件
gfbase._generate_init_py('Base')
gfbase._generate_init_py('Parse')
gfbase._generate_init_py('TFIDF')
# 5 批量存储函数
some_pack_list = [x for x in scan_dict.keys() if x.startswith('Base.') or x.startswith('Parse.') or x.startswith('TFIDF.')]

for some_file in some_pack_list:
    gfbase._save_a_file_rom(some_file)

在这里插入图片描述

2 GFGo Lite 更新

GFGo Lite 有所修改,文件在项目文件夹gfgo_lite_24090 下面

2.1 文件

切入gfgo_lite_build容器,里面已经有了一些依赖文件

  • 1 init_funcs 里面存放了数据库连接相关的函数
  • 2 按模块执行加载,然后初始化

以下是从Base模块中加载一些函数的示例

from init_funcs import create_file,generate_init_py,RedisOrMongo, Naive

import os 
import json
# 声明空间

# 在容器中启动
redis_cfg = Naive()
redis_cfg.redis_agent_host = 'http://172.17.0.1:24021/'
redis_cfg.redis_connection_hash = None


# 模块Base
if True:

    # 声明当前要创建的程序文件夹:默认为funcs
    target_folder = 'GlobalFunc'
    tier1 = 'sp_GlobalFunc'
    var_space_name = 'Base'
    # 分支,一般默认为master
    branch_name = 'master' 
    tier2 = '_'.join([var_space_name, branch_name])
    the_space_name = '.'.join([tier1,tier2])


    target_folder = target_folder + '/' + var_space_name

    os.makedirs(target_folder, exist_ok=True)

    rom = RedisOrMongo(the_space_name, redis_cfg.dict(),backend='mongo', mongo_servername='m7.24065')

    # 这个一般根据需要,或者代码中得来 --- 需要的列表项
    func_list = [ 'from_pickle','to_pickle','is_file_exists',
    'gen_time_axis','ATimer2','get_time_str1','cols2s',
    'create_folder_if_notexist','flat_dict','flatten_list'
    ]
    # func_list = [ 'from_pickle','to_pickle','pose_a_file']
    for some_name in func_list:
        # 获取 meta,data : data就是代码字符
        the_data = rom.getx(some_name)
        filename = the_data['meta']['name']
        filedata = the_data['data']
        create_file(target_folder, filename, filedata)


    # 生成初始化文件
    generate_init_py(target_folder)

在导入新的包时,需要手动修改GlobalFunc下的__init__.py(与Base包和Parse包平级)。

from . import Base
from . import Parse

2.2 服务

/workspace下直接启动服务即可 python3 server.py

3 应用

3.1 通用函数 UCS

UCS是一个规范,为了支持这个规范,必须依赖一些特定(同时也是固定)的函数。因为函数的通用性,所以这些函数放在了最外层,每个函数都占据了一个api接口。

3.1.1 block (int)

整型block分割三件套

import requests as req 


some_dict = {}
some_dict['rec_id'] = 111111

res = req.post('http://127.0.0.1:8000/get_brick_name/', json = some_dict).json()

'0.0.0.11'

some_dict = {}
some_dict['brick_name'] = '0.0.0.11'

res = req.post('http://127.0.0.1:8000/get_brick_bounds/', json = some_dict).json()
[110000.0, 120000.0]


some_dict = {}
some_dict['start_brick_name'] = '0.0.0.9'
some_dict['end_brick_name'] = '0.0.0.12'

res = req.post('http://127.0.0.1:8000/get_brick_list/', json = some_dict).json()
['0.0.0.9', '0.0.0.10', '0.0.0.11'
3.1.2 time block

操作如下:时间支持字符和数值(时间戳)两种模式。

import requests as req 

# char
some_dict = {}
some_dict['dt_str_or_ts'] = '2024-01-31 11:11:11'
res = req.post('http://127.0.0.1:8000/get_time_brick_name/', json = some_dict).json()
'2024.01.31.11'

# num
some_dict = {}
some_dict['dt_str_or_ts'] = 1706670671
res = req.post('http://127.0.0.1:8000/get_time_brick_name/', json = some_dict).json()
'2024.01.31.11'

# char 
some_dict = {}
some_dict['brick_name'] = '2024.01.31.11'
some_dict['char_or_num'] = 'char'
res = req.post('http://127.0.0.1:8000/get_time_brick_bounds/', json = some_dict).json()

'''
In [13]: res
Out[13]: ['2024-01-31 11:00:00', '2024-01-31 12:00:00']
'''

# num 
some_dict = {}
some_dict['brick_name'] = '2024.01.31.11'
some_dict['char_or_num'] = 'num'
res = req.post('http://127.0.0.1:8000/get_time_brick_bounds/', json = some_dict).json()

'''
In [15]: res
Out[15]: [1706670000, 1706673600]
'''


some_dict = {}
some_dict['start_brick_name'] = '2024.01.31.11'
some_dict['end_brick_name'] = '2024.02.02.11'
res = req.post('http://127.0.0.1:8000/get_time_brick_list/', json = some_dict).json()

'''
In [11]: res
Out[11]:
['2024.01.31.11',
 '2024.01.31.12',
 '2024.01.31.13',
 '2024.01.31.14',
 ...
'''

3.2 功能函数

3.2.1 Base包的函数调用

以下是两个Base包函数的测试

import requests as req 

# 测试1:调用Base包的函数
kwargs = {'ts':None, 
             'bias_hours':8}
pack_func = 'Base.get_time_str1'

some_dict = {}
some_dict['kwargs'] = kwargs
some_dict['pack_func'] = pack_func

res = req.post('http://127.0.0.1:8000/gfgo/', json = some_dict).json()
'2024-05-05 11:04:35'

# 测试2:列表扁平化
kwargs = {'nested_list':[[1,2],[3],[4,5]]}
pack_func = 'Base.flatten_list'

some_dict = {}
some_dict['kwargs'] = kwargs
some_dict['pack_func'] = pack_func

res = req.post('http://127.0.0.1:8000/gfgo/', json = some_dict).json()
[1, 2, 3, 4, 5]

有两点需要注意:

  • 1 函数规范为全部关键字参数输入(主要是为了方便调用)
  • 2 接口直接返回处理信息(而不是包上状态和消息)
3.3.3 Parse包的函数调用
x = "This is a sample text."
word_list = ["sample", "test", "string"]

kwargs = {'x':x, 'word_list':word_list}
pack_func = 'Parse.judge_existence'

some_dict = {}
some_dict['kwargs'] = kwargs
some_dict['pack_func'] = pack_func

res = req.post('http://127.0.0.1:8000/gfgo/', json = some_dict).json()

True

3.4 服务迭代

推送新的变化
docker push myregistry.domain.com:24052/worker.andy.gfgo_lite_24090:v101
启动服务

docker run -d \
 --restart=always \
 --name=gfgo_lite_24090 \
 -v /etc/localtime:/etc/localtime  \
 -v /etc/timezone:/etc/timezone\
 -v /etc/hostname:/etc/hostname\
 -e "LANG=C.UTF-8" \
 -w /workspace\
 -p 24090:8000\
 myregistry.domain.com:24052/worker.andy.gfgo_lite_24090:v101 \
 sh -c "python3 server.py"

公网调用

In [3]:
   ...: some_dict = {}
   ...: some_dict['brick_name'] = '2024.01.31.11'
   ...: some_dict['char_or_num'] = 'num'
   ...: res = req.post('http://WAN_IP:24090/get_time_brick_bounds/', json = some_dict).json()

In [4]: res
Out[4]: [1706670000, 1706673600]

4 总结与展望

RuleSet As A Func

将复杂的规则(判定)作为一个函数调用。

Series Apply

每个函数都要支持列表(多个元素)的并行处理。

踩过的一个小坑:GlobalFunc使用了一个公网机的Redis做ROM,而GFGoLite使用m7本地的redis,导致了逻辑上看起来更新了,但是实际未更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构十:哈希表

本次将从概念上理解什么是哈希表,理论知识较多,满满干货,这也是面试笔试的一个重点区域。 目录 一、什么是哈希表 1.0 为什么会有哈希表? 1.1 哈希表的基本概念 1.2 基本思想 1.3 举例理解 1.4 存在的问题 1.5 总结 二、…

基于TL431基准电压源的可调恒压恒流源的Multisim电路仿真设计

1、线性电源的工作原理 在我们日常应用里,直流电是从市电或电网中的交流电获取的。例如15V直流电压源、24V直流电压源等等。交流电变为直流电的过程大概分为一下几步: 首先,交流电通过变压器降低其电压幅值。接着,经过整流电路进…

01_SpringBoot简单搭建入门程序

目录 1、先创建一个java项目2、导入依赖3、将Java项目修改为SpringBoot项目4、编写一个测试的Controller5、测试(创建一个*.http的文件)方式1:方式2:可以直接在浏览器访问该地址方式3:使用postman也可以 1、先创建一个java项目 我的项目结构…

智能化工单助力业务运作:亿发解析工单系统的功能与适用场景

在现代企业管理中,工单系统扮演着至关重要的角色。面对市面上众多的工单系统,我们可以根据不同的依据进行分类,以更好地满足企业的需求。 1、按部署方式分类: 按照部署方式可以分为本地化部署工单系统和云端SaaS服务工单系统。 …

步态识别论文(6)GaitDAN: Cross-view Gait Recognition via Adversarial Domain Adaptation

摘要: 视角变化导致步态外观存在显着差异。因此,识别跨视图场景中的步态是非常具有挑战性的。最近的方法要么在进行识别之前将步态从原始视图转换为目标视图,要么通过蛮力学习或解耦学习提取与相机视图无关的步态特征。然而,这些方法有许多约…

【java9】java9新特性之Optional类改进

其实Optional类在Java8中就引入了,用于避免null检查和NullPointerException指针问题。 在Java9中,Optional类得到了进一步的改进,增加了一些新的方法,使其更加灵活和易用。 以下是一些Java9中对Optional类的改进: s…

ssm106学生公寓管理系统的设计与实现+jsp

学生公寓管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本学生公寓管理系统就是在这样的大环境下诞生,其可以帮助管理者在短…

python数据分析——数据分析的统计推断

数据分析的统计推断 前言一、提出问题二、统计归纳方法三、统计推断四、统计推断步骤4.1.点估计4.2.区间估计4.2.1. 总体方差已知4.2.2总体方差未知 4.3. 假设检验4.4. 假设检验的假设4.5.显著性水平 五、检验统计量六、检验方法七、拒绝域八、假设检验步骤九、重要假设检验方法…

CGAL 网格简化

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 为了提高网格处理的效率,通常需要将过于冗长的3D数据集简化为更简洁而又真实的表示。尽管从几何压缩到逆向工程有许多应用,但简洁地捕捉表面的几何形状仍然是一项乏味的任务。CGAL中则为我们提供了一种通过变分几…

SpringBoot的ProblemDetails

1.RFC 7807 之前的项目如果出现异常,默认跳转到error页面。或者是抛出500 异常。 但是对于前后端分离的项目,Java程序员不负责页面跳转,只需要 把错误信息交给前端程序员处理即可。而RFC 7807规范就是将异常 信息转为JSON格式的数据。这个…

Golang | Leetcode Golang题解之第70题爬楼梯

题目: 题解: func climbStairs(n int) int {sqrt5 : math.Sqrt(5)pow1 : math.Pow((1sqrt5)/2, float64(n1))pow2 : math.Pow((1-sqrt5)/2, float64(n1))return int(math.Round((pow1 - pow2) / sqrt5)) }

5.Spring Security-web权限方案

设置登录的用户名和密码 1.通过配置文件设置用户名密码 spring:security:user:name: xiankejinpassword: 123456 如果没有以上配置,那么就会在后台生成一个随机密码,用户名固定位user。 2.通过配置类设置用户名密码 Configuration public class Sec…

[C++核心编程-02]----C++引用详解和使用方法分析

前言 在C中,引用是一个别名,它允许将一个已存在的变量或对象用不同的名称来访问。引用在定义时必须初始化,并且一旦初始化就不能再绑定其他对象,因此引用在声明时被初始化后就不能再改变引用对象。引用使用&符号进行声明。 引…

打印菱形

使用拆分法&#xff1a;空格和*分开打印 #include <stdio.h> int main() { int n 0; //行数 scanf("%d", &n); int i 0; //打印上半行 for (i 0; i < n; i) { int j 0; for (j 0; j < n - i - 1;…

玩comfyui踩过的坑之使用ComfyUI_Custom_NODES_ALEKPET翻译组件问题

环境&#xff1a; 秋叶安装包&#xff0c;安装ComfyUI_Custom_NODES_ALEKPET组件或者直接下载网盘中的包&#xff0c;直接解压包到comfyui根目录/custom_nodes/&#xff0c;重启后&#xff0c;按指导文件操作。 注意&#xff1a;网盘指导包中有配置好的流程json文件&#xff0…

【011】网上鲜花商店(SSM+JSP)

【011】网上鲜花商店(SSMJSP&#xff09; 一、系统情况介绍 网上鲜花商店分为前台端和后台端&#xff0c;是致力于可以便捷购花而开发的一套系统&#xff0c;可以按照不同种类进行分类管理&#xff0c;清晰客观的展示鲜花的详情信息以及价格等等&#xff0c;适合新手学习开发…

C++多态特性详解

目录 概念&#xff1a; 定义及实现&#xff1a; 虚函数重写的两个例外&#xff1a; 1.协变&#xff1a; 2.析构函数的重写&#xff1a; final关键字&#xff1a; override关键字&#xff1a; 多态是如何实现的&#xff08;底层&#xff09;&#xff1a; 面试题&#xff1…

代码审计之浅谈RASP技术

前言&#xff1a; 想摆会烂&#xff0c;所以就落个笔吧。 其实本来是想写关于iast技术的&#xff0c;但是认真思考了下&#xff0c;感觉笔者自己本身也不太能讲清楚iast技术&#xff0c;怕误人子弟。 所以最后还是基于笔者的理解以及实际应用写一篇关于RASP技术的文章&#xf…

酷我音乐无广VIP破姐版,支持蝰蛇音效,PC端 v9.2.0.0

01 软件介绍 酷我音乐是一款优质在线音乐播放服务软件&#xff0c;拥有全面的音乐版权库存&#xff0c;中国好声音、蒙面歌王、燃烧吧少年等热门综艺的版权&#xff0c;包括无损音质选项&#xff0c;并涵盖广泛多样的音乐类型&#xff0c;如华语、英语、粤语音乐&#xff0c;以…

[暂未实现]APP签名不同保留数据覆盖安装记录

APP签名不同无法直接覆盖安装 使用adb可以卸载应用同时保留数据&#xff0c;但签名不同也无法覆盖安装&#xff08;安装原来签名的应用打开和卸载前一样&#xff09; 使用adb导出应用数据&#xff08;QQ&#xff09;db文件只有1kb&#xff0c;显然此方法也行不通