Skip to content

Commit

Permalink
Merge pull request #53 from studio-recoding/feat/email
Browse files Browse the repository at this point in the history
[feat] 이메일 api 완성
  • Loading branch information
uommou authored May 3, 2024
2 parents 8b034a5 + 5db4888 commit 047368f
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 5 deletions.
13 changes: 9 additions & 4 deletions app/database/chroma_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ async def db_daily_schedule(user_data: RecommendationMainRequestDTO):
month = int(schedule_date.split("-")[1])
date = int(schedule_date.split("-")[2])
persona = user_data.user_persona or "hard working"
results = schedules.query(
query_texts=[persona],
n_results=5,
results = schedules.get(
where={"$and":
[
{"member": {"$eq": int(member)}},
Expand All @@ -84,7 +82,14 @@ async def db_daily_schedule(user_data: RecommendationMainRequestDTO):
}
# where_document={"$contains":"search_string"} # optional filter
)
return results['documents']

# documents와 datetime_start 추출
results = [(doc, meta['datetime_start']) for doc, meta in zip(results['documents'], results['metadatas'])]

# 결과 출력
print(results)

return results

# 태그 생성용 스케쥴 반환 - 카테고리에 따라
async def db_monthly_tag_schedule(user_data: ReportTagsRequestDTO):
Expand Down
6 changes: 6 additions & 0 deletions app/dto/db_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ class ReportTagsRequestDTO(BaseModel):
schedule_datetime_start: str
schedule_datetime_end: str

class EmailRequestDTO(BaseModel):
member_id: int
user_persona: str
schedule_datetime_start: str
schedule_datetime_end: str

6 changes: 5 additions & 1 deletion app/dto/openai_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ class TagDescription(BaseModel):
desc: str

class TagsResponse(BaseModel):
tagList: List[TagDescription]
tagList: List[TagDescription]

class EmailResponse(BaseModel):
text: str
image: str
3 changes: 3 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
from app.routers import report
app.include_router(report.router)

from app.routers import email
app.include_router(email.router)

# description: prevent CORS error
origins = [
"*",
Expand Down
34 changes: 34 additions & 0 deletions app/prompt/email_prompt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class Template:
daily_email_template = """
{persona}
Construct an email to conclude the user's day. The email should:
Acknowledge the user's efforts and achievements throughout the day.
Offer encouragement and suggestions for preparing for tomorrow’s agenda.
Use this information to create a personalized, thoughtful email that reinforces positive feedback and provides motivational insights for the upcoming day.
You should construct the email based solely on the schedule provided, without assuming or extrapolating additional details.
YOU MUST USE {output_language} TO RESPOND. The length of the email should not exceed 2 paragraphs. Do not call user's name.
Today's schedule for the user1:
2021-07-19T09:00:00: Zoom meeting attendance
2021-07-19T11:00:00: Review of project report
2021-07-19T13:00:00: Business lunch
2021-07-19T15:00:00: Team meeting
2021-07-19T18:00:00: Workshop preparation
Email:
Today's activities show you managed a full and productive schedule.
In the morning, your active participation in the Zoom meeting was impressive. Such engagement is crucial for fostering collaborative success.
During your project report review, your attention to detail stood out. This meticulousness will significantly contribute to the project's success.
The business lunch was an important time for building relationships. Such networking will assist in future tasks.
In the afternoon, you effectively led the team meeting, playing a vital role in enhancing team cooperation.
Lastly, thank you for your effort in preparing for the workshop. This preparation will facilitate a smooth running of tomorrow's session.
Thank you for your hard work today. Rest well and recharge for another fruitful day tomorrow.
Today's schedule for the user2:
{schedule}
Email:
"""
5 changes: 5 additions & 0 deletions app/prompt/openai_config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ MODEL_NAME = gpt-4
[NESS_TAGS]
TEMPERATURE = 0.5
MAX_TOKENS = 2048
MODEL_NAME = gpt-4

[NESS_EMAIL]
TEMPERATURE = 0.5
MAX_TOKENS = 2048
MODEL_NAME = gpt-4
80 changes: 80 additions & 0 deletions app/routers/email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import configparser
import os

from openai import OpenAI
from dotenv import load_dotenv
from fastapi import APIRouter, Depends, status, HTTPException
from langchain_community.chat_models import ChatOpenAI
from langchain_core.prompts import PromptTemplate

from app.dto.db_dto import EmailRequestDTO
from app.dto.openai_dto import EmailResponse
from app.prompt import email_prompt, persona_prompt
import app.database.chroma_db as vectordb

router = APIRouter(
prefix="/email",
tags=["email"]
)

# description: load env variables from .env file
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

# description: load config variables from openai_config.ini file
CONFIG_FILE_PATH = "app/prompt/openai_config.ini"
config = configparser.ConfigParser()
config.read(CONFIG_FILE_PATH)

# description: 유저의 하루 스케줄을 기반으로 이메일 내용을 작성한다.
@router.post("/daily", status_code=status.HTTP_200_OK)
async def get_daily_email(user_data: EmailRequestDTO) -> EmailResponse:
try:
# 모델
config_recommendation = config['NESS_EMAIL']

chat_model = ChatOpenAI(temperature=config_recommendation['TEMPERATURE'], # 창의성 (0.0 ~ 2.0)
max_tokens=config_recommendation['MAX_TOKENS'], # 최대 토큰수
model_name=config_recommendation['MODEL_NAME'], # 모델명
openai_api_key=OPENAI_API_KEY # API 키
)

# vectordb에서 유저의 정보를 가져온다.
schedule = await vectordb.db_daily_schedule(user_data)

print(schedule)

# 템플릿
email_template = email_prompt.Template.daily_email_template

# 페르소나
persona = user_data.user_persona
user_persona_prompt = persona_prompt.Template.from_persona(persona)

# 이메일 내용
prompt = PromptTemplate.from_template(email_template)
email_text = chat_model.predict(
prompt.format(persona=user_persona_prompt, output_language="Korean", schedule=schedule))
print(email_text)

# \n을 <br>로 변환
email_text = email_text.replace("\n", "<br>")
print(email_text)

# 이메일에 들어갈 텍스트
client = OpenAI()

response = client.images.generate(
model="dall-e-3",
prompt="Relaxing image, Calm and Quiet illustration style",
size="1792x1024",
quality="standard",
n=1,
)

image_url = response.data[0].url

return EmailResponse(text=email_text, image=image_url)

except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
1 change: 1 addition & 0 deletions app/routers/recommendation.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
config = configparser.ConfigParser()
config.read(CONFIG_FILE_PATH)

# 유저의 하루 스케줄을 기반으로 한 줄 추천을 생성한다.
@router.post("/main", status_code=status.HTTP_200_OK)
async def get_recommendation(user_data: RecommendationMainRequestDTO) -> ChatResponse:
try:
Expand Down

0 comments on commit 047368f

Please sign in to comment.