Compare commits
7 Commits
2c893df2cf
...
8884e92f2d
| Author | SHA1 | Date |
|---|---|---|
|
|
8884e92f2d | |
|
|
f2956d6f28 | |
|
|
9a78e476b0 | |
|
|
94f46857c6 | |
|
|
4194e9e12f | |
|
|
3d35e7325e | |
|
|
055cad882b |
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="SqlDialectMappings">
|
|
||||||
<file url="file://$PROJECT_DIR$/migrations/models/11_20250803092810_update.py" dialect="MySQL" />
|
|
||||||
<file url="file://$PROJECT_DIR$/migrations/models/16_20250806104900_update.py" dialect="GenericSQL" />
|
|
||||||
<file url="file://$PROJECT_DIR$/migrations/models/21_20250827100315_update.py" dialect="MySQL" />
|
|
||||||
<file url="file://$PROJECT_DIR$/migrations/models/33_20250929111212_update.py" dialect="MySQL" />
|
|
||||||
<file url="file://$PROJECT_DIR$/scripts/update_fr.py" dialect="MySQL" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -768,7 +768,8 @@ Authorization: Bearer <your_jwt_token>
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"title_content": "我的作文全文......",
|
"theme": "标题(可选)",
|
||||||
|
"content": "正文内容",
|
||||||
"article_type": "议论文"
|
"article_type": "议论文"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ async def get_and_set_last_key(redis: Redis, word: str, user_id: str):
|
||||||
print(last_word)
|
print(last_word)
|
||||||
|
|
||||||
# 如果上一次查的词和这次不同,就清空旧词的记录
|
# 如果上一次查的词和这次不同,就清空旧词的记录
|
||||||
if last_word and last_word != word:
|
if last_word and last_word.decode() != word:
|
||||||
await clear_chat_history(redis, user_id, last_word.decode())
|
await clear_chat_history(redis, user_id, last_word.decode())
|
||||||
|
|
||||||
# 更新当前词
|
# 更新当前词
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class UserArticleRequest(BaseModel):
|
class UserArticleRequest(BaseModel):
|
||||||
# theme: Optional[str]
|
theme: Optional[str]
|
||||||
title_content: str
|
content: str
|
||||||
article_type: str
|
article_type: str
|
||||||
|
|
||||||
class UserQuery(BaseModel):
|
class UserQuery(BaseModel):
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ async def article_director(
|
||||||
article_lang = "法语" if lang == "fr-FR" else "日语"
|
article_lang = "法语" if lang == "fr-FR" else "日语"
|
||||||
|
|
||||||
user_id = user[0].id
|
user_id = user[0].id
|
||||||
article = upload_article.title_content
|
article = upload_article.content
|
||||||
|
|
||||||
# 读取历史对话
|
# 读取历史对话
|
||||||
session = await service.get_session(redis_client=redis, user_id=user_id)
|
session = await service.get_session(redis_client=redis, user_id=user_id)
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,16 @@ def chat_ecnu_request(
|
||||||
|
|
||||||
return completion
|
return completion
|
||||||
|
|
||||||
|
|
||||||
def set_user_prompt(user_article: UserArticleRequest, article_lang: str):
|
def set_user_prompt(user_article: UserArticleRequest, article_lang: str):
|
||||||
user_prompt = f"以下是我的{article_lang}作文,作文体裁为{user_article.article_type},请帮我修改:{user_article.title_content}"
|
if user_article.theme is not None:
|
||||||
|
user_prompt = f"以下是我的{article_lang}作文,作文体裁为{user_article.article_type},标题为{user_article.theme}, 请帮我修改:{user_article.content}"
|
||||||
|
else:
|
||||||
|
user_prompt = f"以下是我的{article_lang}作文,作文体裁为{user_article.article_type}, 请帮我修改:{user_article.content}"
|
||||||
|
|
||||||
return user_prompt
|
return user_prompt
|
||||||
|
|
||||||
|
|
||||||
async def get_session(redis_client: Redis, user_id: str) -> List[Dict[str, str]]:
|
async def get_session(redis_client: Redis, user_id: str) -> List[Dict[str, str]]:
|
||||||
"""从 Redis 读取对话上下文"""
|
"""从 Redis 读取对话上下文"""
|
||||||
data = await redis_client.get(f"session:{user_id}")
|
data = await redis_client.get(f"session:{user_id}")
|
||||||
|
|
@ -55,10 +61,12 @@ async def get_session(redis_client: Redis, user_id: str) -> List[Dict[str, str]]
|
||||||
# 如果没有记录,创建带 system prompt 的初始会话
|
# 如果没有记录,创建带 system prompt 的初始会话
|
||||||
return [{"role": "system", "content": SYSTEM_PROMPT}]
|
return [{"role": "system", "content": SYSTEM_PROMPT}]
|
||||||
|
|
||||||
|
|
||||||
async def save_session(redis_client: Redis, user_id: str, session: List[Dict[str, str]]):
|
async def save_session(redis_client: Redis, user_id: str, session: List[Dict[str, str]]):
|
||||||
"""保存对话上下文到 Redis"""
|
"""保存对话上下文到 Redis"""
|
||||||
await redis_client.setex(f"session:{user_id}", 86400, json.dumps(session))
|
await redis_client.setex(f"session:{user_id}", 86400, json.dumps(session))
|
||||||
|
|
||||||
|
|
||||||
async def reset_session(redis_client: Redis, user_id: str):
|
async def reset_session(redis_client: Redis, user_id: str):
|
||||||
"""清空用户上下文"""
|
"""清空用户上下文"""
|
||||||
await redis_client.delete(f"session:{user_id}")
|
await redis_client.delete(f"session:{user_id}")
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,10 @@ async def search(request: Request, body: SearchRequest, user=Depends(get_current
|
||||||
:param user:
|
:param user:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
redis = request.app.state.redis
|
||||||
|
|
||||||
query = body.query
|
query = body.query
|
||||||
|
|
||||||
if body.language == 'fr':
|
if body.language == 'fr':
|
||||||
query = normalize_text(query)
|
query = normalize_text(query)
|
||||||
word_contents = await (
|
word_contents = await (
|
||||||
|
|
@ -100,6 +103,9 @@ async def search(request: Request, body: SearchRequest, user=Depends(get_current
|
||||||
eng_explanation=wc.eng_explanation,
|
eng_explanation=wc.eng_explanation,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await service.search_time_updates(redis)
|
||||||
|
|
||||||
return WordSearchResponse(
|
return WordSearchResponse(
|
||||||
query=query,
|
query=query,
|
||||||
pos=pos_contents,
|
pos=pos_contents,
|
||||||
|
|
@ -130,6 +136,9 @@ async def search(request: Request, body: SearchRequest, user=Depends(get_current
|
||||||
example=wc.example,
|
example=wc.example,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await service.search_time_updates(redis)
|
||||||
|
|
||||||
return WordSearchResponse(
|
return WordSearchResponse(
|
||||||
query=query,
|
query=query,
|
||||||
pos=pos_contents,
|
pos=pos_contents,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import re
|
||||||
from typing import List, Tuple, Dict, Literal, Type
|
from typing import List, Tuple, Dict, Literal, Type
|
||||||
|
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
|
from redis.asyncio import Redis
|
||||||
from tortoise import Tortoise, Model
|
from tortoise import Tortoise, Model
|
||||||
from tortoise.expressions import Q
|
from tortoise.expressions import Q
|
||||||
|
|
||||||
|
|
@ -12,6 +13,12 @@ from app.utils.textnorm import normalize_text
|
||||||
from settings import TORTOISE_ORM
|
from settings import TORTOISE_ORM
|
||||||
|
|
||||||
|
|
||||||
|
async def search_time_updates(redis: Redis) -> None:
|
||||||
|
key = "search_time"
|
||||||
|
|
||||||
|
await redis.incr(key, 1)
|
||||||
|
|
||||||
|
|
||||||
async def detect_language(text: str) -> Tuple[str, str, bool]:
|
async def detect_language(text: str) -> Tuple[str, str, bool]:
|
||||||
"""
|
"""
|
||||||
自动检测输入语言:
|
自动检测输入语言:
|
||||||
|
|
|
||||||
|
|
@ -78,13 +78,13 @@ async def baidu_translation(query: str, from_lang: str, to_lang: str):
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise HTTPException(status_code=500, detail=response.text)
|
raise HTTPException(status_code=500, detail=response.json())
|
||||||
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
print(json.dumps(data, indent=2, ensure_ascii=False))
|
print(json.dumps(data, indent=2, ensure_ascii=False))
|
||||||
|
|
||||||
if "trans_result" not in data:
|
if "trans_result" not in data:
|
||||||
raise HTTPException(status_code=500, detail=data.get("error_msg", "Unknown error"))
|
raise HTTPException(status_code=500, detail={"error_code": data.get("error_code"), "error_msg": data.get("error_msg")})
|
||||||
|
|
||||||
return "\n".join([item["dst"] for item in data["trans_result"]])
|
return "\n".join([item["dst"] for item in data["trans_result"]])
|
||||||
|
|
||||||
|
|
@ -117,13 +117,17 @@ async def rate_limiter(
|
||||||
@translator_router.post('/translate', response_model=TransResponse, dependencies=[Depends(rate_limiter)])
|
@translator_router.post('/translate', response_model=TransResponse, dependencies=[Depends(rate_limiter)])
|
||||||
async def translate(
|
async def translate(
|
||||||
translate_request: TransRequest,
|
translate_request: TransRequest,
|
||||||
user=Depends(get_current_user)
|
user: Tuple[User, Dict] = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
text = await baidu_translation(
|
try:
|
||||||
query=translate_request.query,
|
text = await baidu_translation(
|
||||||
from_lang=translate_request.from_lang,
|
query=translate_request.query,
|
||||||
to_lang=translate_request.to_lang,
|
from_lang=translate_request.from_lang,
|
||||||
)
|
to_lang=translate_request.to_lang,
|
||||||
|
)
|
||||||
|
except HTTPException as e:
|
||||||
|
print(e.status_code, e.detail)
|
||||||
|
raise HTTPException(status_code=400, detail=e.detail)
|
||||||
return TransResponse(translated_text=text)
|
return TransResponse(translated_text=text)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -144,4 +148,5 @@ async def test_translate(
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
raw = await baidu_translation(query, from_lang, to_lang)
|
raw = await baidu_translation(query, from_lang, to_lang)
|
||||||
|
print(raw)
|
||||||
return TransResponse(translated_text=raw)
|
return TransResponse(translated_text=raw)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#TODO 更新接口文档
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from starlette.requests import Request
|
||||||
|
|
||||||
|
ulit_router = APIRouter()
|
||||||
|
|
||||||
|
@ulit_router.get("/search_time", tags=["search times"])
|
||||||
|
async def get_search_time(request: Request):
|
||||||
|
redis = request.app.state.redis
|
||||||
|
|
||||||
|
key = f"search_time"
|
||||||
|
|
||||||
|
count = await redis.get(key)
|
||||||
|
if not count:
|
||||||
|
await redis.set(key, value=0)
|
||||||
|
count = 0
|
||||||
|
print(count, type(count))
|
||||||
|
return {
|
||||||
|
"count": int(count),
|
||||||
|
}
|
||||||
|
|
@ -5,8 +5,8 @@ from pydantic import BaseModel, field_validator, model_validator
|
||||||
|
|
||||||
class TransRequest(BaseModel):
|
class TransRequest(BaseModel):
|
||||||
query: str
|
query: str
|
||||||
from_lang: Literal['auto', 'fr', 'jp', 'zh'] = 'auto'
|
from_lang: Literal['auto', 'fr', 'jp', 'zh', 'en'] = 'auto'
|
||||||
to_lang: Literal['fr', 'jp', 'zh'] = 'zh'
|
to_lang: Literal['fr', 'jp', 'zh', 'en'] = 'zh'
|
||||||
|
|
||||||
@field_validator('from_lang', 'to_lang')
|
@field_validator('from_lang', 'to_lang')
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
3
main.py
3
main.py
|
|
@ -15,6 +15,7 @@ from app.api.redis_test import redis_test_router
|
||||||
from app.api.search_dict.routes import dict_search
|
from app.api.search_dict.routes import dict_search
|
||||||
from app.api.translator import translator_router
|
from app.api.translator import translator_router
|
||||||
from app.api.user.routes import users_router
|
from app.api.user.routes import users_router
|
||||||
|
from app.api.util_api.routes import ulit_router
|
||||||
from app.api.word_comment.routes import word_comment_router
|
from app.api.word_comment.routes import word_comment_router
|
||||||
from app.core.redis import init_redis, close_redis
|
from app.core.redis import init_redis, close_redis
|
||||||
from app.utils.phone_encrypt import PhoneEncrypt
|
from app.utils.phone_encrypt import PhoneEncrypt
|
||||||
|
|
@ -67,5 +68,7 @@ app.include_router(pron_test_router, tags=["Pron Test API"], prefix="/test/pron"
|
||||||
|
|
||||||
app.include_router(article_router, tags=["Article API"])
|
app.include_router(article_router, tags=["Article API"])
|
||||||
|
|
||||||
|
app.include_router(ulit_router, tags=["Util Functions API"])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
|
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue