first commit
This commit is contained in:
commit
f4179ad700
14
README.md
Normal file
14
README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# sage
|
||||
|
||||
a llm application, which can select differences llm avaiable in the backend, can interacts with the llm, if click the text widget in message showing area, the will call tts server to translate text inside the widget to audio and speak it out
|
||||
|
||||
# 变量定义
|
||||
为上层应用更方便,统一使用llm交互的变量名称
|
||||
## prompt
|
||||
指用户输入的文本信息
|
||||
## llmtext
|
||||
大模型返回的文本信息
|
||||
## attachfiles
|
||||
上传文件集
|
||||
##
|
||||
|
||||
50
apitools/README.md
Normal file
50
apitools/README.md
Normal file
@ -0,0 +1,50 @@
|
||||
# API tools
|
||||
this tool read api specific file in json format, and generates python code
|
||||
## json file format
|
||||
{
|
||||
"apiname":API name
|
||||
"title":API descriptions
|
||||
"description":
|
||||
"data":{
|
||||
}
|
||||
mapis:{
|
||||
methodname:mapi #each methos a key
|
||||
}
|
||||
}
|
||||
|
||||
mapi has following format
|
||||
{
|
||||
"title":name of the api
|
||||
"descriptions":"description of the api
|
||||
"url":call url for this api
|
||||
"method":http method
|
||||
"headers":haed need to set to
|
||||
"params":data will sent to api server
|
||||
"response_type":json, file,
|
||||
"response_error_type":"json"
|
||||
"response":resposne return from api server
|
||||
"error_field":
|
||||
"error_text_field":
|
||||
"returnData":[
|
||||
{
|
||||
"field":"sssss",
|
||||
"name":"ggggg"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
## header, params, response format
|
||||
{
|
||||
name:
|
||||
type:
|
||||
required:
|
||||
value:
|
||||
description
|
||||
}
|
||||
|
||||
## data in json file
|
||||
Use ${name} format to refer the data in API's data object,
|
||||
if name is not in data, replace ${name} as ""
|
||||
|
||||
## method call logic
|
||||
this tool just build all the method api function for coder, and not call logic implement
|
||||
0
app/README.md
Normal file
0
app/README.md
Normal file
174
app/ali_sms_send.py
Normal file
174
app/ali_sms_send.py
Normal file
@ -0,0 +1,174 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time: 2023/4/23 17:18
|
||||
|
||||
"""
|
||||
环境要求
|
||||
Python 3
|
||||
安装 SDK 核心库 OpenAPI ,使用pip安装包依赖:
|
||||
pip install alibabacloud_tea_openapi
|
||||
pip install alibabacloud_dysmsapi20170525
|
||||
"""
|
||||
|
||||
"""
|
||||
资源到期预警
|
||||
[开元云科技] 尊敬的用户, 您好!您的云服务器账号中将于 2023-01-14 23:59:59 到期, 为避免影响到您的使用, 请及时关注并续费!
|
||||
感谢您的支持。
|
||||
|
||||
资源到期通知
|
||||
[开元云科技] 尊敬的用户, 您好!您的云服务器已于昨天到期, 将于今天中午12:00关停服务, 为避免影响到您的使用, 请及时关注并续费!
|
||||
|
||||
新产品上线通知
|
||||
[开元云科技] 惠上云,更简单,新产品火热开售,王牌性价比,享触底尝鲜价,立即抢购: http://...
|
||||
|
||||
余额不足预警
|
||||
[开元云科技] 尊敬的用户,您好!您的余额还有${amount}$元, 为避免影响到您的使用, 请及时关注并续费!
|
||||
|
||||
"""
|
||||
|
||||
import random
|
||||
import re
|
||||
import asyncio
|
||||
# from core.exception import CustomException
|
||||
from alibabacloud_dysmsapi20170525.client import Client as Dysmsapi20170525Client
|
||||
from alibabacloud_tea_openapi import models as open_api_models
|
||||
from alibabacloud_dysmsapi20170525 import models as dysmsapi_20170525_models
|
||||
from alibabacloud_tea_util import models as util_models
|
||||
from alibabacloud_tea_util.client import Client as UtilClient
|
||||
import json
|
||||
import logging
|
||||
import datetime
|
||||
from sqlor.dbpools import DBPools
|
||||
from appPublic.uniqueID import getID as uuid
|
||||
|
||||
|
||||
class AliyunSMS:
|
||||
# 返回错误码对应:
|
||||
doc = "https://help.aliyun.com/document_detail/101346.html"
|
||||
|
||||
def __init__(self):
|
||||
self.access_key = 'LTAI5t5w7xsZgueod6uZ3TCD'
|
||||
self.access_key_secret = 'n1HttSbQvgEbjvf62Gzl1aagfKyIyS'
|
||||
self.sms_client = self.create_client(self.access_key,
|
||||
self.access_key_secret)
|
||||
self.sign_name = '开元云科技'
|
||||
self.sms_types = {
|
||||
"SMS_460770222": send_vcode,
|
||||
}
|
||||
|
||||
async def send(self, stype, type_code, phone, ns) -> dict:
|
||||
"""
|
||||
主程序入口,异步方式
|
||||
"""
|
||||
if isinstance(ns, dict):
|
||||
ns = json.dumps(ns)
|
||||
|
||||
send_sms_request = dysmsapi_20170525_models.SendSmsRequest(
|
||||
phone_numbers=phone,
|
||||
sign_name=self.sign_name,
|
||||
template_code=type_code,
|
||||
template_param=ns
|
||||
)
|
||||
runtime = util_models.RuntimeOptions()
|
||||
try:
|
||||
# 复制代码运行请自行打印 API 的返回值
|
||||
resp = await self.sms_client.send_sms_with_options_async(send_sms_request, runtime)
|
||||
return await self.__validation(stype=stype, type_code=type_code, ns=ns, phone=phone, resp=resp)
|
||||
except Exception as error:
|
||||
print(error)
|
||||
return {
|
||||
'status': False,
|
||||
'msg': error
|
||||
}
|
||||
# 如有需要,请打印 error
|
||||
|
||||
async def send_vcode(self, phone: str, stype: str, vcode) -> dict:
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
type_code_li = await sor.R('sms_template', {'name': stype})
|
||||
if type_code_li:
|
||||
type_code = type_code_li[0]['code']
|
||||
else:
|
||||
sms_record_log = {
|
||||
'id': uuid(),
|
||||
'send_type': stype,
|
||||
'mobile': phone,
|
||||
'message': str(vcode),
|
||||
'send_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
'send_status': 0,
|
||||
'remark': '无法找到:%s, 请查看字符串是否一致' % stype
|
||||
}
|
||||
await sor.C('sms_record', sms_record_log)
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'can not get type code from sms_template, please check...'
|
||||
}
|
||||
return await self.send(stype, type_code, phone, vcode)
|
||||
|
||||
async def __validation(self, stype, type_code, ns, phone, resp: dysmsapi_20170525_models.SendSmsResponse) -> dict:
|
||||
"""
|
||||
验证结果并返回
|
||||
"""
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
send_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
sms_record_log = {
|
||||
'id': uuid(),
|
||||
'send_type': stype,
|
||||
'mobile': phone,
|
||||
'message': str(ns),
|
||||
'send_time': send_time,
|
||||
'send_status': 1
|
||||
}
|
||||
if resp.body.code == "OK":
|
||||
msg = f'{send_time} {phone} 短信发送成功,返回code:{resp.body.code}'
|
||||
print(msg)
|
||||
sms_record_log['send_status'] = 1
|
||||
await sor.C('sms_record', sms_record_log)
|
||||
return {
|
||||
'status': True,
|
||||
'msg': msg
|
||||
}
|
||||
else:
|
||||
msg = f'{send_time} {phone} 短信发送失败,返回code:{resp.body.code},请参考文档:{self.doc}'
|
||||
print(msg)
|
||||
sms_record_log['send_status'] = 0
|
||||
sms_record_log['remark'] = msg
|
||||
await sor.C('sms_record', sms_record_log)
|
||||
return {
|
||||
'status': False,
|
||||
'msg': msg
|
||||
}
|
||||
|
||||
def create_client(self,
|
||||
access_key_id: str,
|
||||
access_key_secret: str,
|
||||
) -> Dysmsapi20170525Client:
|
||||
"""
|
||||
使用AK&SK初始化账号Client
|
||||
@param access_key_id:
|
||||
@param access_key_secret:
|
||||
@return: Client
|
||||
@throws Exception
|
||||
"""
|
||||
config = open_api_models.Config(
|
||||
# 您的 AccessKey ID,
|
||||
access_key_id=access_key_id,
|
||||
# 您的 AccessKey Secret,
|
||||
access_key_secret=access_key_secret
|
||||
)
|
||||
# 访问的域名
|
||||
config.endpoint = f'dysmsapi.aliyuncs.com'
|
||||
return Dysmsapi20170525Client(config)
|
||||
|
||||
|
||||
async def send_vcode(phone: str, stype:str, vcode: dict) -> dict:
|
||||
result = await AliyunSMS().send_vcode(phone, stype, vcode)
|
||||
return result
|
||||
|
||||
|
||||
# if __name__ == '__main__':
|
||||
# loop = asyncio.get_event_loop()
|
||||
# loop.run_until_complete(send_vcode('13801015291', '注册登录验证', {'code': '209898'}))
|
||||
# loop.run_until_complete(send_vcode('13801015291', '供应商结算提醒', {'name': '中金超算 济南超算'}))
|
||||
# loop.run_until_complete(send_vcode('13801015291', '到期续费通知', {'time': '2023-10-10'}))
|
||||
# AliyunSMS("13801015291").main_async()
|
||||
122
app/alisms.py
Normal file
122
app/alisms.py
Normal file
@ -0,0 +1,122 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time: 2023/4/23 17:18
|
||||
|
||||
"""
|
||||
环境要求
|
||||
Python 3
|
||||
安装 SDK 核心库 OpenAPI ,使用pip安装包依赖:
|
||||
pip install alibabacloud_tea_openapi
|
||||
pip install alibabacloud_dysmsapi20170525
|
||||
"""
|
||||
|
||||
"""
|
||||
资源到期预警
|
||||
[开元云科技] 尊敬的用户, 您好!您的云服务器账号中将于 2023-01-14 23:59:59 到期, 为避免影响到您的使用, 请及时关注并续费!
|
||||
感谢您的支持。
|
||||
|
||||
资源到期通知
|
||||
[开元云科技] 尊敬的用户, 您好!您的云服务器已于昨天到期, 将于今天中午12:00关停服务, 为避免影响到您的使用, 请及时关注并续费!
|
||||
|
||||
新产品上线通知
|
||||
[开元云科技] 惠上云,更简单,新产品火热开售,王牌性价比,享触底尝鲜价,立即抢购: http://...
|
||||
|
||||
余额不足预警
|
||||
[开元云科技] 尊敬的用户,您好!您的余额还有${amount}$元, 为避免影响到您的使用, 请及时关注并续费!
|
||||
|
||||
"""
|
||||
|
||||
import random
|
||||
import re
|
||||
import asyncio
|
||||
from alibabacloud_dysmsapi20170525.client import Client as Dysmsapi20170525Client
|
||||
from alibabacloud_tea_openapi import models as open_api_models
|
||||
from alibabacloud_dysmsapi20170525 import models as dysmsapi_20170525_models
|
||||
from alibabacloud_tea_util import models as util_models
|
||||
from alibabacloud_tea_util.client import Client as UtilClient
|
||||
import json
|
||||
from sqlor.dbpools import DBPools
|
||||
from appPublic.uniqueID import getID as uuid
|
||||
from appPublic.timeUtils import timestampstr
|
||||
from appPublic.log import info, debug, error, warning, critical, exception
|
||||
|
||||
|
||||
"""
|
||||
self.access_key = 'LTAI5t5w7xsZgueod6uZ3TCD'
|
||||
self.access_key_secret = 'n1HttSbQvgEbjvf62Gzl1aagfKyIyS'
|
||||
"""
|
||||
class AliSMS:
|
||||
# 返回错误码对应:
|
||||
doc = "https://help.aliyun.com/document_detail/101346.html"
|
||||
|
||||
def __init__(self, apikey, secretkey):
|
||||
self.access_key = apikey
|
||||
self.access_key_secret = secretkey
|
||||
self.sms_client = self.create_client(self.access_key,
|
||||
self.access_key_secret)
|
||||
self.sign_name = '开元云科技'
|
||||
|
||||
async def send_validate_code(self, cell_no, vcode):
|
||||
info(f'{cell_no=}, {vcode=}')
|
||||
return await self.send('SMS_460770222', cell_no, {'code':vcode})
|
||||
|
||||
async def send(self, type_code, phone, ns) -> dict:
|
||||
"""
|
||||
主程序入口,异步方式
|
||||
"""
|
||||
if isinstance(ns, dict):
|
||||
ns = json.dumps(ns)
|
||||
|
||||
send_sms_request = dysmsapi_20170525_models.SendSmsRequest(
|
||||
phone_numbers=phone,
|
||||
sign_name=self.sign_name,
|
||||
template_code=type_code,
|
||||
template_param=ns
|
||||
)
|
||||
runtime = util_models.RuntimeOptions()
|
||||
try:
|
||||
# 复制代码运行请自行打印 API 的返回值
|
||||
resp = await self.sms_client.send_sms_with_options_async(send_sms_request, runtime)
|
||||
if resp.body.code == "OK":
|
||||
return {
|
||||
'status': True
|
||||
}
|
||||
return {
|
||||
'status': False,
|
||||
'msg':f'{timestampstr()} {phone} 短信发送失败,返回code:{resp.body.code},请参考文档:{self.doc}'
|
||||
}
|
||||
except Exception as error:
|
||||
print(error)
|
||||
return {
|
||||
'status': False,
|
||||
'msg': error
|
||||
}
|
||||
|
||||
def create_client(self,
|
||||
access_key_id: str,
|
||||
access_key_secret: str,
|
||||
) -> Dysmsapi20170525Client:
|
||||
"""
|
||||
使用AK&SK初始化账号Client
|
||||
@param access_key_id:
|
||||
@param access_key_secret:
|
||||
@return: Client
|
||||
@throws Exception
|
||||
"""
|
||||
config = open_api_models.Config(
|
||||
# 您的 AccessKey ID,
|
||||
access_key_id=access_key_id,
|
||||
# 您的 AccessKey Secret,
|
||||
access_key_secret=access_key_secret
|
||||
)
|
||||
# 访问的域名
|
||||
config.endpoint = f'dysmsapi.aliyuncs.com'
|
||||
return Dysmsapi20170525Client(config)
|
||||
|
||||
if __name__ == '__main__':
|
||||
async def main(sms):
|
||||
r = await sms.send('SMS_460770222', '13801015292', {'code':'993344'})
|
||||
print(f'return {r}')
|
||||
|
||||
sms = AliSMS('LTAI5t5w7xsZgueod6uZ3TCD', 'n1HttSbQvgEbjvf62Gzl1aagfKyIyS')
|
||||
asyncio.get_event_loop().run_until_complete(main(sms))
|
||||
|
||||
1
app/const.py
Normal file
1
app/const.py
Normal file
@ -0,0 +1 @@
|
||||
DBNAME='sage'
|
||||
77
app/ext.py
Normal file
77
app/ext.py
Normal file
@ -0,0 +1,77 @@
|
||||
import json
|
||||
from traceback import print_exc
|
||||
from appPublic.log import info
|
||||
from appPublic.registerfunction import RegisterCoroutine
|
||||
from sqlor.dbpools import DBPools
|
||||
from appbase.businessdate import get_business_date
|
||||
from ahserver.serverenv import ServerEnv
|
||||
|
||||
async def load_sysparams(*args, **kw):
|
||||
info('load_sysparams() called')
|
||||
db = DBPools()
|
||||
|
||||
async with db.sqlorContext('sage') as sor:
|
||||
r = await sor.sqlExe("select * from sysparams", {})
|
||||
g = ServerEnv()
|
||||
x = { i.params_name:i.params_value for i in r }
|
||||
g.sysparams = x
|
||||
|
||||
rf = RegisterCoroutine()
|
||||
rf.register('ahapp_built', load_sysparams)
|
||||
rf.register(f'sage:sysparams:C:after', load_sysparams)
|
||||
rf.register(f'sage:sysparams:D:after', load_sysparams)
|
||||
rf.register(f'sage:sysparams:U:after', load_sysparams)
|
||||
|
||||
def get_module_dbname(mname):
|
||||
return 'sage'
|
||||
|
||||
def UiWindow(title, icon, content, cheight=10, cwidth=15):
|
||||
return {
|
||||
"widgettype":"PopupWindow",
|
||||
"options":{
|
||||
"author":"cc",
|
||||
"cwidth":cwidth,
|
||||
"cheight":cheight,
|
||||
"title":title,
|
||||
"content":content,
|
||||
"icon":icon or entire_url('/bricks/imgs/app.png'),
|
||||
"movable":True,
|
||||
"auto_open":True
|
||||
}
|
||||
}
|
||||
|
||||
def UiError(title="出错", message="出错啦", timeout=5):
|
||||
return {
|
||||
"widgettype":"Error",
|
||||
"options":{
|
||||
"author":"tr",
|
||||
"timeout":timeout,
|
||||
"cwidth":15,
|
||||
"cheight":10,
|
||||
"title":title,
|
||||
"message":message
|
||||
}
|
||||
}
|
||||
|
||||
def UiMessage(title="消息", message="后台消息", timeout=5):
|
||||
return {
|
||||
"widgettype":"Message",
|
||||
"options":{
|
||||
"author":"tr",
|
||||
"timeout":timeout,
|
||||
"cwidth":15,
|
||||
"cheight":10,
|
||||
"title":title,
|
||||
"message":message
|
||||
}
|
||||
}
|
||||
|
||||
def get_business_date():
|
||||
return curDateString()
|
||||
g = ServerEnv()
|
||||
g.get_module_dbname = get_module_dbname
|
||||
g.UiError = UiError
|
||||
g.UiMessage = UiMessage
|
||||
g.UiWindow = UiWindow
|
||||
g.get_business_date = get_business_date
|
||||
|
||||
58
app/global_func.py
Normal file
58
app/global_func.py
Normal file
@ -0,0 +1,58 @@
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from sqlor.dbpools import DBPools
|
||||
from alisms import AliSMS
|
||||
|
||||
def PopError(title='Error', message='Error happened'):
|
||||
return {
|
||||
'widgettype':'Error',
|
||||
'options':{
|
||||
'title':title,
|
||||
'timeout':4,
|
||||
'message':message
|
||||
}
|
||||
}
|
||||
|
||||
def PopMessage(title='Error', message='Error happened'):
|
||||
return {
|
||||
'widgettype':'Message',
|
||||
'options':{
|
||||
'title':title,
|
||||
'timeout':4,
|
||||
'message':message
|
||||
}
|
||||
}
|
||||
|
||||
async def get_llm_types():
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('sage') as sor:
|
||||
ns = {
|
||||
'order':'name'
|
||||
}
|
||||
recs = await sor.R('modeltype', ns)
|
||||
return recs
|
||||
return []
|
||||
|
||||
async def get_llminstances_by_modeltype(mtid):
|
||||
db = DBPools()
|
||||
userorgid = await get_userorgid()
|
||||
async with db.sqlorContext('sage') as sor:
|
||||
sql = """select a.* from modelinstance a, modelapi b
|
||||
where
|
||||
a.modelid = b.modelid and
|
||||
a.orgid is null and
|
||||
b.modeltypeid = ${mtid}$
|
||||
order by a.name
|
||||
"""
|
||||
recs = await sor.sqlExe(sql, {'mtid':mtid, 'userorgid':userorgid})
|
||||
return recs
|
||||
return []
|
||||
|
||||
|
||||
def set_globalvariable():
|
||||
sms_engine = sms = AliSMS('LTAI5t5w7xsZgueod6uZ3TCD', 'n1HttSbQvgEbjvf62Gzl1aagfKyIyS')
|
||||
g = ServerEnv()
|
||||
g.sms_engine = sms_engine
|
||||
g.PopError = PopError
|
||||
g.PopMessage = PopMessage
|
||||
g.get_llm_types = get_llm_types
|
||||
g.get_llminstances_by_modeltype = get_llminstances_by_modeltype
|
||||
12
app/id2file.py
Executable file
12
app/id2file.py
Executable file
@ -0,0 +1,12 @@
|
||||
|
||||
from sqlor.dbpools import runSQL
|
||||
|
||||
async def getFilenameFromId(idstr:str) -> str:
|
||||
sql = "select * from kvobjects where id='%s'" % idstr
|
||||
recs = await runSQL('homedata',sql)
|
||||
if recs is None:
|
||||
return None
|
||||
if len(recs) == 0:
|
||||
return None
|
||||
return recs[0].name
|
||||
|
||||
28
app/idfile.py
Normal file
28
app/idfile.py
Normal file
@ -0,0 +1,28 @@
|
||||
import os
|
||||
from PIL import Image, ExifTags
|
||||
from io import BytesIO
|
||||
from aiohttp.web_exceptions import (
|
||||
HTTPException,
|
||||
HTTPExpectationFailed,
|
||||
HTTPForbidden,
|
||||
HTTPMethodNotAllowed,
|
||||
HTTPNotFound,
|
||||
)
|
||||
from aiohttp.web_response import Response, StreamResponse
|
||||
|
||||
from appPublic.registerfunction import RegisterFunction
|
||||
from appPublic.jsonConfig import getConfig
|
||||
from ahserver.filedownload import file_download
|
||||
from id2file import getFilenameFromId
|
||||
|
||||
def www_abspath(fp):
|
||||
if fp[0] == '/':
|
||||
fp = fp[1:]
|
||||
config = getConfig()
|
||||
return os.path.join(config.filesroot, fp)
|
||||
|
||||
async def idFileDownload(request, kw, *args):
|
||||
print(f'idFileDownload(): {args=}, {kw=}')
|
||||
fname = kw.get('path', None)
|
||||
path = www_abspath(fname)
|
||||
return await file_download(request,path)
|
||||
48
app/phonelogin.py
Normal file
48
app/phonelogin.py
Normal file
@ -0,0 +1,48 @@
|
||||
from rand import randint
|
||||
from sqlor.dbpools import DBPools
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from appPublic.uniqueID import getID
|
||||
from appPublic.timeUtils import timestampstr
|
||||
|
||||
from alisms import AliSMS
|
||||
from const import DBNAME, VALID_SECONDS
|
||||
async def gen_validatecode(phone_no){
|
||||
codes = []
|
||||
while len(codes) < 6:
|
||||
v = randint(0,13)
|
||||
if v >= 10:
|
||||
continue
|
||||
codes.append(str(v))
|
||||
code = ''.join(codes)
|
||||
sms = AliSMS()
|
||||
r = sms.send(
|
||||
ns = {
|
||||
'id':getID(),
|
||||
'code':''.join(code),
|
||||
'timestamp':timestampstr()
|
||||
}
|
||||
db = DBPools()
|
||||
async with db.sqlorContext(DBNAME) as sor:
|
||||
await sor.C('validatecode', ns)
|
||||
return ns['id']
|
||||
return None
|
||||
|
||||
async def validate_code(id:str, code:str) -> boolean:
|
||||
db = DBPools()
|
||||
sql = """select * from validatecode
|
||||
where id= ${id}$
|
||||
and code = ${code}$
|
||||
and timestamp + ${valid_secords}$ >= ${curr_timestamp}$"""
|
||||
ns = {
|
||||
'id':id,
|
||||
'code':code,
|
||||
'valid_seconds':VALID_SECONDS,
|
||||
'curr_timestamp':time.time()
|
||||
}
|
||||
async with db.sqlorContext(DBNAME) as sor:
|
||||
r = await sor.sqlExe(sql, ns.copy())
|
||||
if len(r) < 1:
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
153
app/rf.py
Normal file
153
app/rf.py
Normal file
@ -0,0 +1,153 @@
|
||||
import hashlib
|
||||
import hmac
|
||||
import base64
|
||||
import datetime
|
||||
import time
|
||||
import jwt
|
||||
|
||||
from appPublic.registerfunction import RegisterFunction
|
||||
from appPublic.rc4 import password, unpassword
|
||||
from appPublic.jsonConfig import getConfig
|
||||
from appPublic.log import debug
|
||||
|
||||
rf = RegisterFunction()
|
||||
def get_module_dbname(modulename):
|
||||
return 'sage'
|
||||
|
||||
rf.register('get_module_dbname', get_module_dbname)
|
||||
|
||||
def zhipu_token(uk_dic:dict):
|
||||
apikey = uk_dic.get('apikey')
|
||||
exp_seconds = 86400
|
||||
try:
|
||||
id, secret = apikey.split(".")
|
||||
except Exception as e:
|
||||
raise Exception("invalid apikey", e)
|
||||
|
||||
payload = {
|
||||
"api_key": id,
|
||||
"exp": int(round(time.time() * 1000)) + exp_seconds * 1000,
|
||||
"timestamp": int(round(time.time() * 1000)),
|
||||
}
|
||||
|
||||
uk_dic.update({'token':jwt.encode(
|
||||
payload,
|
||||
secret,
|
||||
algorithm="HS256",
|
||||
headers={"alg": "HS256", "sign_type": "SIGN"},
|
||||
)})
|
||||
return uk_dic
|
||||
|
||||
rf.register('zhipu_token', zhipu_token)
|
||||
|
||||
def shangtang_apikey(uk_dic):
|
||||
apikey = uk_dic.get("apikey")
|
||||
secretkey = uk_dic.get("secretkey")
|
||||
current_time = int(time.time())
|
||||
headers = {
|
||||
"alg": "HS256",
|
||||
"typ": "JWT"
|
||||
}
|
||||
payload = {
|
||||
"iss": apikey,
|
||||
"exp": current_time + 1800,
|
||||
"nbf": current_time - 5
|
||||
}
|
||||
token = jwt.encode(payload, secretkey, algorithm="HS256", headers=headers)
|
||||
return {
|
||||
"apikey": apikey,
|
||||
"secretkey": secretkey,
|
||||
"authorization": token
|
||||
}
|
||||
rf.register('shangtang_apikey', shangtang_apikey)
|
||||
|
||||
# body_str body请求体
|
||||
def mengzi_apikey(uk_dic):
|
||||
body_str = uk_dic.get("body_str")
|
||||
access_key = uk_dic.get("apikey")
|
||||
access_secret = uk_dic.get("secretkey")
|
||||
md5 = hashlib.md5(body_str.encode('utf-8')).digest()
|
||||
content_md5 = base64.b64encode(md5).decode('utf-8')
|
||||
|
||||
date_str = datetime.datetime.utcnow().strftime('%a,%d %b %Y %H:%M:%S GMT')
|
||||
|
||||
nonce = str(int(datetime.datetime.utcnow().timestamp() * 1000))
|
||||
|
||||
string_to_sign = "\n".join([
|
||||
"POST",
|
||||
"application/json",
|
||||
content_md5,
|
||||
"application/json",
|
||||
date_str,
|
||||
"HMAC-SHA256",
|
||||
nonce,
|
||||
""
|
||||
])
|
||||
|
||||
signature = base64.b64encode(
|
||||
hmac.new(access_secret.encode('utf-8'), string_to_sign.encode('utf-8'), hashlib.sha256).digest()).decode('utf-8')
|
||||
authorization = access_key + ":" + signature
|
||||
|
||||
return {
|
||||
"apikey": access_key,
|
||||
"secretkey": access_secret,
|
||||
"content_md5": content_md5,
|
||||
"date_header": date_str,
|
||||
"nonce": nonce,
|
||||
"authorization": authorization,
|
||||
}
|
||||
rf.register('mengzi_apikey', mengzi_apikey)
|
||||
|
||||
def tiangong_apikey(uk_dic):
|
||||
app_key = uk_dic.get("apikey")
|
||||
app_secret = uk_dic.get("secretkey")
|
||||
# 获取当前的时间戳
|
||||
timestamp = str(int(time.time()))
|
||||
# 计算sign
|
||||
sign_str = app_key + app_secret + timestamp
|
||||
sign = hashlib.md5(sign_str.encode()).hexdigest()
|
||||
return {
|
||||
"apikey": app_key,
|
||||
"secretkey": app_secret,
|
||||
"sign": sign,
|
||||
"timestamp": timestamp,
|
||||
}
|
||||
|
||||
rf.register('tiangong_apikey', tiangong_apikey)
|
||||
|
||||
default_pkey='456ft7ygubhinjlmkjiuyg7t65'
|
||||
def encode_password(ns):
|
||||
config = getConfig()
|
||||
pwd = ns.get('password');
|
||||
pkey = config.password_key or default_pkey
|
||||
debug(f'encode_password(): {pwd=}, {pkey=}')
|
||||
crypt = password(pwd, key=pkey)
|
||||
ns['password'] = crypt
|
||||
|
||||
def decode_password(ns):
|
||||
config.getConfig()
|
||||
pkey = config.password_key or default_pkey
|
||||
crypt = ns.get('password')
|
||||
pwd = unpassword(crypt, key=pkey)
|
||||
ns['password'] = pwd;
|
||||
return pwd
|
||||
|
||||
# {dbname}:{tablename}:c:before
|
||||
|
||||
def cut_b64_image_header(b64img):
|
||||
debug('cut_b64_image_header() called .........')
|
||||
if isinstance(b64img, str):
|
||||
return b64img.split(';base64,')[-1]
|
||||
if isinstance(b64img, list):
|
||||
ret = []
|
||||
for s in b64img:
|
||||
ret.append(s.split(';base64,')[-1])
|
||||
return ret
|
||||
|
||||
rf.register('cut_b64_image_header', cut_b64_image_header)
|
||||
# rf.register('password', encode_password)
|
||||
# rf.register('sage:hostdev:c:before', encode_password)
|
||||
# rf.register('sage:hostdev:u:before', encode_password)
|
||||
# rf.register('sage:users:c:before', encode_password)
|
||||
# rf.register('sage:users:u:before', encode_password)
|
||||
# rf.register('unpassword', decode_password)
|
||||
54
app/sage.py
Normal file
54
app/sage.py
Normal file
@ -0,0 +1,54 @@
|
||||
import os, sys
|
||||
import argparse
|
||||
from appPublic.log import MyLogger, info, debug, warning
|
||||
from appPublic.folderUtils import ProgramPath
|
||||
from appPublic.jsonConfig import getConfig
|
||||
from appPublic.registerfunction import RegisterFunction
|
||||
from ahserver.configuredServer import ConfiguredServer
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from rbac.init import load_rbac
|
||||
from appbase.init import load_appbase
|
||||
from basellm.init import load_basellm
|
||||
from filemgr.init import load_filemgr
|
||||
from uapi.init import load_uapi
|
||||
|
||||
from global_func import set_globalvariable
|
||||
from pf_pay.init import load_pf_pay
|
||||
from platformbiz.init import load_platformbiz
|
||||
from accounting.init import load_accounting
|
||||
from ext import *
|
||||
from rf import *
|
||||
__version__ = '0.0.1'
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(prog="Sage")
|
||||
parser.add_argument('-w', '--workdir')
|
||||
parser.add_argument('-p', '--port')
|
||||
args = parser.parse_args()
|
||||
workdir = args.workdir or os.getcwd()
|
||||
p = ProgramPath()
|
||||
config = getConfig(workdir, NS={'workdir':workdir, 'ProgramPath':p})
|
||||
if config.logger:
|
||||
logger = MyLogger(config.logger.name or 'sage',
|
||||
levelname=config.logger.levelname or 'debug',
|
||||
logfile=config.logger.logfile or None)
|
||||
else:
|
||||
logger = MyLogger('sage', levelname='debug')
|
||||
|
||||
info(f'====================sage version={__version__}')
|
||||
# server = ConfiguredServer(auth_klass=MyAuthAPI, workdir=workdir)
|
||||
server = ConfiguredServer(workdir=workdir)
|
||||
rf = RegisterFunction()
|
||||
set_globalvariable()
|
||||
load_appbase()
|
||||
load_rbac()
|
||||
load_accounting()
|
||||
load_pf_pay()
|
||||
load_platformbiz()
|
||||
load_basellm()
|
||||
load_filemgr()
|
||||
load_uapi()
|
||||
port = args.port or config.website.port or 8080
|
||||
port = int(port)
|
||||
server.run(port=port)
|
||||
|
||||
3
azure/key.py
Normal file
3
azure/key.py
Normal file
@ -0,0 +1,3 @@
|
||||
apikey='eda4e3707f734f1e955d7bba6ebe68d1'
|
||||
apikey2='a9250a0802864b889f882e0751b73807'
|
||||
|
||||
4
baidu/ak.py
Normal file
4
baidu/ak.py
Normal file
@ -0,0 +1,4 @@
|
||||
# AccessKey = "ALTAKpUCiGSkgJE32uxNACxzZ2"
|
||||
# AccessKeySecret = "2fec1ab19ded48efb81b4564e6986e15"
|
||||
AccessKey = "SjAN4GHU07LuB8ZYOIstB31G"
|
||||
AccessKeySecret = "QbakADoGJsM2qjUzIogTkBZruToxYAve"
|
||||
138
baidu/qianfan_api.py
Normal file
138
baidu/qianfan_api.py
Normal file
@ -0,0 +1,138 @@
|
||||
import asyncio
|
||||
import ak
|
||||
from appPublic.oauth_client import OAuthClient
|
||||
desc = {
|
||||
"data":{
|
||||
"APIKey":ak.AccessKey,
|
||||
"SecretKey":ak.AccessKeySecret
|
||||
},
|
||||
"mapis":{
|
||||
"get_access_token":{
|
||||
"url":"https://aip.baidubce.com/oauth/2.0/token",
|
||||
"method":"POST",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"grant_type",
|
||||
"value":"client_credentials"
|
||||
},
|
||||
{
|
||||
"name":"client_id",
|
||||
"value":"${APIKey}"
|
||||
},
|
||||
{
|
||||
"name":"client_secret",
|
||||
"value":"${SecretKey}"
|
||||
}
|
||||
],
|
||||
"resposne_type":"2",
|
||||
"error_field":"error",
|
||||
"error_msg_field":"error_description",
|
||||
"resp_set_data":[
|
||||
{
|
||||
"field":"access_token",
|
||||
"name":"AccessToken"
|
||||
},
|
||||
{
|
||||
"field":"expires_in",
|
||||
"name":"TokenExpiresIn"
|
||||
}
|
||||
]
|
||||
},
|
||||
"chat":{
|
||||
"url":"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro",
|
||||
# "url":"http://localhost/test/show.dspy",
|
||||
"method":"POST",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"access_token",
|
||||
"value":"${AccessToken}"
|
||||
}
|
||||
],
|
||||
"data":[
|
||||
{
|
||||
"name":"messages",
|
||||
"value":"${messages}"
|
||||
},
|
||||
{
|
||||
"name":"temperature",
|
||||
"value":0.1
|
||||
},
|
||||
{
|
||||
"name":"top_p",
|
||||
"value":0.8
|
||||
},
|
||||
{
|
||||
"name":"penalty_score",
|
||||
"value":1.0
|
||||
},
|
||||
{
|
||||
"name":"stream",
|
||||
"value":False
|
||||
},
|
||||
{
|
||||
"name":"system",
|
||||
"value":"开元云助手"
|
||||
},
|
||||
{
|
||||
"name":"stop",
|
||||
"value":[]
|
||||
},
|
||||
{
|
||||
"name":"max_output_token",
|
||||
"value":2048
|
||||
}
|
||||
],
|
||||
"resposne_type":"2",
|
||||
"error_field":"error",
|
||||
"error_msg_field":"error_description",
|
||||
"resp_set_data":[
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async def main(desc):
|
||||
qianfanapi = OAuthClient(desc)
|
||||
r = await qianfanapi('get_access_token', {})
|
||||
print(f'get_access_token: response={r}, data={qianfanapi.data}')
|
||||
msgs = []
|
||||
while True:
|
||||
print('prompt:')
|
||||
p = input()
|
||||
if p == '':
|
||||
continue
|
||||
if p == 'quit':
|
||||
break
|
||||
msg = {
|
||||
"role":"user",
|
||||
"content":p
|
||||
}
|
||||
msgs.append(msg)
|
||||
r = await qianfanapi('chat',{"messages":msgs})
|
||||
try:
|
||||
print(r['result'])
|
||||
msg = {
|
||||
"role":"assistant",
|
||||
"content":r['result']
|
||||
}
|
||||
msgs.append(msg)
|
||||
except Exception as e:
|
||||
print(r, e)
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.get_event_loop().run_until_complete(main(desc))
|
||||
|
||||
23
chatglm3_6b/load_model.py
Normal file
23
chatglm3_6b/load_model.py
Normal file
@ -0,0 +1,23 @@
|
||||
from appPublic.worker import awaitify
|
||||
from ahserver.serverEnv import ServerEnv
|
||||
from transformers import AutoTokenizer, AutoModel
|
||||
|
||||
class ChatGLM3:
|
||||
def __init__(self, model_path, gpu=False):
|
||||
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
|
||||
model = AutoModel.from_pretrained(model_path, trust_remote_code=True)
|
||||
if gpu:
|
||||
model = model.cuda()
|
||||
else:
|
||||
model = model.float()
|
||||
model = model.eval()
|
||||
self.model = model
|
||||
self.tokenizer = tokenizer
|
||||
|
||||
def _generate(self, prompt, history=[]):
|
||||
response, history = self.model.chat(self.tokenizer, prompt, history=history)
|
||||
return response, history
|
||||
|
||||
generate = awaitify(_generate)
|
||||
|
||||
|
||||
6
chatglm3_6b/requirements.txt
Normal file
6
chatglm3_6b/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
transformers==4.30.2
|
||||
protobuf
|
||||
cpm_kernels
|
||||
torch>=2.0
|
||||
sentencepiece
|
||||
accelerate
|
||||
5
codellama/load_model.py
Normal file
5
codellama/load_model.py
Normal file
@ -0,0 +1,5 @@
|
||||
from transformers import AutoTokenizer, AutoModelForCausalLM
|
||||
tokenizer = AutoTokenizer.from_pretrained("codellama/CodeLlama-7b-hf")
|
||||
tokenizer.save_pretrained('CodeLlama-7b-tokenizer')
|
||||
model = AutoModelForCausalLM.from_pretrained("codellama/CodeLlama-7b-hf")
|
||||
model.save_pretrained('CodeLlama-7b-model')
|
||||
3
conf/alipay/private.txt
Normal file
3
conf/alipay/private.txt
Normal file
@ -0,0 +1,3 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCNEFKfj8jib0cWXyEml7I7cTKyUMAMJmcIfoNNeFcNvp7pNH8cB9QpHvQIOrPTwuyxw591iGWkLCzfKRJc1K594hl558OVrJrB7sM716jyCT1SOqlFcMvuk1Eq3ayMCTR2gyMqdnzaxbSedpPDFQXCXeT5AWDq+IPI1un32Qi35jl0sZu8Ve8KKzaFogig/MkDONShMb593B89p1qRie5HfeHMilcMy4Q1jJ7eo83Q2PfsE0NIuDj6gm38+GcFr3n0h24KeGUANkjU4DhBN2hKwqcpyPFmFio+JWIB8u8dH+8nKS81p8PgqeiKaeJEMWMes1VCeBtICoiyTVgYCpY9AgMBAAECggEALigdIOCnVpAarpNKAZq5UwHjGL2bWV5ncDwVMpAhy/mHfb8TqFRXc20RZG/wz2WElVXxI0ASIfniZNLHk2B0B/SnaWAQezUTHknF0BrsyOWFDxbqtDIISHQjpucJwnhwliaqpwZGLD9srj0WdEq4q7SVa3SsBbZzSJAp1lNJqwJJf7GZUL+5riuSSBBqv+ZExBEwFRlJL8mjOqlISgQQanU5N6ROr5h5vQ3kn2KsXNZdkroEVSA9aeCHn1nDZLE3qCRLhSyOCSmx4YqTO3neFYN50Zo7QoE40LLzSK5SACctp/AWzq12GN9f5iGya6mf+t4pKF/SjZ6ogFZo9QOCcQKBgQDB50aVaBSDsRLXcSFveFPUrOtIzOBmNtuaq96ibqHj+3fGmji6XKIoWN2Yd0Iet6CK7Ph0hKQgljtiaRWSi0cmkqZU4NvZerNWKWxBhnVBkZRqPdyHjEG47qJCaz7wv72S2kQTh3yBap8o/Mtt1M+2QDG0TkHfbjF2mI1q6dnzCwKBgQC6PRwHyArbcqCy48NGTgmxUBJhHIz1zKB/7xX+uPzUyMfvx4bHwwih8bL362zQMlpxwjm28qFQ8/Dh1/baavnrEztaqUChnD6sb2xENP26PNCmxoho71AInVnp0vKEYDw7jYfc5pvl46nlvK8ErbKeohL8gzfew7lit+sUP6lo1wKBgFr9zs+Z0daip7bV7dzDWIN6ycaV7c/JenAwqv8Kb4nunZxjDq/VfHr2iLZdcHe9r+bBoS38eJCaLy/VJDxqg28Ebm1yP3jk7XdHZPeywx+L01uvv+cT2FuSEC6e6SBMugdJyZxoffK1OA8h4cyeiwJ5SVnVR3Az455FpEdBifdVAoGABf5DcaipWMiGjVsxBIksXK1j+gYOLzbHj3ZlMc5ILJzNelTkbHdFRtjdVocX+Fc2e+SxMMb8E/vVq57kjcDVjBARX+iEcO7zQV9Qj51Y8O5WFJfc+euBmtVdeF3WehYSuiPi1GQDblF2PTNmOnNQhTRYAhJC8QNBawDaKsulqv8CgYA1fxxqgYqV3BKh4stzDnczt9bPMrCmWmwo2RkVykJMZv/jtXzefPOE27Q+COp5dxLxRnYnGc55B4COVov0p8y05KABOTvN1IJR5BwJLST+gofZW2X3Zd2swAVO758hbpDukKP1A3BeHFoe40S2udGqgntVsMHQhnWUlnDAH++C5A==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
3
conf/alipay/public.txt
Normal file
3
conf/alipay/public.txt
Normal file
@ -0,0 +1,3 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgD4YlfnWKd4vEHsim6vxLwustbnBBh9IUJwF5rGJ3b7wjYyzMnQZ36Cgf81A685IQ+Ni9GogNDaUWZx9V+qGxZRwaLbktSLnUNwPMudKlUoPyQtqyygU+Bmwg1B+UBzZsz8eG72qOuvu9xNbT72QZqFxzLlo0vzWldijnaPcqukUhTaeIYe1AObI9v3ySAa72GkGCHaSkQqvBLydCJt2mu3zJYhPMKre1oNmQkGYUxLKCwonbABaugOEl7t1vL8mAMlwFg2ihJbYiogGfr2Imt/Y1jy8rftiW41opX1UQ30rgfRYeuEsKvVwuoyqffGHeBSjs53xZkYStYKj0m+8AQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
100
conf/config.json
Executable file
100
conf/config.json
Executable file
@ -0,0 +1,100 @@
|
||||
{
|
||||
"password_key":"!@#$%^&*(*&^%$QWERTYUIqwertyui234567",
|
||||
"logger":{
|
||||
"name":"sage",
|
||||
"levelname":"clientinfo",
|
||||
"logfile":"$[workdir]$/logs/sage.log"
|
||||
},
|
||||
"pay":{
|
||||
"alipay":{
|
||||
"public_key_file":"$[workdir]$/conf/alipay/public.txt",
|
||||
"private_key_file":"$[workdir]$/conf/alipay/private.txt",
|
||||
"appid":"2021005111636494",
|
||||
"callback":"https://sage.opencomputing.cn/api/callback/alipay"
|
||||
},
|
||||
"paypal":{
|
||||
"mode":"sandbox",
|
||||
"client_id":"myid",
|
||||
"client_secret":"mysecret",
|
||||
"return_url":"ret_url",
|
||||
"cancel_url":"cancel_url"
|
||||
}
|
||||
},
|
||||
"filesroot":"$[workdir]$/files",
|
||||
"databases":{
|
||||
"sage":{
|
||||
"driver":"aiomysql",
|
||||
"async_mode":true,
|
||||
"coding":"utf8",
|
||||
"maxconn":100,
|
||||
"dbname":"sage",
|
||||
"kwargs":{
|
||||
"user":"test",
|
||||
"db":"sage",
|
||||
"password":"QUZVcXg5V1p1STMybG5Ia6mX9D0v7+g=",
|
||||
"host":"db"
|
||||
}
|
||||
}
|
||||
},
|
||||
"website":{
|
||||
"paths":[
|
||||
["$[workdir]$/wwwroot",""]
|
||||
],
|
||||
"client_max_size":10000,
|
||||
"host":"0.0.0.0",
|
||||
"port":9080,
|
||||
"coding":"utf-8",
|
||||
"ssl_gg":{
|
||||
"crtfile":"$[workdir]$/conf/www.bsppo.com.pem",
|
||||
"keyfile":"$[workdir]$/conf/www.bsppo.com.key"
|
||||
},
|
||||
"indexes":[
|
||||
"index.html",
|
||||
"index.tmpl",
|
||||
"index.ui",
|
||||
"index.dspy",
|
||||
"index.md"
|
||||
],
|
||||
"startswiths":[
|
||||
{
|
||||
"leading":"/idfile",
|
||||
"registerfunction":"idFileDownload"
|
||||
}
|
||||
],
|
||||
"processors":[
|
||||
[".ws","ws"],
|
||||
[".xterm","xterm"],
|
||||
[".proxy","proxy"],
|
||||
[".llm", "llm"],
|
||||
[".llms", "llms"],
|
||||
[".llma", "llma"],
|
||||
[".xlsxds","xlsxds"],
|
||||
[".sqlds","sqlds"],
|
||||
[".tmpl.js","tmpl"],
|
||||
[".tmpl.css","tmpl"],
|
||||
[".html.tmpl","tmpl"],
|
||||
[".bcrud", "bricks_crud"],
|
||||
[".tmpl","tmpl"],
|
||||
[".app","app"],
|
||||
[".bui","bui"],
|
||||
[".ui","bui"],
|
||||
[".dspy","dspy"],
|
||||
[".md","md"]
|
||||
],
|
||||
"rsakey":{
|
||||
"privatekey":"$[workdir]$/conf/rsa_private_key.pem",
|
||||
"publickey":"$[workdir]$/conf/rsa_public_key.pem"
|
||||
},
|
||||
"session_max_time":3000,
|
||||
"session_issue_time":2500,
|
||||
"session_redis":{
|
||||
"url":"redis://127.0.0.1:6379"
|
||||
}
|
||||
},
|
||||
"langMapping":{
|
||||
"zh-Hans-CN":"zh-cn",
|
||||
"zh-CN":"zh-cn",
|
||||
"en-us":"en",
|
||||
"en-US":"en"
|
||||
}
|
||||
}
|
||||
9
coquitts/generate/index.dspy
Normal file
9
coquitts/generate/index.dspy
Normal file
@ -0,0 +1,9 @@
|
||||
text = params_kw.get('text')
|
||||
lang = params_kw.get('lang', 'cn')
|
||||
if lang == cn:
|
||||
b = await cn_tts.generate(text)
|
||||
return b
|
||||
if lang == en:
|
||||
b = await en_tts.generate(text)
|
||||
return b
|
||||
|
||||
15
coquitts/load_model.py
Normal file
15
coquitts/load_model.py
Normal file
@ -0,0 +1,15 @@
|
||||
from apppublic.worker import awaitify
|
||||
from coquitts.coqui import CoquiTTS
|
||||
|
||||
g = ServerEnv()
|
||||
# e = CoquiTTS('tts_models/en/ljspeech/vits--neon')
|
||||
# g.en_tts = e
|
||||
e = CoquiTTS('tts_models/zh-CN/baker/tacotron2-DDC-GST')
|
||||
g.cn_tts = e
|
||||
|
||||
if __name__ == '__main__':
|
||||
import asyncio
|
||||
b = await e.generate('你好吗?我很好。')
|
||||
with open('w.wav','wb') as f:
|
||||
f.write(b)
|
||||
|
||||
BIN
docs/模型平台数据.docx
Normal file
BIN
docs/模型平台数据.docx
Normal file
Binary file not shown.
BIN
docs/通用LLM应用平台.pptx
Normal file
BIN
docs/通用LLM应用平台.pptx
Normal file
Binary file not shown.
88
embeddings/embeddings_from_text.py
Normal file
88
embeddings/embeddings_from_text.py
Normal file
@ -0,0 +1,88 @@
|
||||
# code from https://platform.openai.com/docs/tutorials/web-qa-embeddings
|
||||
import pandas as pd
|
||||
import tiktoken
|
||||
|
||||
max_tokens = 500
|
||||
|
||||
# Function to split the text into chunks of a maximum number of tokens
|
||||
def split_into_many(text, max_tokens = max_tokens):
|
||||
# Split the text into sentences
|
||||
sentences = text.split('. ')
|
||||
|
||||
# Get the number of tokens for each sentence
|
||||
n_tokens = [len(tokenizer.encode(" " + sentence)) for sentence in sentences]
|
||||
|
||||
chunks = []
|
||||
tokens_so_far = 0
|
||||
chunk = []
|
||||
|
||||
# Loop through the sentences and tokens joined together in a tuple
|
||||
for sentence, token in zip(sentences, n_tokens):
|
||||
|
||||
# If the number of tokens so far plus the number of tokens in the current sentence is greater
|
||||
# than the max number of tokens, then add the chunk to the list of chunks and reset
|
||||
# the chunk and tokens so far
|
||||
if tokens_so_far + token > max_tokens:
|
||||
chunks.append(". ".join(chunk) + ".")
|
||||
chunk = []
|
||||
tokens_so_far = 0
|
||||
|
||||
# If the number of tokens in the current sentence is greater than the max number of
|
||||
# tokens, go to the next sentence
|
||||
if token > max_tokens:
|
||||
continue
|
||||
|
||||
# Otherwise, add the sentence to the chunk and add the number of tokens to the total
|
||||
chunk.append(sentence)
|
||||
tokens_so_far += token + 1
|
||||
|
||||
return chunks
|
||||
|
||||
def remove_newlines(serie):
|
||||
serie = serie.str.replace('\n', ' ')
|
||||
serie = serie.str.replace('\\n', ' ')
|
||||
serie = serie.str.replace(' ', ' ')
|
||||
serie = serie.str.replace(' ', ' ')
|
||||
return serie
|
||||
|
||||
class EmbeddingsBuilder:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def txt2csv(self, sourcePath, csvfile):
|
||||
# Create a list to store the text files
|
||||
texts=[]
|
||||
# Get all the text files in the text directory
|
||||
for file in os.listdir(sourcePath):
|
||||
# Open the file and read the text
|
||||
with open(sourcePath + file, "r", encoding="UTF-8") as f:
|
||||
text = f.read()
|
||||
# Omit the first 11 lines and the last 4 lines, then replace -, _, and #update with spaces.
|
||||
texts.append((file, text))
|
||||
|
||||
# Create a dataframe from the list of texts
|
||||
df = pd.DataFrame(texts, columns = ['title', 'text'])
|
||||
# Set the text column to be the raw text with the newlines removed
|
||||
df['text'] = df.fname + ". " + remove_newlines(df.text)
|
||||
|
||||
# Load the cl100k_base tokenizer which is designed to work with the ada-002 model
|
||||
tokenizer = tiktoken.get_encoding("cl100k_base")
|
||||
# Tokenize the text and save the number of tokens to a new column
|
||||
df['n_tokens'] = df.text.apply(lambda x: len(tokenizer.encode(x)))
|
||||
shortened = []
|
||||
# Loop through the dataframe
|
||||
for row in df.iterrows():
|
||||
# If the text is None, go to the next row
|
||||
if row[1]['text'] is None:
|
||||
continue
|
||||
# If the number of tokens is greater than the max number of tokens, split the text into chunks
|
||||
if row[1]['n_tokens'] > max_tokens:
|
||||
shortened += split_into_many(row[1]['text'])
|
||||
# Otherwise, add the text to the list of shortened texts
|
||||
else:
|
||||
shortened.append( row[1]['text'] )
|
||||
df = pd.DataFrame(shortened, columns = ['text'])
|
||||
df['n_tokens'] = df.text.apply(lambda x: len(tokenizer.encode(x)))
|
||||
|
||||
df.to_csv(csvfile)
|
||||
|
||||
70
fastchat/load_model.py
Normal file
70
fastchat/load_model.py
Normal file
@ -0,0 +1,70 @@
|
||||
import time
|
||||
from fastchat.serve.inference import ChatIO
|
||||
from fastchat.model.model_adapter import (
|
||||
load_model,
|
||||
# get_conversation_template,
|
||||
get_generate_stream_function,
|
||||
)
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from appPublic.worker import awaitify
|
||||
|
||||
class FastChatModel:
|
||||
def __init__(self, model_path, device='cpu',
|
||||
temperature=1.0,
|
||||
context_len=100000,
|
||||
debug=False
|
||||
):
|
||||
self.model_path = model_path
|
||||
self.device = device
|
||||
self.debug = debug
|
||||
self.temperature=temperature
|
||||
self.context_len = context_len
|
||||
self.model, self.tokenizer = load_model(
|
||||
model_path,
|
||||
device=device,
|
||||
debug=debug
|
||||
)
|
||||
self.generate_stream_func = get_generate_stream_function(self.model, self.model_path)
|
||||
|
||||
def _generate(self, prompt):
|
||||
gen_params = {
|
||||
"model": self.model_path,
|
||||
"prompt": prompt,
|
||||
"temperature": self.temperature,
|
||||
"max_new_tokens": self.context_len,
|
||||
"stream":False,
|
||||
"echo": False,
|
||||
}
|
||||
|
||||
output_stream = self.generate_stream_func(
|
||||
self.model,
|
||||
self.tokenizer,
|
||||
gen_params,
|
||||
self.device,
|
||||
context_len=self.context_len
|
||||
)
|
||||
t = time.time()
|
||||
output = ''
|
||||
for i,s in enumerate(output_stream):
|
||||
if self.debug:
|
||||
print(i, ':', s['text'], '\n')
|
||||
return s['text']
|
||||
|
||||
generate = awaitify(_generate)
|
||||
|
||||
g = ServerEnv()
|
||||
# m = FastChatModel('./vicuna-7b-v1.5', device='mps')
|
||||
# m = FastChatModel('/Users/ymq/models/hub/CodeLlama-13b-Instruct-hf')
|
||||
m = FastChatModel('/Users/ymq/models/hub/CodeLlama-13-hf')
|
||||
g.fschat = m
|
||||
|
||||
if __name__ == '__main__':
|
||||
import asyncio
|
||||
async def main():
|
||||
while True:
|
||||
print('input prompt:')
|
||||
p = input()
|
||||
x = await m.generate(p)
|
||||
print(f'answer:\n{x}')
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
||||
1
fastchat/requirements.txt
Normal file
1
fastchat/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
fschat
|
||||
0
files/README.md
Normal file
0
files/README.md
Normal file
2
gpt4all/generate.dspy
Normal file
2
gpt4all/generate.dspy
Normal file
@ -0,0 +1,2 @@
|
||||
prompt = params_kw.get('prompt')
|
||||
return await gpt4all_engine.generate(prompt)
|
||||
25
gpt4all/load_model.py
Normal file
25
gpt4all/load_model.py
Normal file
@ -0,0 +1,25 @@
|
||||
from gpt4all import GPT4All
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from appPublic.worker import awaitify
|
||||
|
||||
class GadgetGpt4all:
|
||||
def __init__(self, model_name):
|
||||
self.model_name = model_name
|
||||
self.model = GPT4All(model_name,device='intel')
|
||||
# device='amd', device='intel'
|
||||
|
||||
def _generate(text):
|
||||
return self.model.generate(text, max_tokens=10000000)
|
||||
|
||||
generate = awaitify(_generate)
|
||||
|
||||
g = ServerEnv()
|
||||
m = GadgetGpt4all('orca-mini-3b-gguf2-q4_0.gguf')
|
||||
g.gpt4all_model = m
|
||||
|
||||
if __name__ == '__main__':
|
||||
import asyncio
|
||||
asyncio.get_event_loop().run_until_complete(g.generate('what is the color of lotus'))
|
||||
|
||||
output = model.generate("The capital of France is ", max_tokens=3)
|
||||
print(output)
|
||||
1
gpt4all/requirements.txt
Normal file
1
gpt4all/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
gpt4all
|
||||
0
i18n/README.md
Normal file
0
i18n/README.md
Normal file
9
initln
Executable file
9
initln
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
for m in accounting appbase basellm filemgr msp platformbiz rag rbac uapi
|
||||
do
|
||||
cd ~/py/$m/json
|
||||
sh ./build.sh
|
||||
cd ~/py/sage/wwwroot
|
||||
ln -s ~/py/$m/wwwroot $m
|
||||
done
|
||||
17
json/acc_balance.json
Normal file
17
json/acc_balance.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/acc_balance",
|
||||
"dbname": "sage",
|
||||
"tblname": "acc_balance",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/acc_detail.json
Normal file
17
json/acc_detail.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/acc_detail",
|
||||
"dbname": "sage",
|
||||
"tblname": "acc_detail",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/account.json
Normal file
17
json/account.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/account",
|
||||
"dbname": "sage",
|
||||
"tblname": "account",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
28
json/account_config.json
Normal file
28
json/account_config.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/accounting/wwwroot/account_config",
|
||||
"dbname": "sage",
|
||||
"tblname": "account_config",
|
||||
"params": {
|
||||
"sortby":[
|
||||
"partytype",
|
||||
"subjectname"
|
||||
],
|
||||
"browserfields": {
|
||||
"exclouded": ["id", "subjectid"],
|
||||
"alters": {
|
||||
"partytype":{
|
||||
"cwidth":8
|
||||
},
|
||||
"subjectname":{
|
||||
"cwidth":12
|
||||
}
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
40
json/accounting_config.json
Normal file
40
json/accounting_config.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/accounting_config",
|
||||
"dbname": "sage",
|
||||
"tblname": "accounting_config",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"alters":{
|
||||
"action":{
|
||||
"cwidth":12
|
||||
},
|
||||
"specstr":{
|
||||
"cwidth":6
|
||||
},
|
||||
"accounting_orgtype":{
|
||||
"cwidth":12
|
||||
},
|
||||
"accounting_dir":{
|
||||
"cwidth":3
|
||||
},
|
||||
"orgtype":{
|
||||
"cwidth":6
|
||||
},
|
||||
"subjectname":{
|
||||
"cwidth":10
|
||||
},
|
||||
"amt_pattern":{
|
||||
"cwidth":20
|
||||
}
|
||||
}
|
||||
},
|
||||
"sortby":["action", "accounting_orgtype", "accounting_dir", "orgtype" ],
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/accounting_log.json
Normal file
17
json/accounting_log.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/accounting_log",
|
||||
"dbname": "sage",
|
||||
"tblname": "accounting_log",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": [],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/apidata.json
Normal file
17
json/apidata.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/apidata",
|
||||
"dbname": "sage",
|
||||
"tblname": "apidata",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/apiparams.json
Normal file
17
json/apiparams.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/apiparams",
|
||||
"dbname": "sage",
|
||||
"tblname": "apiparams",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
24
json/appcodes.json
Normal file
24
json/appcodes.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/appcodes",
|
||||
"dbname": "sage",
|
||||
"tblname": "appcodes",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": [],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": {
|
||||
"widgettype":"urlwidget",
|
||||
"options":{
|
||||
"url":"{{entire_url('../appcodes_kv')}}",
|
||||
"params":{
|
||||
"parentid":"${id}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
json/appcodes_kv.json
Normal file
22
json/appcodes_kv.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/appcodes_kv",
|
||||
"dbname": "sage",
|
||||
"tblname": "appcodes_kv",
|
||||
"params": {
|
||||
"sortby":"k",
|
||||
"notitle":true,
|
||||
"browserfields": {
|
||||
"exclouded": [
|
||||
"id",
|
||||
"parentid"
|
||||
],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id", "parentid"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/bill.json
Normal file
17
json/bill.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/bill",
|
||||
"dbname": "sage",
|
||||
"tblname": "bill",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": [],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/bill_detail.json
Normal file
17
json/bill_detail.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/bill_detail",
|
||||
"dbname": "sage",
|
||||
"tblname": "bill_detail",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": [],
|
||||
"alters": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
47
json/feelog.json
Normal file
47
json/feelog.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/fee/feelog",
|
||||
"dbname": "sage",
|
||||
"tblname": "feelog",
|
||||
"params": {
|
||||
"sortby":"transtime desc",
|
||||
"noedit":true,
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"alters":{
|
||||
"transtime":{
|
||||
"cwidth":14
|
||||
},
|
||||
"modelinstanceid":{
|
||||
"cwidth":10
|
||||
},
|
||||
"modeltypeid":{
|
||||
"cwidth":5
|
||||
},
|
||||
"customerid":{
|
||||
"cwidth":20
|
||||
},
|
||||
"userid":{
|
||||
"cwidth":4
|
||||
},
|
||||
"pricing_mode":{
|
||||
"cwidth":5
|
||||
},
|
||||
"resp_time":{
|
||||
"cwidth":6
|
||||
},
|
||||
"finish_time":{
|
||||
"cwidth":6
|
||||
},
|
||||
"estimate":{
|
||||
"cwidth":4
|
||||
}
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/httpapi.json
Normal file
17
json/httpapi.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/httpapi",
|
||||
"dbname": "sage",
|
||||
"tblname": "httpapi",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/minimax_acc.json
Normal file
17
json/minimax_acc.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/minimax_acc",
|
||||
"dbname": "sage",
|
||||
"tblname": "minimax_acc",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/minimax_bill.json
Normal file
17
json/minimax_bill.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/minimax_bill",
|
||||
"dbname": "sage",
|
||||
"tblname": "minimax_bill",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
18
json/modelapi.json
Normal file
18
json/modelapi.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modelapi",
|
||||
"dbname": "sage",
|
||||
"tblname": "modelapi",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id",
|
||||
"modelid"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
20
json/modelinstance.json
Normal file
20
json/modelinstance.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modelinstance",
|
||||
"dbname": "sage",
|
||||
"tblname": "modelinstance",
|
||||
"params": {
|
||||
"logined_userorgid":"ownerid",
|
||||
"sortby":"modelid_text",
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id",
|
||||
"ownerid"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/modeliodata.json
Normal file
17
json/modeliodata.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modeliodata",
|
||||
"dbname": "sage",
|
||||
"tblname": "modeliodata",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/modelpricing.json
Normal file
17
json/modelpricing.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modelpricing",
|
||||
"dbname": "sage",
|
||||
"tblname": "modelpricing",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/modelprovider.json
Normal file
17
json/modelprovider.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modelprovider",
|
||||
"dbname": "sage",
|
||||
"tblname": "modelprovider",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
32
json/models.json
Normal file
32
json/models.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/models",
|
||||
"dbname": "sage",
|
||||
"tblname": "models",
|
||||
"title":"模型世界",
|
||||
"params": {
|
||||
"sortby":"name",
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"subtables":[
|
||||
{
|
||||
"field":"modelid",
|
||||
"title":"模型API",
|
||||
"url":"../modelapi",
|
||||
"subtable":"modelapi"
|
||||
},
|
||||
{
|
||||
"field":"modelid",
|
||||
"title":"模型定价",
|
||||
"url":"../modelpricing",
|
||||
"subtable":"modelpricing"
|
||||
}
|
||||
],
|
||||
"record_toolbar": null
|
||||
}
|
||||
}
|
||||
15
json/modeltype.json
Normal file
15
json/modeltype.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modeltype",
|
||||
"dbname": "sage",
|
||||
"tblname": "modeltype",
|
||||
"params": {
|
||||
"sortby":"id",
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
]
|
||||
}
|
||||
}
|
||||
17
json/modeltypein.json
Normal file
17
json/modeltypein.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modeltypein",
|
||||
"dbname": "sage",
|
||||
"tblname": "modeltypein",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/modeltypeout.json
Normal file
17
json/modeltypeout.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/modeltypeout",
|
||||
"dbname": "sage",
|
||||
"tblname": "modeltypeout",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/org_roles.json
Normal file
17
json/org_roles.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/org_roles",
|
||||
"dbname": "sage",
|
||||
"tblname": "org_roles",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
25
json/organization.json
Normal file
25
json/organization.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/organization",
|
||||
"dbname": "sage",
|
||||
"tblname": "organization",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": {
|
||||
"widgettype":"urlwidget",
|
||||
"options":{
|
||||
"params":{
|
||||
"orgid":"${id}"
|
||||
},
|
||||
"url":"{{entire_url('../orgtypes')}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
json/orgtype.json
Normal file
16
json/orgtype.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/orgtype",
|
||||
"dbname": "sage",
|
||||
"tblname": "orgtype",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": ["id" ],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null
|
||||
}
|
||||
}
|
||||
16
json/orgtypes.json
Normal file
16
json/orgtypes.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/orgtypes",
|
||||
"dbname": "sage",
|
||||
"tblname": "orgtypes",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"exclouded": ["id" ],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id", "orgid"
|
||||
],
|
||||
"record_toolbar": null
|
||||
}
|
||||
}
|
||||
17
json/permission.json
Normal file
17
json/permission.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/permission",
|
||||
"dbname": "sage",
|
||||
"tblname": "permission",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/role.json
Normal file
17
json/role.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/role",
|
||||
"dbname": "sage",
|
||||
"tblname": "role",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/rolepermission.json
Normal file
17
json/rolepermission.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/rolepermission",
|
||||
"dbname": "sage",
|
||||
"tblname": "rolepermission",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
31
json/subject.json
Normal file
31
json/subject.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/accounting/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/subject",
|
||||
"dbname": "sage",
|
||||
"tblname": "subject",
|
||||
"params": {
|
||||
"sortby":[
|
||||
"subjecttype",
|
||||
"name"
|
||||
],
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"alters": {
|
||||
"balance_side":{
|
||||
"cwidth":4
|
||||
},
|
||||
"subjecttype":{
|
||||
"cwidth":4
|
||||
},
|
||||
"name":{
|
||||
"uitype":"str"
|
||||
}
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
5
json/t.sh
Normal file
5
json/t.sh
Normal file
@ -0,0 +1,5 @@
|
||||
for fn in *.json
|
||||
do
|
||||
sed 's/\/Users\/ymq/\$\{HOME\}\$/g' -i $fn
|
||||
done
|
||||
|
||||
17
json/token_usgae.json
Normal file
17
json/token_usgae.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/token_usgae",
|
||||
"dbname": "sage",
|
||||
"tblname": "token_usgae",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
20
json/userapikey.json
Normal file
20
json/userapikey.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/userapikey",
|
||||
"dbname": "sage",
|
||||
"tblname": "userapikey",
|
||||
"params": {
|
||||
"logined_userorgid":"ownerid",
|
||||
"browserfields": {
|
||||
"excloud": [
|
||||
"id", "ownerid"
|
||||
],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id", "ownerid"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
17
json/userdepartment.json
Normal file
17
json/userdepartment.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/userdepartment",
|
||||
"dbname": "sage",
|
||||
"tblname": "userdepartment",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
23
json/userrole.json
Normal file
23
json/userrole.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/userrole",
|
||||
"dbname": "sage",
|
||||
"tblname": "userrole",
|
||||
"params": {
|
||||
"relation":{
|
||||
"outter_field":"roleid",
|
||||
"param_field":"userid"
|
||||
},
|
||||
"binds":[],
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"alters":{
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
25
json/users.json
Normal file
25
json/users.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/users",
|
||||
"dbname": "sage",
|
||||
"tblname": "users",
|
||||
"params": {
|
||||
"browserfields": {
|
||||
"excloud": [],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": {
|
||||
"widgettype":"urlwidget",
|
||||
"options":{
|
||||
"url":"{{entire_url('../userrole1')}}",
|
||||
"params":{
|
||||
"userid":"${id}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
json/xterm.json
Normal file
19
json/xterm.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"models_dir": "${HOME}$/py/sage/models",
|
||||
"output_dir": "${HOME}$/py/sage/wwwroot/_a/xterm",
|
||||
"dbname": "sage",
|
||||
"tblname": "xterm",
|
||||
"params": {
|
||||
"logined_userid":"ownerid",
|
||||
"browserfields": {
|
||||
"exclouded": ["id", "ownerid"],
|
||||
"cwidth": {}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id",
|
||||
"ownerid"
|
||||
],
|
||||
"record_toolbar": null,
|
||||
"content_view": null
|
||||
}
|
||||
}
|
||||
BIN
minimax/MiniMax子账号相关接口 +Api账单查询(最新版).docx
Normal file
BIN
minimax/MiniMax子账号相关接口 +Api账单查询(最新版).docx
Normal file
Binary file not shown.
267
minimax/api.py
Normal file
267
minimax/api.py
Normal file
@ -0,0 +1,267 @@
|
||||
from appPublic.dictObject import DictObject
|
||||
from appPublic.oauth_client import OAuthClient
|
||||
api_desc = {
|
||||
"data":{
|
||||
"apikey":'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiJtb3FpbmcgeXUiLCJVc2VyTmFtZSI6Im1vcWluZyB5dSIsIkFjY291bnQiOiIiLCJTdWJqZWN0SUQiOiIxNzY4NTM3NjQ1ODMyNDg3NjAyIiwiUGhvbmUiOiIxMzgwMTAxNTI5MiIsIkdyb3VwSUQiOiIxNzY4NTM3NjQ1ODI4MjkyOTMwIiwiUGFnZU5hbWUiOiIiLCJNYWlsIjoiIiwiQ3JlYXRlVGltZSI6IjIwMjQtMDQtMTAgMTg6MDA6NTMiLCJpc3MiOiJtaW5pbWF4In0.VaRRHr9XMUSYhZOKVS2PRZv6Y9VCaW4JX2ks4QZX3aFr_emjnDbGv5HfNskf54piflEAeTMW4Qw1nG7bqhYea7N5LKHGf0YpesPGSoqxwyZUR4oaJNNVUsSe6eiLbdYSDO2wMb_hV5xyawh-lYe1reBKWaPVuOjfTrDhxzA0IBmzl-jAQhL8-kIZet2uX-p3NjxElpo_zjmVV_hA1BJEvTwuAk8ka-1SBZmXciMhBi1fJG4jcqoHCCN_JHJ7pgjKr5bk2Zw5qCqiU2Ecsc-kPIEK1SI5EYoLszT43UpJ8_wV4Pm07UBCn3vktAa0fjKDSUArPkBoYWSkgKDMWlmxig',
|
||||
"group_id":'1768537645828292930'
|
||||
},
|
||||
"sub_account":{
|
||||
"path":"/v1/sub_account",
|
||||
"method":"POST",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
},
|
||||
{
|
||||
"name":"Authorization",
|
||||
"value":"Bearer ${apikey}"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"GroupId",
|
||||
"value":"${group_id}"
|
||||
}
|
||||
],
|
||||
"data":[
|
||||
{
|
||||
"name":"account_name",
|
||||
"value":"${account_name}"
|
||||
}
|
||||
],
|
||||
"resp":[
|
||||
{
|
||||
"name":"subject_id",
|
||||
"resp_keys":"subject_id"
|
||||
},
|
||||
{
|
||||
"name":"account_name",
|
||||
"resp_keys":"account",
|
||||
},
|
||||
{
|
||||
"name":"password",
|
||||
"resp_keys":"password"
|
||||
},
|
||||
{
|
||||
"name":"group_id",
|
||||
"resp_keys":"group_id"
|
||||
},
|
||||
{
|
||||
"name":"apikey",
|
||||
"resp_keys":"token"
|
||||
}
|
||||
],
|
||||
"error_if":{
|
||||
"error_keys":"base_resp.status_code",
|
||||
"op":"!=",
|
||||
"value":0,
|
||||
"code_keys":"base_resp.status_code",
|
||||
"msg_keys":"base_resp.status_msg"
|
||||
}
|
||||
},
|
||||
"sub_delete":{
|
||||
"path":"/v1/sub_account/${sub_account_id}",
|
||||
"method":"DELETE",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
},
|
||||
{
|
||||
"name":"Authorization",
|
||||
"value":"Bearer ${apikey}"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"GroupId",
|
||||
"value":"${group_id}"
|
||||
}
|
||||
],
|
||||
"error_if":{
|
||||
"error_keys":"base_resp.status_code",
|
||||
"op":"!=",
|
||||
"value":0,
|
||||
"code_keys":"base_resp.status_code",
|
||||
"msg_keys":"base_resp.status_msg"
|
||||
}
|
||||
},
|
||||
"change_sub_status":{
|
||||
"path":"/v1/sub_account/${sub_account_id}/status",
|
||||
"method":"PUT",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
},
|
||||
{
|
||||
"name":"Authorization",
|
||||
"value":"Bearer ${apikey}"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"GroupId",
|
||||
"value":"${group_id}"
|
||||
}
|
||||
],
|
||||
"data":[
|
||||
{
|
||||
"name":"status",
|
||||
"value":"${status}"
|
||||
}
|
||||
],
|
||||
"error_if":{
|
||||
"error_keys":"base_resp.status_code",
|
||||
"op":"!=",
|
||||
"value":0,
|
||||
"code_keys":"base_resp.status_code",
|
||||
"msg_keys":"base_resp.status_msg"
|
||||
}
|
||||
},
|
||||
"change_sub_apikey":{
|
||||
"path":"/v1/sub_account/${sub_account_id}/token",
|
||||
"method":"PUT",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
},
|
||||
{
|
||||
"name":"Authorization",
|
||||
"value":"Bearer ${apikey}"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"GroupId",
|
||||
"value":"${group_id}"
|
||||
}
|
||||
],
|
||||
"resp":[
|
||||
{
|
||||
"name":"apikey",
|
||||
"resp_keys":"token"
|
||||
}
|
||||
],
|
||||
"error_if":{
|
||||
"error_keys":"base_resp.status_code",
|
||||
"op":"!=",
|
||||
"value":0,
|
||||
"code_keys":"base_resp.status_code",
|
||||
"msg_keys":"base_resp.status_msg"
|
||||
}
|
||||
},
|
||||
"get_sub_bill":{
|
||||
"path":"/v1/sub_account/${sub_account_id}/bill",
|
||||
"method":"GET",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
},
|
||||
{
|
||||
"name":"Authorization",
|
||||
"value":"Bearer ${apikey}"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"GroupId",
|
||||
"value":"${group_id}"
|
||||
},
|
||||
{
|
||||
"name":"method",
|
||||
"value":"${bill_type}"
|
||||
}
|
||||
],
|
||||
"resp":[
|
||||
{
|
||||
"name":"bills",
|
||||
"resp_keys":"bill_list"
|
||||
}
|
||||
],
|
||||
"error_if":{
|
||||
"error_keys":"base_resp.status_code",
|
||||
"op":"!=",
|
||||
"value":0,
|
||||
"code_keys":"base_resp.status_code",
|
||||
"msg_keys":"base_resp.status_msg"
|
||||
}
|
||||
},
|
||||
"bill":{
|
||||
"path":"/v1/batch_query_bill",
|
||||
"method":"GET",
|
||||
"headers":[
|
||||
{
|
||||
"name":"Content-Type",
|
||||
"value":"application/json"
|
||||
},
|
||||
{
|
||||
"name":"Authorization",
|
||||
"value":"Bearer ${apikey}"
|
||||
}
|
||||
],
|
||||
"params":[
|
||||
{
|
||||
"name":"GroupId",
|
||||
"value":"${group_id}"
|
||||
},
|
||||
{
|
||||
"name":"start_date",
|
||||
"value":"${start_date}"
|
||||
},
|
||||
{
|
||||
"name":"end_date",
|
||||
"value":"${end_date}"
|
||||
}
|
||||
],
|
||||
"resp":[
|
||||
{
|
||||
"name":"bills",
|
||||
"resp_keys":"bill_list"
|
||||
}
|
||||
],
|
||||
"error_if":{
|
||||
"error_keys":"base_resp.status_code",
|
||||
"op":"!=",
|
||||
"value":0,
|
||||
"code_keys":"base_resp.status_code",
|
||||
"msg_keys":"base_resp.status_msg"
|
||||
}
|
||||
}
|
||||
}
|
||||
if __name__ == '__main__':
|
||||
import asyncio
|
||||
async def main():
|
||||
m = OAuthClient(DictObject(**api_desc))
|
||||
# sub_account test ok
|
||||
# resp = await m('https://api.minimax.chat', 'sub_account', {'account_name':'test1'})
|
||||
# sub_delete test ok
|
||||
# resp = await m('https://api.minimax.chat', 'sub_delete', {'sub_account_id':'1765984131482656836'})
|
||||
# change_sub_status test ok
|
||||
# resp = await m('https://api.minimax.chat', 'change_sub_status',
|
||||
# {'sub_account_id':'1766027179931476048', 'status':0})
|
||||
# change_sub_apikey test ok
|
||||
# resp = await m('https://api.minimax.chat', 'change_sub_apikey',
|
||||
# {'sub_account_id':'1766027179931476048'})
|
||||
# get_sub_bill test, wait data to check
|
||||
# resp = await m('https://api.minimax.chat', 'get_sub_bill',
|
||||
# {'sub_account_id':'1766027179931476048',
|
||||
# bill test ok
|
||||
resp = await m('https://api.minimax.chat', 'bill',
|
||||
{
|
||||
'start_date':'20240419',
|
||||
'end_date':'20240419'})
|
||||
print(resp)
|
||||
|
||||
async def t():
|
||||
for i in range(100):
|
||||
await main()
|
||||
with open('t.py', 'r') as f:
|
||||
print('-------------------',f.fileno())
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
||||
|
||||
|
||||
185
minimax/minimax.py
Normal file
185
minimax/minimax.py
Normal file
@ -0,0 +1,185 @@
|
||||
from appPublic.jsonConfig import getConfig
|
||||
from appPublic.oauth_client import OAuthClient
|
||||
from appPublic.uniqueID import getID
|
||||
from sqlor.dbpools import DBPools
|
||||
|
||||
from ahserver.globalEnv import get_definition
|
||||
from .api import api_desc
|
||||
|
||||
class MinimaxAdm:
|
||||
def __init__(self, dbname, url_base='https://api.minimax.chat'):
|
||||
self.api_desc = api_desc
|
||||
self.name = api_desc.name
|
||||
self.dbname = dbname
|
||||
self.url_base = url_base
|
||||
self.api = OAuthClient(DictObject(**self.api_desc))
|
||||
|
||||
async def write_usage(self, userid, model, usage):
|
||||
ns = {
|
||||
'id':getID(),
|
||||
'userid':userid,
|
||||
'apiname':self.name,
|
||||
'model':model,
|
||||
'u_date':curdate(),
|
||||
'u_time':curtime(),
|
||||
'input_usage':usage.input_token,
|
||||
'output_usage':usage.output_token,
|
||||
'total_usage':usage.total_token
|
||||
}
|
||||
db = DBPools()
|
||||
async with db.sqlorContext(self.dbname) as sor:
|
||||
await sor.C('token_usage', ns)
|
||||
|
||||
async def get_account(self, userid):
|
||||
db = DBPools()
|
||||
async with db.sqlorContext(self.dbname) as sor:
|
||||
ns = {'userid':userid}
|
||||
r = await sor.sqlExe('select * from minimax_acc where userid=${userid}$', ns)
|
||||
if len(r) > 0:
|
||||
return r[0]
|
||||
return None
|
||||
asyncdef get_username(self, userid):
|
||||
db = DBPools()
|
||||
async with db.sqlorContext(self.dbname) as sor:
|
||||
ns = {'userid':userid}
|
||||
r = await sor.sqlExe('select * from users where userid=${userid}$', ns)
|
||||
if len(r) > 0:
|
||||
return r[0].username
|
||||
return None
|
||||
|
||||
async def new_account(self, ns):
|
||||
db = DBPools()
|
||||
async with db.sqlContext(self.dbname) as sor:
|
||||
await sor.C('minimax_acc', ns)
|
||||
return True
|
||||
return False
|
||||
|
||||
async def open_accoount(self, userid):
|
||||
acc = await self.get_account(userid)
|
||||
if acc:
|
||||
return acc
|
||||
username = self.get_username(userid)
|
||||
if not username:
|
||||
return False
|
||||
resp = await self.api(self.url_base,
|
||||
'sub_account',
|
||||
{'account_name':username})
|
||||
if resp.status != 'ok':
|
||||
print(resp)
|
||||
return False
|
||||
d = resp.data
|
||||
ns = {
|
||||
'id':getID(),
|
||||
'userid':userid,
|
||||
'acc_id:d.subject_id,
|
||||
'acc_name':d.account,
|
||||
'password':d.password,
|
||||
'apikey':d.token,
|
||||
'groupid':d.group_id,
|
||||
'acc_status':0
|
||||
}
|
||||
r = await self.new_account(self, ns)
|
||||
return r
|
||||
|
||||
async def delete_account(self, ns):
|
||||
db = DBPools()
|
||||
async with db.sqlContext(self.dbname) as sor:
|
||||
await sor.D('minimax_acc', ns)
|
||||
return True
|
||||
return False
|
||||
|
||||
async def update_acc(self, ns):
|
||||
db = DBPools()
|
||||
async with db.sqlorContext(self.dbname) as sor:
|
||||
r = await sor.U('minimax_acc', ns)
|
||||
return r
|
||||
return False
|
||||
|
||||
async def delete_acc(self, userid):
|
||||
acc = await self.get_account(userid)
|
||||
if acc is None:
|
||||
return False
|
||||
if acc.acc_status == 0:
|
||||
print(f'{acc_name} minimax acc is using, please disable it first')
|
||||
return False
|
||||
|
||||
resp = await self.api(self.url_base,
|
||||
'sub_delete',
|
||||
{'sub_account_id':acc.acc_id})
|
||||
if resp.status == 'ok':
|
||||
r = await self.delete_account(acc)
|
||||
return r
|
||||
return False
|
||||
|
||||
async def acc_enable(self, userid):
|
||||
return await self._acc_change_status(self, user, 0)
|
||||
|
||||
async def acc_disable(self, userid):
|
||||
return await self._acc_change_status(self, user, 2)
|
||||
|
||||
async def _acc_change_status(self, userid, status):
|
||||
acc = await self.get_account(userid)
|
||||
if acc is None:
|
||||
return False
|
||||
if acc.acc_status == status:
|
||||
return True
|
||||
resp = await self.api(self.url_base, 'ststus', {
|
||||
'sub_account_id':acc.acc_id,
|
||||
'status':status
|
||||
})
|
||||
if resp.status != 'ok':
|
||||
return False
|
||||
ns = {
|
||||
'id':acc.id,
|
||||
'status':status
|
||||
}
|
||||
return await self.update_acc(ns):
|
||||
|
||||
async def reset_apikey(self, userid):
|
||||
acc = await self.get_account(userid)
|
||||
if acc is None:
|
||||
return False
|
||||
resp = await self.api(self.url_base, 'token', {
|
||||
'sub_account_id':acc.acc_id
|
||||
})
|
||||
if resp.status != 'ok':
|
||||
return False
|
||||
ns = {
|
||||
'id':acc.id,
|
||||
'apikey':resp.apikey
|
||||
}
|
||||
return await self.update_acc(ns):
|
||||
|
||||
async def get_daily_bill(self, dat):
|
||||
acc = await self.get_account(userid)
|
||||
if acc is None:
|
||||
return False
|
||||
d = ''.join(dat.split('-'))
|
||||
resp = await self.api(self.url_base, 'bill', {
|
||||
'start_date':d,
|
||||
'end_date':d
|
||||
})
|
||||
if resp.status != 'ok':
|
||||
return await self.append_bill(resp.data.bills, dat)
|
||||
|
||||
async def append_bill(bills, dat):
|
||||
db = DBPools()
|
||||
for b in bills:
|
||||
ns = {
|
||||
'id':getID(),
|
||||
'acc_id':b.creator_id,
|
||||
'acc_name':b.creator_name,
|
||||
'model':b.model,
|
||||
'consume_time':b.consume_time,
|
||||
'consume_token':b.consume_token,
|
||||
'consume_amt':b.consume_cash,
|
||||
'create_at':b.create_at,
|
||||
'consume_date':dat
|
||||
}
|
||||
r = False
|
||||
async with db.sqlorContext(self.dbname) as sor:
|
||||
sor.C('minimax_bill', ns)
|
||||
r = True
|
||||
if not r:
|
||||
print(f'{ns} write to db error')
|
||||
return True
|
||||
92
minimax/t
Normal file
92
minimax/t
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
'status': 'ok',
|
||||
'data': {
|
||||
'bills': [
|
||||
{
|
||||
'method': 'chatcompletion-pro',
|
||||
'consume_cash': '0.0075',
|
||||
'consume_token': '75',
|
||||
'created_at': 1713517200,
|
||||
'status': 'SUCCESS',
|
||||
'model': 'abab6-chat',
|
||||
'mail': '主账户',
|
||||
'creator_id': '',
|
||||
'api_token_name': 'open computing',
|
||||
'group_id': '1768537645828292930',
|
||||
'creator_name': '主账户',
|
||||
'ymd': '',
|
||||
'consume_time': '2024年04月19日 17:00-18:00'
|
||||
}, {
|
||||
'method': 'chatcompletion-pro',
|
||||
'consume_cash': '0.0057',
|
||||
'consume_token': '57',
|
||||
'created_at': 1713434400,
|
||||
'status': 'SUCCESS',
|
||||
'model': 'abab6-chat',
|
||||
'mail': '主账户',
|
||||
'creator_id': '',
|
||||
'api_token_name': 'open computing',
|
||||
'group_id': '1768537645828292930',
|
||||
'creator_name': '主账户',
|
||||
'ymd': '',
|
||||
'consume_time': '2024年04月18日 18:00-19:00'
|
||||
}, {
|
||||
'method': 'chatcompletion-pro',
|
||||
'consume_cash': '0.0467',
|
||||
'consume_token': '467',
|
||||
'created_at': 1713430800,
|
||||
'status': 'SUCCESS',
|
||||
'model': 'abab6-chat',
|
||||
'mail': '主账户',
|
||||
'creator_id': '',
|
||||
'api_token_name': 'open computing',
|
||||
'group_id': '1768537645828292930',
|
||||
'creator_name': '主账户',
|
||||
'ymd': '',
|
||||
'consume_time': '2024年04月18日 17:00-18:00'
|
||||
}, {
|
||||
'method': 'chatcompletion-pro',
|
||||
'consume_cash': '0.1040',
|
||||
'consume_token': '1040',
|
||||
'created_at': 1713348000,
|
||||
'status': 'SUCCESS',
|
||||
'model': 'abab6-chat',
|
||||
'mail': '主账户',
|
||||
'creator_id': '',
|
||||
'api_token_name': 'open computing',
|
||||
'group_id': '1768537645828292930',
|
||||
'creator_name': '主账户',
|
||||
'ymd': '',
|
||||
'consume_time': '2024年04月17日 18:00-19:00'
|
||||
}, {
|
||||
'method': 'chatcompletion-pro',
|
||||
'consume_cash': '0.1102',
|
||||
'consume_token': '1102',
|
||||
'created_at': 1713344400,
|
||||
'status': 'SUCCESS',
|
||||
'model': 'abab6-chat',
|
||||
'mail': '主账户',
|
||||
'creator_id': '',
|
||||
'api_token_name': 'open computing',
|
||||
'group_id': '1768537645828292930',
|
||||
'creator_name': '主账户',
|
||||
'ymd': '',
|
||||
'consume_time': '2024年04月17日 17:00-18:00'
|
||||
}, {
|
||||
'method': 'chatcompletion-pro',
|
||||
'consume_cash': '0.0106',
|
||||
'consume_token': '708',
|
||||
'created_at': 1713340800,
|
||||
'status': 'SUCCESS',
|
||||
'model': 'abab5.5-chat',
|
||||
'mail': '主账户',
|
||||
'creator_id': '',
|
||||
'api_token_name': 'open computing',
|
||||
'group_id': '1768537645828292930',
|
||||
'creator_name': '主账户',
|
||||
'ymd': '',
|
||||
'consume_time': '2024年04月17日 16:00-17:00'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
models/.DS_Store
vendored
Normal file
BIN
models/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
models/apiparams.xlsx
Normal file
BIN
models/apiparams.xlsx
Normal file
Binary file not shown.
BIN
models/appcodes.xlsx
Normal file
BIN
models/appcodes.xlsx
Normal file
Binary file not shown.
BIN
models/appcodes_kv.xlsx
Normal file
BIN
models/appcodes_kv.xlsx
Normal file
Binary file not shown.
BIN
models/feelog.xlsx
Normal file
BIN
models/feelog.xlsx
Normal file
Binary file not shown.
BIN
models/httpapi.xlsx
Normal file
BIN
models/httpapi.xlsx
Normal file
Binary file not shown.
BIN
models/minimax_acc.xlsx
Normal file
BIN
models/minimax_acc.xlsx
Normal file
Binary file not shown.
BIN
models/minimax_bill.xlsx
Normal file
BIN
models/minimax_bill.xlsx
Normal file
Binary file not shown.
BIN
models/modelapi.xlsx
Normal file
BIN
models/modelapi.xlsx
Normal file
Binary file not shown.
BIN
models/modelinstance.xlsx
Normal file
BIN
models/modelinstance.xlsx
Normal file
Binary file not shown.
BIN
models/modeliodata.xlsx
Normal file
BIN
models/modeliodata.xlsx
Normal file
Binary file not shown.
BIN
models/modelpricing.xlsx
Normal file
BIN
models/modelpricing.xlsx
Normal file
Binary file not shown.
BIN
models/modelprovider.xlsx
Normal file
BIN
models/modelprovider.xlsx
Normal file
Binary file not shown.
BIN
models/models.xlsx
Normal file
BIN
models/models.xlsx
Normal file
Binary file not shown.
BIN
models/modeltype.xlsx
Normal file
BIN
models/modeltype.xlsx
Normal file
Binary file not shown.
BIN
models/modeltypein.xlsx
Normal file
BIN
models/modeltypein.xlsx
Normal file
Binary file not shown.
BIN
models/modeltypeout.xlsx
Normal file
BIN
models/modeltypeout.xlsx
Normal file
Binary file not shown.
6581
models/mysql.ddl.sql
Normal file
6581
models/mysql.ddl.sql
Normal file
File diff suppressed because it is too large
Load Diff
BIN
models/org_roles.xlsx
Normal file
BIN
models/org_roles.xlsx
Normal file
Binary file not shown.
BIN
models/organization.xlsx
Normal file
BIN
models/organization.xlsx
Normal file
Binary file not shown.
BIN
models/orgtypes.xlsx
Normal file
BIN
models/orgtypes.xlsx
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user