diff --git a/.idea/misc.xml b/.idea/misc.xml index 3c51a0d..d0c282b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,9 @@ - + + + \ No newline at end of file diff --git a/.idea/monkeyFunctions.iml b/.idea/monkeyFunctions.iml index eb9179d..d0976f6 100644 --- a/.idea/monkeyFunctions.iml +++ b/.idea/monkeyFunctions.iml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/apps/app.py b/apps/app.py index 23948a0..95e3211 100644 --- a/apps/app.py +++ b/apps/app.py @@ -21,6 +21,16 @@ title="monkey-patch-apps", ) +origins = ["*"] +app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + app.include_router(router) # origins = [CLIENT_URL] diff --git a/apps/controllers/food_controller.py b/apps/controllers/food_controller.py new file mode 100644 index 0000000..dc98b97 --- /dev/null +++ b/apps/controllers/food_controller.py @@ -0,0 +1,12 @@ +from typing import List, Dict +from services.food_service import specific_ratings, recommended_dishes + + +def get_ratings(reviews: List[str]) -> Dict[str, int]: + rating = specific_ratings(reviews) + return rating.model_dump() + + +def get_best_dishes(reviews: List[str]) -> List[str]: + recommended = recommended_dishes(reviews) + return recommended diff --git a/apps/routers/__init__.py b/apps/routers/__init__.py index bdbfe01..5f71f29 100644 --- a/apps/routers/__init__.py +++ b/apps/routers/__init__.py @@ -4,8 +4,10 @@ # local from routers import ( youtube_router as youtube, + food_router as food, ) router = APIRouter() router.include_router(youtube.router) +router.include_router(food.router) diff --git a/apps/routers/food_router.py b/apps/routers/food_router.py new file mode 100644 index 0000000..b8f964b --- /dev/null +++ b/apps/routers/food_router.py @@ -0,0 +1,26 @@ +# standard / third party +import json + +from fastapi import APIRouter + +# local +from controllers.food_controller import get_best_dishes, get_ratings + +from services.food_service import get_yelp_reviews + +router = APIRouter( + prefix="/food", + tags=["food"], +) + + +@router.get("/") +async def analyze_reviews(url: str): + reviews = get_yelp_reviews(url) + ratings = get_ratings(reviews) + best_dishes = get_best_dishes(reviews) + return { + "message": "success", + "ratings": ratings, + "best_dishes": best_dishes, + } diff --git a/apps/services/food_service.py b/apps/services/food_service.py new file mode 100644 index 0000000..7a35251 --- /dev/null +++ b/apps/services/food_service.py @@ -0,0 +1,67 @@ +from pydantic import Field, BaseModel +from typing import List, Annotated, Dict +from monkey import Monkey +import openai +import requests +from bs4 import BeautifulSoup + +# from dotenv import load_dotenv +import os + + +# load_dotenv() +openai.api_key = os.getenv("OPENAI_API_KEY") + + +class RatingModel(BaseModel): + food: int = Annotated[ + Field(..., ge=1, le=10), "The food-only rating based on the provided reviews" + ] + service: int = Annotated[ + Field(..., ge=1, le=10), "The service-only rating based on the provided reviews" + ] + atmosphere: int = Annotated[ + Field(..., ge=1, le=10), + "The atmosphere-only rating based on the provided reviews", + ] + location: int = Annotated[ + Field(..., ge=1, le=10), + "The location-only rating based on the provided reviews", + ] + + +@Monkey.patch +def specific_ratings(reviews: List[str]) -> RatingModel: + """ + based on the reviews, separately rate (from 1 to 10) the following aspects: + - food + - service + - atmosphere + - location + - overall + """ + + +@Monkey.align +def test_specific_ratings(): + """We can test the function as normal using Pytest or Unittest""" + + +@Monkey.patch +def recommended_dishes(reviews: List[str]) -> List[str]: + """ + List the top 5 (or fewer) best dishes based on the given reviews + """ + + +@Monkey.align +def test_recommended_dishes(): + """We can test the function as normal using Pytest or Unittest""" + + +def get_yelp_reviews(yelp_url: str) -> List[str]: + response = requests.get(yelp_url) + soup = BeautifulSoup(response.text, "html.parser") + # get all "p" tags with class beginning with comment__ + reviews = soup.find_all("p", class_=lambda x: x and x.startswith("comment__")) + return [review.text for review in reviews]