Spaces:
Sleeping
Sleeping
db
Browse files- .gitignore +2 -1
- api_keys.db +0 -0
- app.py +47 -12
- captcha.png +0 -0
- db.py +64 -0
- requirements.txt +5 -1
- routers/openai_v1.py +86 -0
- routers/users_v1.py +48 -0
- routers/webtools_v1.py +29 -0
- sql.md +88 -0
- test_db.py +22 -0
- users.sql +41 -0
.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1 |
-
__pycache__/
|
|
|
|
1 |
+
__pycache__/
|
2 |
+
.env
|
api_keys.db
ADDED
Binary file (12.3 kB). View file
|
|
app.py
CHANGED
@@ -1,19 +1,54 @@
|
|
1 |
# uvicorn app:app --host 0.0.0.0 --port 7860 --reload
|
2 |
|
3 |
-
from fastapi import FastAPI, HTTPException
|
4 |
from starlette.requests import Request
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
app = FastAPI()
|
7 |
|
|
|
|
|
|
|
|
|
8 |
@app.get("/")
|
9 |
-
def greet_json():
|
10 |
-
|
11 |
-
|
12 |
-
@app.
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# uvicorn app:app --host 0.0.0.0 --port 7860 --reload
|
2 |
|
3 |
+
from fastapi import FastAPI, HTTPException, Response, Depends
|
4 |
from starlette.requests import Request
|
5 |
|
6 |
+
from routers.webtools_v1 import router as webtools_router
|
7 |
+
from routers.users_v1 import router as users_router
|
8 |
+
from routers.openai_v1 import router as openai_router
|
9 |
+
|
10 |
+
from db import Db
|
11 |
+
|
12 |
+
from dotenv import load_dotenv
|
13 |
+
import os
|
14 |
+
|
15 |
+
# 加载.env文件
|
16 |
+
load_dotenv()
|
17 |
+
|
18 |
+
DB_PATH = os.getenv("DB_PATH")
|
19 |
+
|
20 |
+
# 依赖注入,获取 DB_PATH
|
21 |
+
def get_db_path():
|
22 |
+
return DB_PATH
|
23 |
+
|
24 |
app = FastAPI()
|
25 |
|
26 |
+
app.include_router(webtools_router, prefix="/airs/v1", tags=["webtools"])
|
27 |
+
app.include_router(users_router, prefix="/airs/v1", tags=["users"])
|
28 |
+
app.include_router(openai_router, prefix="/airs/v1", tags=["openai"])
|
29 |
+
|
30 |
@app.get("/")
|
31 |
+
def greet_json(db_path: str = Depends(get_db_path)):
|
32 |
+
print(DB_PATH)
|
33 |
+
return {"Hello": "World!"}
|
34 |
+
@app.get("/init_db")
|
35 |
+
def init_db():
|
36 |
+
sql = """
|
37 |
+
CREATE TABLE api_keys (
|
38 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
39 |
+
api_key TEXT NOT NULL,
|
40 |
+
type TEXT NOT NULL,
|
41 |
+
status INTEGER NOT NULL,
|
42 |
+
idx INTEGER NOT NULL,
|
43 |
+
dest_api_key TEXT NOT NULL
|
44 |
+
);
|
45 |
+
"""
|
46 |
+
Db('api_keys.db').execute_query(sql)
|
47 |
+
|
48 |
+
# def create_user_api_key(user_id, api_key, type, status, idx, dest_api_key):
|
49 |
+
# sql = f"""
|
50 |
+
# INSERT INTO api_keys (api_key, type, status, idx, dest_api_key)
|
51 |
+
# """
|
52 |
+
# Db('api_keys.db').execute_query(sql)
|
53 |
+
|
54 |
+
# create_user_api_key('i_am_tanbushi', 'llm', '1', '0', 'dest_api_key')
|
captcha.png
ADDED
![]() |
db.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import sqlite3
|
2 |
+
import json
|
3 |
+
|
4 |
+
class Db():
|
5 |
+
def __init__(self, db_path):
|
6 |
+
self.db_path = db_path
|
7 |
+
# print(self.db_path)
|
8 |
+
|
9 |
+
def list_query(self, query):
|
10 |
+
conn = sqlite3.connect(self.db_path)
|
11 |
+
cursor = conn.cursor()
|
12 |
+
cursor.execute(query)
|
13 |
+
conn.commit()
|
14 |
+
|
15 |
+
rows = cursor.fetchall()
|
16 |
+
# print('results')
|
17 |
+
# print(results)
|
18 |
+
cursor.close()
|
19 |
+
conn.close()
|
20 |
+
|
21 |
+
json_rows = []
|
22 |
+
# 为每一行结果创建一个字典,并添加到列表中
|
23 |
+
for row in rows:
|
24 |
+
# 使用cursor.description获取列名和相关信息
|
25 |
+
columns = dict(zip([col[0] for col in cursor.description], row))
|
26 |
+
json_rows.append(columns)
|
27 |
+
|
28 |
+
return json_rows
|
29 |
+
|
30 |
+
def insert_query(self, query):
|
31 |
+
conn = sqlite3.connect(self.db_path)
|
32 |
+
cursor = conn.cursor()
|
33 |
+
cursor.execute(query)
|
34 |
+
conn.commit()
|
35 |
+
rowcount = cursor.rowcount
|
36 |
+
|
37 |
+
return f"插入的行数: {rowcount}"
|
38 |
+
|
39 |
+
def update_query(self, query):
|
40 |
+
conn = sqlite3.connect(self.db_path)
|
41 |
+
cursor = conn.cursor()
|
42 |
+
cursor.execute(query)
|
43 |
+
conn.commit()
|
44 |
+
rowcount = cursor.rowcount
|
45 |
+
|
46 |
+
return f"影响的行数: {rowcount}"
|
47 |
+
# from fastapi import FastAPI
|
48 |
+
|
49 |
+
# # 依赖注入,获取 FastAPI 应用实例
|
50 |
+
# def get_app() -> FastAPI:
|
51 |
+
# return FastAPI()
|
52 |
+
|
53 |
+
# def execute_query(query):
|
54 |
+
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
# CREATE TABLE api_keys (
|
59 |
+
# api_key TEXT NOT NULL,
|
60 |
+
# type TEXT NOT NULL,
|
61 |
+
# status INTEGER NOT NULL,
|
62 |
+
# idx INTEGER NOT NULL,
|
63 |
+
# PRIMARY KEY (api_key, type, status, idx)
|
64 |
+
# );
|
requirements.txt
CHANGED
@@ -1,2 +1,6 @@
|
|
1 |
fastapi
|
2 |
-
uvicorn[standard]
|
|
|
|
|
|
|
|
|
|
1 |
fastapi
|
2 |
+
uvicorn[standard]
|
3 |
+
captcha
|
4 |
+
python-dotenv
|
5 |
+
langchain_google_genai==1.0.10
|
6 |
+
langchain-openai==0.1.25 # 使用 openai 或兼容 openai
|
routers/openai_v1.py
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Request, HTTPException
|
2 |
+
from db import Db
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
import os, json
|
5 |
+
from langchain_core.output_parsers import StrOutputParser
|
6 |
+
from langchain_core.prompts import ChatPromptTemplate
|
7 |
+
|
8 |
+
# 加载.env文件
|
9 |
+
load_dotenv()
|
10 |
+
|
11 |
+
router = APIRouter()
|
12 |
+
|
13 |
+
@router.post("/chat/completions")
|
14 |
+
async def chat_completions(request:Request):
|
15 |
+
print('chat_completions')
|
16 |
+
auth_header = request.headers['authorization']
|
17 |
+
user_api_key = auth_header.split()[1] # 分割字符串并取第二个元素
|
18 |
+
data = await request.json()
|
19 |
+
try:
|
20 |
+
model = data['model']
|
21 |
+
except:
|
22 |
+
model = ''
|
23 |
+
if model=='':
|
24 |
+
model = await get_default_model()
|
25 |
+
api_key_info = await get_api_key(model)
|
26 |
+
api_key = api_key_info['api_key']
|
27 |
+
group_name = api_key_info['group_name']
|
28 |
+
|
29 |
+
|
30 |
+
# 下面是google api
|
31 |
+
if group_name=='gemini':
|
32 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
33 |
+
# 初始化模型
|
34 |
+
llm = ChatGoogleGenerativeAI(
|
35 |
+
api_key = api_key,
|
36 |
+
model = model,
|
37 |
+
)
|
38 |
+
|
39 |
+
|
40 |
+
# 下面就是 chatgpt 兼容 api
|
41 |
+
if group_name=='glm':
|
42 |
+
from langchain_openai import ChatOpenAI
|
43 |
+
# 初始化 ChatOpenAI 模型
|
44 |
+
llm = ChatOpenAI(
|
45 |
+
model = model,
|
46 |
+
api_key = api_key,
|
47 |
+
base_url = 'https://open.bigmodel.cn/api/paas/v4', # 下一步将base_url 写到数据库里
|
48 |
+
)
|
49 |
+
|
50 |
+
messages = data['messages']
|
51 |
+
rslt = [(item["role"], item["content"]) for item in messages] # 转换为所需的元组列表格式
|
52 |
+
parser = StrOutputParser()
|
53 |
+
prompt_template = ChatPromptTemplate.from_messages(rslt)
|
54 |
+
|
55 |
+
chain = prompt_template | llm | parser
|
56 |
+
result = chain.invoke({})
|
57 |
+
return result
|
58 |
+
|
59 |
+
async def get_default_model():
|
60 |
+
results = Db(os.getenv("DB_PATH")).list_query("SELECT * FROM api_names order by default_order limit 1")
|
61 |
+
try:
|
62 |
+
result = results[0]['api_name']
|
63 |
+
except:
|
64 |
+
result = ''
|
65 |
+
return result
|
66 |
+
|
67 |
+
async def get_api_key(model):
|
68 |
+
sql = f"""
|
69 |
+
SELECT an.api_name, ak.api_key, ag.group_name
|
70 |
+
FROM api_keys ak
|
71 |
+
JOIN api_groups ag ON ak.api_group_id = ag.id
|
72 |
+
JOIN api_names an ON an.api_group_id = ag.id
|
73 |
+
WHERE ak.category='LLM' and an.api_name='{model}' and disabled=0
|
74 |
+
ORDER BY ak.last_call_at
|
75 |
+
limit 1
|
76 |
+
"""
|
77 |
+
results = Db(os.getenv("DB_PATH")).list_query(sql)
|
78 |
+
try:
|
79 |
+
result = results[0]
|
80 |
+
api_key = result['api_key']
|
81 |
+
except:
|
82 |
+
api_key = ''
|
83 |
+
|
84 |
+
sql = f"update api_keys set last_call_at=datetime('now') where api_key='{api_key}'"
|
85 |
+
Db(os.getenv("DB_PATH")).update_query(sql)
|
86 |
+
return result
|
routers/users_v1.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Request, FastAPI, Depends
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
import os
|
4 |
+
import uuid
|
5 |
+
from db import Db
|
6 |
+
|
7 |
+
router = APIRouter()
|
8 |
+
|
9 |
+
# 加载.env文件
|
10 |
+
load_dotenv()
|
11 |
+
|
12 |
+
DB_PATH = os.getenv("DB_PATH")
|
13 |
+
|
14 |
+
# 依赖注入,获取 DB_PATH
|
15 |
+
def get_db_path():
|
16 |
+
return DB_PATH
|
17 |
+
|
18 |
+
@router.get("/users")
|
19 |
+
async def read_users(db_path: str = Depends(get_db_path)):
|
20 |
+
# print('\n\n\n\n\n')
|
21 |
+
# print(db_path)
|
22 |
+
result = Db(db_path).list_query("SELECT * FROM users")
|
23 |
+
return result
|
24 |
+
|
25 |
+
@router.post("/users")
|
26 |
+
async def create_user(request: Request, b_path: str = Depends(get_db_path)):
|
27 |
+
request_json = await request.json()
|
28 |
+
username = request_json.get('username')
|
29 |
+
password = request_json.get('password')
|
30 |
+
email = request_json.get('email')
|
31 |
+
nikename = request_json.get('nikename')
|
32 |
+
if nikename==None:
|
33 |
+
nikename = ''
|
34 |
+
# print(nikename)
|
35 |
+
api_key = f'airs-{uuid.uuid4()}'
|
36 |
+
# result = api_key
|
37 |
+
# print(api_key)
|
38 |
+
result = Db(b_path).insert_query(f"INSERT INTO users (username, password, email, nikename, api_key) VALUES ('{username}', '{password}', '{email}', '{nikename}', '{api_key}')")
|
39 |
+
return result
|
40 |
+
|
41 |
+
@router.get("/users/{id}")
|
42 |
+
async def read_user(request: Request, id:int, db_path: str = Depends(get_db_path)):
|
43 |
+
result = Db(db_path).list_query(f"SELECT * FROM users where id={id}")
|
44 |
+
if len(result)>0:
|
45 |
+
return result[0]
|
46 |
+
else:
|
47 |
+
return None
|
48 |
+
|
routers/webtools_v1.py
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, APIRouter, Response, Depends
|
2 |
+
from captcha.image import ImageCaptcha
|
3 |
+
from io import BytesIO
|
4 |
+
|
5 |
+
router = APIRouter()
|
6 |
+
|
7 |
+
# 依赖注入,获取 FastAPI 应用实例
|
8 |
+
def get_app() -> FastAPI:
|
9 |
+
return FastAPI()
|
10 |
+
|
11 |
+
@router.get("/webtools/captcha")
|
12 |
+
async def get_captcha(app: FastAPI = Depends(get_app)):
|
13 |
+
# 生成随机验证码字符串
|
14 |
+
captcha_text = "123456" # 这里只是一个示例,实际应用中应该生成一个随机字符串
|
15 |
+
# 创建验证码图片
|
16 |
+
image = ImageCaptcha(width=280, height=90)
|
17 |
+
image.write(captcha_text, "captcha.png")
|
18 |
+
|
19 |
+
# 将验证码字符串存储在内存中,以便后续验证
|
20 |
+
# 注意:实际应用中应该使用更安全的方式存储验证码,例如使用会话或数据库
|
21 |
+
app.captcha_text = captcha_text
|
22 |
+
|
23 |
+
# 读取图片内容并返回
|
24 |
+
image_buffer = BytesIO()
|
25 |
+
image.write(captcha_text, image_buffer)
|
26 |
+
image_buffer.seek(0)
|
27 |
+
|
28 |
+
# 返回图片数据
|
29 |
+
return Response(content=image_buffer.getvalue(), media_type="image/png")
|
sql.md
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
当然,以下是完整的SQL语句,用于创建`api_names`、`api_keys`表,以及可选的`api_usage`表。这些表将支持存储API名称、API-KEY信息,并可选地记录API的使用情况。
|
2 |
+
|
3 |
+
### SQL 创建表的语句
|
4 |
+
|
5 |
+
```sql
|
6 |
+
-- 创建 users 表
|
7 |
+
DROP TABLE IF EXISTS "users";
|
8 |
+
CREATE TABLE "users" (
|
9 |
+
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
|
10 |
+
"username" TEXT NOT NULL,
|
11 |
+
"password" TEXT NOT NULL,
|
12 |
+
"email" TEXT NOT NULL,
|
13 |
+
"nikename" TEXT,
|
14 |
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
15 |
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
16 |
+
UNIQUE ("username" ASC),
|
17 |
+
UNIQUE ("email" ASC)
|
18 |
+
);
|
19 |
+
|
20 |
+
-- 创建api_groups表
|
21 |
+
CREATE TABLE api_groups (
|
22 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
23 |
+
group_name TEXT NOT NULL UNIQUE,
|
24 |
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
25 |
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
26 |
+
);
|
27 |
+
|
28 |
+
-- 创建api_names表
|
29 |
+
CREATE TABLE api_names (
|
30 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
31 |
+
api_name TEXT NOT NULL UNIQUE,
|
32 |
+
api_group_id INTEGER,
|
33 |
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
34 |
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
35 |
+
FOREIGN KEY (api_group_id) REFERENCES api_groups(id) ON DELETE SET NULL
|
36 |
+
);
|
37 |
+
|
38 |
+
-- 创建api_keys表
|
39 |
+
CREATE TABLE api_keys (
|
40 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
41 |
+
api_group_id INTEGER NOT NULL,
|
42 |
+
api_key TEXT NOT NULL,
|
43 |
+
category TEXT NOT NULL,
|
44 |
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
45 |
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
46 |
+
FOREIGN KEY (api_group_id) REFERENCES api_groups(id) ON DELETE CASCADE
|
47 |
+
);
|
48 |
+
|
49 |
+
-- 创建user_api_keys表
|
50 |
+
CREATE TABLE user_api_keys (
|
51 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
52 |
+
user_api_key TEXT NOT NULL,
|
53 |
+
user_id INTEGER,
|
54 |
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
55 |
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
56 |
+
);
|
57 |
+
|
58 |
+
-- 创建api_usage表(如果需要)
|
59 |
+
CREATE TABLE api_usage (
|
60 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
61 |
+
user_api_key_id INTEGER,
|
62 |
+
api_key_id INTEGER,
|
63 |
+
request_count INTEGER DEFAULT 0,
|
64 |
+
last_used DATETIME DEFAULT CURRENT_TIMESTAMP,
|
65 |
+
FOREIGN KEY (user_api_key_id) REFERENCES user_api_keys(id),
|
66 |
+
FOREIGN KEY (api_key_id) REFERENCES api_keys(id)
|
67 |
+
);
|
68 |
+
```
|
69 |
+
|
70 |
+
### 说明
|
71 |
+
|
72 |
+
- **`api_names` 表**:存储唯一的API名称。
|
73 |
+
- **`api_keys` 表**:存储每个API名称对应的多个API-KEY,包括分类信息。`api_names_id`作为外键,关联到`api_names`表。
|
74 |
+
- **`user_api_keys` 表**:存储用户的API-KEY。
|
75 |
+
- **`api_usage` 表**(可选):记录API的使用情况,包括请求次数和最后使用时间。这个表可以用来监控API的使用情况,帮助管理API-KEY的使用限额。
|
76 |
+
|
77 |
+
这些SQL语句假设你使用的是MySQL数据库。如果你使用的是其他类型的数据库(如PostgreSQL、SQLite等),可能需要对SQL语句进行适当的调整。如果有任何问题或需要进一步的帮助,请随时告诉我。
|
78 |
+
|
79 |
+
|
80 |
+
|
81 |
+
### 通过 api_name 查询 api_key 的 SQL 语句
|
82 |
+
```sql
|
83 |
+
SELECT ak.api_key
|
84 |
+
FROM api_keys ak
|
85 |
+
JOIN api_groups ag ON ak.api_group_id = ag.id
|
86 |
+
JOIN api_names an ON an.api_group_id = ag.id
|
87 |
+
WHERE an.api_name = 'your_api_name';
|
88 |
+
```
|
test_db.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# PC上数据库的位置为:/mnt/f/微云同步目录/1913864316/dev/projects/api-mapper
|
2 |
+
|
3 |
+
from db import Db
|
4 |
+
from dotenv import load_dotenv
|
5 |
+
import os
|
6 |
+
|
7 |
+
# 加载.env文件
|
8 |
+
load_dotenv()
|
9 |
+
|
10 |
+
db = Db(os.getenv("DB_PATH"))
|
11 |
+
|
12 |
+
results = db.execute_query("""
|
13 |
+
SELECT an.api_name, ak.api_key
|
14 |
+
FROM api_keys ak
|
15 |
+
JOIN api_groups ag ON ak.api_group_id = ag.id
|
16 |
+
JOIN api_names an ON an.api_group_id = ag.id
|
17 |
+
WHERE an.api_name = 'glm-4-flash';
|
18 |
+
""")
|
19 |
+
|
20 |
+
|
21 |
+
for row in results:
|
22 |
+
print(row)
|
users.sql
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
Navicat Premium Dump SQL
|
3 |
+
|
4 |
+
Source Server : api_keys
|
5 |
+
Source Server Type : SQLite
|
6 |
+
Source Server Version : 3045000 (3.45.0)
|
7 |
+
Source Schema : main
|
8 |
+
|
9 |
+
Target Server Type : SQLite
|
10 |
+
Target Server Version : 3045000 (3.45.0)
|
11 |
+
File Encoding : 65001
|
12 |
+
|
13 |
+
Date: 03/11/2024 20:45:36
|
14 |
+
*/
|
15 |
+
|
16 |
+
PRAGMA foreign_keys = false;
|
17 |
+
|
18 |
+
-- ----------------------------
|
19 |
+
-- Table structure for users
|
20 |
+
-- ----------------------------
|
21 |
+
DROP TABLE IF EXISTS "users";
|
22 |
+
CREATE TABLE "users" (
|
23 |
+
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
|
24 |
+
"username" TEXT NOT NULL,
|
25 |
+
"password" TEXT NOT NULL,
|
26 |
+
"email" TEXT NOT NULL,
|
27 |
+
"nikename" TEXT,
|
28 |
+
"api_key" TEXT,
|
29 |
+
"config" TEXT,
|
30 |
+
"created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
31 |
+
"updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
|
32 |
+
UNIQUE ("username" ASC),
|
33 |
+
UNIQUE ("email" ASC)
|
34 |
+
);
|
35 |
+
|
36 |
+
-- ----------------------------
|
37 |
+
-- Auto increment value for users
|
38 |
+
-- ----------------------------
|
39 |
+
UPDATE "sqlite_sequence" SET seq = 5 WHERE name = 'users';
|
40 |
+
|
41 |
+
PRAGMA foreign_keys = true;
|