Skip to content

Commit

Permalink
feat: add the i18n middleware for the server
Browse files Browse the repository at this point in the history
  • Loading branch information
xingwanying committed Nov 15, 2024
1 parent 22bf140 commit 005546b
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 42 deletions.
57 changes: 36 additions & 21 deletions server/agent/tools/bot_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

g = Github()


@tool
async def create_bot(
repo_name: str,
Expand All @@ -25,20 +26,23 @@ async def create_bot(
"""
res = await bot_builder(uid, repo_name, starters, hello_message)
if not res:
return JSONResponse(content={"success": False, "errorMessage": "仓库不存在,生成失败"})
return JSONResponse(

Check warning on line 29 in server/agent/tools/bot_builder.py

View check run for this annotation

Codecov / codecov/patch

server/agent/tools/bot_builder.py#L29

Added line #L29 was not covered by tests
content={"success": False, "errorMessage": "Failed to create bot."}
)
return res.json()


@tool
def edit_bot(
id: str,
uid: str,
avatar: Optional[str] = None,
name: Optional[str] = None,
description : Optional[str] = None,
prompt: Optional[str] = None,
starters: Optional[list[str]] = None,
hello_message: Optional[str] = None
):
id: str,
uid: str,
avatar: Optional[str] = None,
name: Optional[str] = None,
description: Optional[str] = None,
prompt: Optional[str] = None,
starters: Optional[list[str]] = None,
hello_message: Optional[str] = None,
):
"""
Modify Bot Configuration based on the given parameters.
Expand All @@ -54,30 +58,41 @@ def edit_bot(
try:
# Step1: Get the bot object
supabase = get_client()
bot = supabase.table("bots").select("*").eq("id", id).eq("uid", uid).execute().data[0]
bot = (
supabase.table("bots")

Check warning on line 62 in server/agent/tools/bot_builder.py

View check run for this annotation

Codecov / codecov/patch

server/agent/tools/bot_builder.py#L62

Added line #L62 was not covered by tests
.select("*")
.eq("id", id)
.eq("uid", uid)
.execute()
.data[0]
)
if not bot:
raise ValueError(f"Bot with ID {id} not found.")

# Step2: Update the bot data
bot_data = {
"name": name if name else bot["name"],
"name": name if name else bot["name"],
"description": description if description else bot["description"],
"avatar": avatar if avatar else bot["avatar"],
"prompt": prompt if prompt else bot["prompt"],
"uid": bot["uid"],
"uid": bot["uid"],

Check warning on line 78 in server/agent/tools/bot_builder.py

View check run for this annotation

Codecov / codecov/patch

server/agent/tools/bot_builder.py#L78

Added line #L78 was not covered by tests
"label": "Assistant",
"starters": starters if isinstance(starters, list) and starters else bot["starters"],
"starters": (

Check warning on line 80 in server/agent/tools/bot_builder.py

View check run for this annotation

Codecov / codecov/patch

server/agent/tools/bot_builder.py#L80

Added line #L80 was not covered by tests
starters if isinstance(starters, list) and starters else bot["starters"]
),
"public": bot["public"],
"hello_message": hello_message if hello_message else bot["hello_message"]
"hello_message": hello_message if hello_message else bot["hello_message"],
}



# Step3: Save the changes to the database
response = supabase.table("bots").update(bot_data).eq("id", id).eq("uid", uid).execute()
response = (
supabase.table("bots")
.update(bot_data)
.eq("id", id)
.eq("uid", uid)
.execute()
)
return response.json()
except Exception as e:
print(f"An error occurred: {e}")
return e



18 changes: 3 additions & 15 deletions server/bot/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,12 @@ async def bot_info_generator(
"prompt": prompt,
"uid": uid,
"label": "Assistant",
"starters": (
starters
if starters
else [
f"介绍一下 {repo.name} 这个项目",
f"查看 {repo_name} 的贡献指南",
"我该怎样快速上手",
]
),
"starters": starters,
"public": False,
"hello_message": (
hello_message
if hello_message
else "我是你专属的答疑机器人,你可以问我关于当前项目的任何问题~"
),
"hello_message": hello_message,
"repo_name": repo_name,
"llm": "openai",
"token_id": ""
"token_id": "",
}

return bot_data
Expand Down
19 changes: 17 additions & 2 deletions server/bot/router.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import datetime
from fastapi import APIRouter, Depends, status, Query, Path
from fastapi import APIRouter, Request, Depends, status, Query, Path
from fastapi.responses import JSONResponse
from github import Github, Auth
from auth.get_user_info import get_user, get_user_id
Expand Down Expand Up @@ -134,11 +134,26 @@ async def create_bot(

@router.post("/config/generator", status_code=200)
async def bot_generator(
request: Request,
bot_data: BotCreateRequest,
user_id: Annotated[str | None, Depends(get_user_id)] = None,
lang: str = Query("en", description="Language of the bot"),

Check warning on line 140 in server/bot/router.py

View check run for this annotation

Codecov / codecov/patch

server/bot/router.py#L140

Added line #L140 was not covered by tests
):
default_starters = [
request.state.i18n.get_text("starter0", lang),

Check warning on line 143 in server/bot/router.py

View check run for this annotation

Codecov / codecov/patch

server/bot/router.py#L142-L143

Added lines #L142 - L143 were not covered by tests
request.state.i18n.get_text("starter1", lang),
request.state.i18n.get_text("starter2", lang),
]
default_hello_message = request.state.i18n.get_text("hello_message", lang)
print(bot_data.starters)
starters = bot_data.starters if bot_data.starters else default_starters
hello_message = (
bot_data.hello_message if bot_data.hello_message else default_hello_message

Check warning on line 151 in server/bot/router.py

View check run for this annotation

Codecov / codecov/patch

server/bot/router.py#L149-L151

Added lines #L149 - L151 were not covered by tests
)
try:
res = await bot_info_generator(user_id, **bot_data.model_dump())
res = await bot_info_generator(
user_id, bot_data.repo_name, starters, hello_message
)
if not res:
return JSONResponse(
content={
Expand Down
6 changes: 6 additions & 0 deletions server/i18n/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"starter0": "Introduce the project",
"starter1": "Review the contribution guidelines",
"starter2": "How can I quickly get started?",
"hello_message": "I'm your dedicated Q&A bot. Feel free to ask me anything about the current project~"
}
6 changes: 6 additions & 0 deletions server/i18n/ja.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"starter0": "このプロジェクトを紹介します",
"starter1": "コントリビューションガイドラインを確認する",
"starter2": "どうやって素早く始められますか?",
"hello_message": "私はあなた専用のQ&Aボットです。現在のプロジェクトについて何でも聞いてくださいね~"
}
6 changes: 6 additions & 0 deletions server/i18n/ko.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"starter0": "이 프로젝트를 소개합니다",
"starter1": "기여 가이드라인 보기",
"starter2": "어떻게 빠르게 시작할 수 있나요?",
"hello_message": "저는 여러분의 전용 Q&A 봇입니다. 현재 프로젝트에 대해 무엇이든 물어보세요~"
}
49 changes: 49 additions & 0 deletions server/i18n/translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from typing import Dict
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
import json
from pathlib import Path


class I18nConfig:
def __init__(
self, default_language: str = "en", translations_dir: str = "translations"
):
self.default_language = default_language
self.translations_dir = Path(translations_dir)
self.translations: Dict[str, Dict] = {}
self._load_translations()

def _load_translations(self):
"""load translations from the translations directory"""
if not self.translations_dir.exists():
raise FileNotFoundError(
f"Translations directory {self.translations_dir} not found"
)

for lang_file in self.translations_dir.glob("*.json"):
lang_code = lang_file.stem
with open(lang_file, "r", encoding="utf-8") as f:
self.translations[lang_code] = json.load(f)

def get_text(self, key: str, lang: str) -> str:
if lang not in self.translations:
lang = self.default_language
return self.translations[lang].get(key, key)


class I18nMiddleware(BaseHTTPMiddleware):
def __init__(self, app: FastAPI, i18n_config: I18nConfig):
super().__init__(app)
self.i18n_config = i18n_config

async def dispatch(self, request: Request, call_next):
lang = request.query_params.get(
"lang", self.i18n_config.default_language
) or request.query_params.get("lang", self.i18n_config.default_language)

request.state.i18n = self.i18n_config
request.state.lang = lang

response = await call_next(request)
return response
6 changes: 6 additions & 0 deletions server/i18n/zh-CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"starter0": "介绍一下这个项目",
"starter1": "查看贡献指南",
"starter2": "我该怎样快速上手",
"hello_message": "我是你专属的答疑机器人,你可以问我关于当前项目的任何问题~"
}
6 changes: 6 additions & 0 deletions server/i18n/zh-TW.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"starter0": "Introduce the project",
"starter1": "Review the contribution guidelines",
"starter2": "How can I quickly get started?",
"hello_message": "I'm your dedicated Q&A bot. Feel free to ask me anything about the current project~"
}
11 changes: 7 additions & 4 deletions server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from starlette.middleware.sessions import SessionMiddleware
from fastapi.middleware.cors import CORSMiddleware
from auth.cors_middleware import AuthCORSMiddleWare
from i18n.translations import I18nConfig, I18nMiddleware

from auth.middleware import AuthMiddleWare
from petercat_utils import get_env_variable
Expand Down Expand Up @@ -36,12 +37,11 @@

app = FastAPI(title="Petercat Server", version="1.0", description="Petercat.ai APIs")

i18n_config = I18nConfig(default_language="en", translations_dir="i18n")

app.add_middleware(AuthMiddleWare)

app.add_middleware(
SessionMiddleware,
secret_key=session_secret_key
)
app.add_middleware(SessionMiddleware, secret_key=session_secret_key)

cors_origins = (
["*"] if cors_origins_whitelist is None else cors_origins_whitelist.split(",")
Expand All @@ -57,6 +57,8 @@

app.add_middleware(AuthCORSMiddleWare)

app.add_middleware(I18nMiddleware, i18n_config=i18n_config)

app.include_router(rag_router.router)
app.include_router(bot_router.router)
app.include_router(auth_router.router)
Expand All @@ -71,6 +73,7 @@
def home_page():
return RedirectResponse(url=WEB_URL)


@app.get("/api/health_checker")
def health_checker():
return {
Expand Down

0 comments on commit 005546b

Please sign in to comment.