Skip to content

Commit

Permalink
feat: optimize refrigerator
Browse files Browse the repository at this point in the history
  • Loading branch information
sspzoa committed Oct 11, 2024
1 parent 0ba6010 commit b5b9712
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 9 deletions.
2 changes: 2 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from app.routes import ping, root
from app.routes.recipe import recipe, ingredient_info, cooking_step
from app.routes.refrigerator import ingredient_detect, refrigerator
from app.routes.refrigerator import rearrange_refrigerator

app = FastAPI(
title="Deening API",
Expand Down Expand Up @@ -35,3 +36,4 @@
app.include_router(ingredient_detect.router, dependencies=[Depends(verify_token)])

app.include_router(refrigerator.router, dependencies=[Depends(verify_token)])
app.include_router(rearrange_refrigerator.router, dependencies=[Depends(verify_token)])
Empty file.
2 changes: 1 addition & 1 deletion app/routes/recipe/cooking_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
router = APIRouter()


@router.post("/recipe/cooking_step", tags=["Recipe"], response_model=CookingStepResponse,
@router.post("/recipe/cooking-step", tags=["Recipe"], response_model=CookingStepResponse,
responses={400: {"model": ErrorResponse}, 404: {"model": ErrorResponse}})
async def get_cooking_step_info(request: CookingStepRequest):
"""
Expand Down
6 changes: 3 additions & 3 deletions app/routes/refrigerator/ingredient_detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
router = APIRouter()


@router.post("/refrigerator/ingredient_detect", tags=["Refrigerator"],
@router.post("/refrigerator/ingredient-detect", tags=["Refrigerator"],
response_model=IngredientDetectResponse,
responses={400: {"model": ErrorResponse}, 404: {"model": NoIngredientsFoundResponse}})
async def ingredient_detect(image: UploadFile = File(...)):
Expand Down Expand Up @@ -41,8 +41,8 @@ async def ingredient_detect(image: UploadFile = File(...)):
{{
"ingredients": []
}}
주의: 반드시 다른 텍스트 없이 유효한 JSON 형식으로만 응답해주세요.
주의: 반드시 다른 텍스트나 코드블록 없이 유효한 JSON 형식으로만 응답해주세요.
"""

# OpenAI API 호출
Expand Down
108 changes: 108 additions & 0 deletions app/routes/refrigerator/rearrange_refrigerator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import json

from fastapi import APIRouter, HTTPException

from app.config import client as openai_client
from app.database import refrigerator_collection
from app.models.error_models import ErrorResponse
from app.models.refrigerator.refrigerator_models import GetIngredientsResponse, Refrigerator, IngredientCategory, \
Ingredient

router = APIRouter()


@router.post("/refrigerator/rearrange-refrigerator", tags=["Refrigerator"], response_model=GetIngredientsResponse,
responses={400: {"model": ErrorResponse}})
async def rearrange_refrigerator():
try:
# 현재 냉장고 내용물 가져오기
ingredients = await refrigerator_collection.find().to_list(length=None)

# ChatGPT에 보낼 메시지 준비
rearrange_prompt = f"""냉장고 내용물을 최적화하고 재정렬해주세요. 다음 구조를 따르는 JSON 형식으로 응답해주세요:
{{
"categories": [
{{
"category": "카테고리명",
"ingredients": [
{{
"name": "재료명",
"amount": 수량,
"unit": "단위"
}}
],
}}
],
}}
현재 냉장고 내용물:
{json.dumps([{
"name": ing["name"],
"amount": ing["amount"],
"unit": ing["unit"],
"category": ing["category"]
} for ing in ingredients], ensure_ascii=False)}
주의사항:
1. 카테고리를 최적화하고, 필요한 경우 새로운 카테고리를 만들거나 기존 카테고리를 병합하세요.
6. 반드시 다른 텍스트나 코드블록 없이 유효한 JSON 형식으로만 응답해주세요.
"""

# ChatGPT로부터 제안 받기
response = openai_client.chat.completions.create(
model="chatgpt-4o-latest",
messages=[
{"role": "system",
"content": "You are an expert in food storage and refrigerator organization. Provide detailed and practical advice for optimizing refrigerator contents."},
{"role": "user", "content": rearrange_prompt}
]
)

# ChatGPT 응답 파싱
response_content = response.choices[0].message.content.strip()
try:
optimized_data = json.loads(response_content)
except json.JSONDecodeError:
print(f"Failed to parse JSON. Raw response: {response_content}")
raise HTTPException(status_code=500, detail="Failed to parse optimization suggestion")

if 'categories' not in optimized_data:
raise HTTPException(status_code=500, detail="Invalid optimization suggestion format")

# 현재 냉장고 내용물 비우기
await refrigerator_collection.delete_many({})

# 최적화된 재료를 데이터베이스에 다시 삽입
for category in optimized_data['categories']:
for ingredient in category['ingredients']:
await refrigerator_collection.insert_one({
"name": ingredient['name'],
"amount": ingredient['amount'],
"unit": ingredient['unit'],
"category": category['category']
})

# 업데이트된 냉장고 내용물 가져오기
updated_ingredients = await refrigerator_collection.find().to_list(length=None)

# 응답 준비
categories = []
for category in optimized_data['categories']:
category_ingredients = [
Ingredient(id=str(ing['_id']), name=ing['name'], amount=ing['amount'], unit=ing['unit'],
category=ing['category'])
for ing in updated_ingredients if ing['category'] == category['category']
]
categories.append(IngredientCategory(
category=category['category'],
ingredients=category_ingredients,
))

refrigerator = Refrigerator(
categories=categories,
)
return GetIngredientsResponse(refrigerator=refrigerator)

except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
10 changes: 5 additions & 5 deletions app/routes/refrigerator/refrigerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@ async def get_ingredients():
response_model=AddIngredientResponse)
async def add_ingredients(request: AddIngredientRequest):
"""
냉장고에 여러 재료를 추가합니다. 이미 존재하는 재료의 경우 양을 더합니다.
냉장고에 여러 재료를 추가합니다. 이미 존재하는 재료의 경우 단위가 같을 때만 양을 더합니다.
"""
try:
for ingredient in request.ingredients:
# 기존 재료 찾기
existing_ingredient = await refrigerator_collection.find_one(
{"name": ingredient.name, "category": ingredient.category})
{"name": ingredient.name, "category": ingredient.category, "unit": ingredient.unit})

if existing_ingredient:
# 이미 존재하는 재료라면 양을 더함
# 이미 존재하는 재료이고 단위가 같다면 양을 더함
new_amount = existing_ingredient["amount"] + ingredient.amount
await refrigerator_collection.update_one(
{"name": ingredient.name, "category": ingredient.category},
{"_id": existing_ingredient["_id"]},
{"$set": {"amount": new_amount}}
)
else:
# 새로운 재료라면 추가
# 새로운 재료이거나 단위가 다르다면 새로 추가
await refrigerator_collection.insert_one(ingredient.dict())

return {"message": "재료가 성공적으로 추가되었습니다."}
Expand Down

0 comments on commit b5b9712

Please sign in to comment.