From f87ec9e4972da63ca3efdf37ebf4ba8877df1b07 Mon Sep 17 00:00:00 2001 From: MichaelSel Date: Fri, 27 Oct 2023 16:20:50 -0400 Subject: [PATCH 1/5] Added utils to new branch --- examples/utils/main.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 examples/utils/main.py diff --git a/examples/utils/main.py b/examples/utils/main.py new file mode 100644 index 0000000..fd4b725 --- /dev/null +++ b/examples/utils/main.py @@ -0,0 +1,10 @@ +import requests +from bs4 import BeautifulSoup +from typing import List, Annotated + +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] \ No newline at end of file From 524bc355c9501ee28e6008ca973eea81401c5faa Mon Sep 17 00:00:00 2001 From: MichaelSel Date: Fri, 27 Oct 2023 16:22:02 -0400 Subject: [PATCH 2/5] Added "Only Food" ratings --- examples/only_food/main.py | 153 +++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 examples/only_food/main.py diff --git a/examples/only_food/main.py b/examples/only_food/main.py new file mode 100644 index 0000000..8ef44d2 --- /dev/null +++ b/examples/only_food/main.py @@ -0,0 +1,153 @@ +import os +from typing import List, Annotated +import openai +from dotenv import load_dotenv +from pydantic import Field + +from examples.utils.main import get_yelp_reviews + +from monkey import Monkey + +load_dotenv() +openai.api_key = os.getenv("OPENAI_API_KEY") + +good_everything = [ + "This restaurant is an absolute gem! From the moment we walked in, we were impressed. The food was out of this " + "world – every dish was a burst of flavor and innovation. The service was impeccable, with attentive staff who " + "made us feel like royalty. The atmosphere was cozy and inviting, and the location was perfect, right in the " + "heart of the city. We'll be returning soon, no doubt about it!", + "What an extraordinary dining experience! This restaurant has it all. The food was a masterpiece, with each dish " + "carefully crafted and bursting with flavor. The service was outstanding; the staff were knowledgeable and " + "courteous. The atmosphere was elegant and romantic, setting the perfect mood. And the location couldn't be " + "better, making it a convenient choice for any occasion. A true culinary haven!", + "This restaurant is a culinary paradise! The food here is a work of art, with flavors that danced on my taste " + "buds. The service was impeccable, with a staff that made sure every need was met. The atmosphere was elegant yet " + "comfortable, and the location was ideal – easy to access. Whether it's a special occasion or a casual dinner, " + "this place exceeds expectations on all fronts.", + "If you're a food lover, this restaurant is a must-visit. The food here is top-notch, with a creative and diverse " + "menu that caters to all tastes. The service is exceptional, with attentive and friendly staff who truly care " + "about your dining experience. The atmosphere is warm and inviting, and the location is centrally located for " + "easy access. I can't recommend this place enough!", + "This restaurant is the epitome of a perfect dining experience. The food is a revelation, with dishes that are " + "both visually stunning and incredibly delicious. The service is unparalleled, with a staff that goes above and " + "beyond to ensure your satisfaction. The atmosphere is cozy and intimate, setting the stage for memorable meals. " + "And the location is just right – easy to find. I can't praise this place enough; it's a culinary delight!" +] + +good_food_bad_service = [ + "I visited this restaurant with high hopes for their food, and I must say, it did not disappoint. The dishes were " + "absolutely delicious, and the flavors were spot on. However, that's where the positives end. The service was " + "abysmal, with slow and inattentive waitstaff, and it seemed like they were more interested in chatting among " + "themselves than taking care of the customers. The atmosphere was lackluster, with uncomfortable seating and a " + "noisy environment. And let's not even get started on the location; it's in the middle of nowhere, making it a " + "hassle to get to. Great food, but not worth the trouble.", + "I have mixed feelings about this place. The food is fantastic; there's no denying that. But everything else is a " + "letdown. The service is unbelievably slow, and the servers seem disinterested in providing even the most basic " + "customer service. The atmosphere is dull and uninspiring, and the location is in the middle of an industrial " + "park – definitely not the kind of place you'd expect to find a good restaurant. If you're a true foodie who can " + "overlook everything else, the dishes might be worth the trek, but I wouldn't recommend it for a special night out.", + "I had high hopes for this restaurant due to the raving reviews about their food, and it did not disappoint in " + "that department. The dishes were indeed superb. However, everything else was a letdown. The service was " + "incredibly slow, and the staff seemed more interested in ignoring us than attending to our needs. The atmosphere " + "was sterile and uninspiring, and the location in a remote, industrial area is far from ideal. If you're a " + "die-hard foodie and can tolerate terrible service, a dismal atmosphere, and a terrible location, this might be " + "the place for you.", + "I have a love-hate relationship with this restaurant. The food is mind-blowingly good; I can't deny that. " + "However, the service is painfully slow, and the servers act like they'd rather be anywhere else but here. The " + "atmosphere is uninspiring, with no effort put into decor or ambiance. And don't even get me started on the " + "location; it's in a desolate part of town that's inconvenient to reach. If you're only here for the food, " + "then it might be worth the visit, but be prepared for terrible service, a lackluster atmosphere, and a terrible " + "location." + "I had heard so much about this restaurant's culinary delights, so I decided to give it a try. The food was, " + "without a doubt, exceptional, and I couldn't fault it in any way. However, the service was shockingly slow and " + "inattentive, making the dining experience less enjoyable. The atmosphere was bland and uninspiring, " + "and the location is in a remote area that feels like a trek. If you're willing to put up with terrible service, " + "a lackluster atmosphere, and a lousy location for the sake of excellent food, then this place is for you." + ] + +bad_everything = [ + "Where do I even begin with this restaurant? It's a complete disaster on all fronts. The food was inedible – I've " + "had better microwave dinners. The service was a joke; it took an eternity to get our orders, and the staff " + "seemed utterly disinterested. The atmosphere was depressing, with dim lighting and outdated decor that " + "transported me back to the '70s. And let's not even talk about the location – it's in the middle of nowhere. " + "Avoid this place at all costs.", + "I cannot express enough how terrible this restaurant is. The food was not just bad; it was revolting. I wouldn't " + "serve it to my worst enemy. The service was equally abysmal; the staff were rude, and it felt like they resented " + "having customers. The atmosphere was gloomy, and the furniture was falling apart. As for the location, " + "it's a hidden gem in the world of awful dining spots. Save your money and your sanity; don't ever set foot in " + "this place.", + "This restaurant is a disaster in every way imaginable. The food was disgusting; I couldn't even finish a single " + "bite. The service was a nightmare; the waitstaff seemed to have no idea what they were doing, and they were " + "incredibly slow. The atmosphere was dismal, with a strange smell in the air, and the decor was straight out of a " + "horror movie. The location is the cherry on top – it's in a sketchy part of town that I wouldn't recommend " + "anyone venture into. Stay far, far away from this place.", + "I wouldn't wish this restaurant on my worst enemy. The food was a culinary catastrophe; I've never tasted " + "anything so terrible. The service was non-existent; it took forever to even get a menu, and the waitstaff seemed " + "to be on another planet. The atmosphere was gloomy and depressing, and the location was in a dodgy area that " + "left me feeling unsafe. If you value your taste buds, your time, your mood, and your safety, stay far away from " + "this restaurant.", + "I made a grave mistake by dining at this wretched establishment. The food was inedible, and it left me " + "questioning the culinary skills of the chef. The service was horrendous; the waitstaff were clueless and " + "apathetic. The atmosphere was dismal, with peeling wallpaper and flickering lights that added to the overall " + "misery. And the location? Well, it's in the sketchiest part of town. Save yourself the agony and avoid this " + "restaurant like the plague."] + +bad_food_good_service = [ + "I had high hopes for this restaurant after hearing raving reviews about its atmosphere, service, and location. " + "The ambiance was indeed delightful, with a charming decor and cozy lighting. The service was impeccable, " + "with attentive and friendly staff. The location was perfect, right in the heart of the city. But the one crucial " + "aspect, the food, was a major disappointment. It was bland and uninspiring, a stark contrast to the rest of the " + "experience. I wish the menu lived up to the rest of the restaurant's offerings.", + "This restaurant has all the right ingredients for a perfect dining experience, except for the most important one " + "– the food. The atmosphere was exquisite, with a chic and cozy interior that set the mood perfectly. The service " + "was top-notch, with knowledgeable and attentive staff. The location was convenient, with easy access. But the " + "food, oh, the food was a letdown. It lacked flavor, creativity, and passion. If only the culinary aspect matched " + "the rest of the restaurant, it would be a dining paradise.", + "It pains me to give this restaurant a less than stellar review, but I must be honest. The atmosphere was " + "enchanting, the service was flawless, and the location was ideal – all of these aspects were beyond reproach. " + "However, the food was a colossal letdown. It lacked the depth of flavors and creativity I was hoping for. It " + "felt like the chef was just going through the motions. If only the culinary team could match the excellence of " + "the rest of the establishment.", + "This restaurant is a true paradox. The atmosphere was charming, the service was exemplary, and the location was " + "convenient – all of these were fantastic. But, and it's a big \"but,\" the food was a significant " + "disappointment. It lacked the taste and innovation I expected. It was as if the culinary team forgot the most " + "crucial aspect of dining. I truly wish the kitchen could measure up to the excellence of the rest of the " + "experience.", + "I wanted to love this restaurant; I really did. The atmosphere was enchanting, the service was exceptional, " + "and the location was perfect – all signs pointed to an outstanding dining experience. Alas, the food fell flat. " + "It was mediocre at best, lacking the complexity and flavor that I had anticipated. It's a shame that the " + "culinary aspect didn't match the excellence of the restaurant's other attributes." + ] + + + + + +@Monkey.patch +def rate_food(reviews: List[str]) -> Annotated[int, Field(ge=1, le=5)]: + """ + Taking into account only remarks made specifically about the food + and disregarding anything pertaining to atmosphere, location, service, etc. What would the rating be from 1 to 5? + """ + + +@Monkey.align +def test_food_rating(): + """We can test the function as normal using Pytest or Unittest""" + +if __name__ == '__main__': + # rating = rate_food(good_everything) + # print(f"When the EVERYTHING was positive the rating is {rating} out of 5") + # + # rating = rate_food(bad_everything) + # print(f"When the EVERYTHING was negative the rating is {rating} out of 5") + # + # rating = rate_food(good_food_bad_service) + # print(f"When the food is good and service is bad the rating is {rating} out of 5") + # + # rating = rate_food(bad_food_good_service) + # print(f"When the food is bad and service is good the rating is {rating} out of 5") + url = "https://www.yelp.com/biz/no-thai-ann-arbor" + reviews = get_yelp_reviews(url) + rating = rate_food(reviews) + print(f"The food (only) rating for {url} is {rating} out of 5") \ No newline at end of file From d0e0c30ef1dfeff4532902df43f2c539964d3528 Mon Sep 17 00:00:00 2001 From: MichaelSel Date: Fri, 27 Oct 2023 16:22:47 -0400 Subject: [PATCH 3/5] Added food recs --- examples/best_dishes/main.py | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 examples/best_dishes/main.py diff --git a/examples/best_dishes/main.py b/examples/best_dishes/main.py new file mode 100644 index 0000000..c16747f --- /dev/null +++ b/examples/best_dishes/main.py @@ -0,0 +1,55 @@ +import os +from typing import List, Annotated +import openai +from dotenv import load_dotenv +from pydantic import Field + +from examples.utils.main import get_yelp_reviews +from monkey import Monkey + +load_dotenv() +openai.api_key = os.getenv("OPENAI_API_KEY") + +reviews = [ + "I had the Grilled Salmon, and it was fantastic, definitely recommended!", + "The Lobster Bisque was decent but not outstanding.", + "I couldn't resist trying the Tiramisu, and it was a sweet surprise.", + "The Spaghetti Carbonara is a definite must-try on the menu.", + "The Beef Tenderloin is consistently good, a safe choice.", + "Shrimp Scampi – a bit too heavy on the garlic, not my cup of tea.", + "I paired a Chardonnay with the Duck Confit, an exquisite combination.", + "The Beet Salad is a colorful and refreshing option.", + "Branzino was recommended by the staff, and I wasn't disappointed.", + "Save room for the Chocolate Lava Cake, it's worth every calorie.", + "The Chicken Parmesan is a standout, the best in town.", + "Ratatouille – a flavorful vegetarian choice, quite impressive.", + "Ribeye Steak – always a winner here, highly recommended.", + "The Onion Soup Gratinee was cheesy and flavorful, a great starter.", + "Try the Miso-Glazed Cod – a unique, delicious dish.", + "The Burrata Caprese was fresh and flavorful, definitely recommended.", + "The Prime Rib is a crowd-pleaser and rightfully so.", + "The Creme Brulee was a sweet ending to a fantastic meal.", + "Indulge in the New York Cheesecake; it's a delightful treat.", + "The Seafood Paella is a must-avoid; it's lacking in flavor and overpriced.", +] + + +@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_food_rating(): + """We can test the function as normal using Pytest or Unittest""" + + +if __name__ == '__main__': + recommended = recommended_dishes(reviews) + + url = "https://www.yelp.com/biz/no-thai-ann-arbor" + reviews = get_yelp_reviews(url) + dishes = recommended_dishes(reviews) + print(f"Based on the reviews, the recommended dishes for {url} are {dishes}") From 67e5a89a678e8e95f3f1300aa5231cb3c0f30dc0 Mon Sep 17 00:00:00 2001 From: MichaelSel Date: Fri, 27 Oct 2023 17:33:25 -0400 Subject: [PATCH 4/5] POC Food review ratings --- .idea/misc.xml | 7 +- .idea/monkeyFunctions.iml | 2 +- apps/app.py | 10 ++ apps/controllers/food_controller.py | 12 +++ apps/routers/__init__.py | 2 + apps/routers/food_router.py | 26 +++++ apps/services/food_service.py | 67 ++++++++++++ examples/best_dishes/main.py | 55 ---------- examples/only_food/main.py | 153 ---------------------------- examples/utils/main.py | 10 -- 10 files changed, 124 insertions(+), 220 deletions(-) create mode 100644 apps/controllers/food_controller.py create mode 100644 apps/routers/food_router.py create mode 100644 apps/services/food_service.py delete mode 100644 examples/best_dishes/main.py delete mode 100644 examples/only_food/main.py delete mode 100644 examples/utils/main.py 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..eb04827 --- /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) -> dict[str, 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] diff --git a/examples/best_dishes/main.py b/examples/best_dishes/main.py deleted file mode 100644 index c16747f..0000000 --- a/examples/best_dishes/main.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -from typing import List, Annotated -import openai -from dotenv import load_dotenv -from pydantic import Field - -from examples.utils.main import get_yelp_reviews -from monkey import Monkey - -load_dotenv() -openai.api_key = os.getenv("OPENAI_API_KEY") - -reviews = [ - "I had the Grilled Salmon, and it was fantastic, definitely recommended!", - "The Lobster Bisque was decent but not outstanding.", - "I couldn't resist trying the Tiramisu, and it was a sweet surprise.", - "The Spaghetti Carbonara is a definite must-try on the menu.", - "The Beef Tenderloin is consistently good, a safe choice.", - "Shrimp Scampi – a bit too heavy on the garlic, not my cup of tea.", - "I paired a Chardonnay with the Duck Confit, an exquisite combination.", - "The Beet Salad is a colorful and refreshing option.", - "Branzino was recommended by the staff, and I wasn't disappointed.", - "Save room for the Chocolate Lava Cake, it's worth every calorie.", - "The Chicken Parmesan is a standout, the best in town.", - "Ratatouille – a flavorful vegetarian choice, quite impressive.", - "Ribeye Steak – always a winner here, highly recommended.", - "The Onion Soup Gratinee was cheesy and flavorful, a great starter.", - "Try the Miso-Glazed Cod – a unique, delicious dish.", - "The Burrata Caprese was fresh and flavorful, definitely recommended.", - "The Prime Rib is a crowd-pleaser and rightfully so.", - "The Creme Brulee was a sweet ending to a fantastic meal.", - "Indulge in the New York Cheesecake; it's a delightful treat.", - "The Seafood Paella is a must-avoid; it's lacking in flavor and overpriced.", -] - - -@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_food_rating(): - """We can test the function as normal using Pytest or Unittest""" - - -if __name__ == '__main__': - recommended = recommended_dishes(reviews) - - url = "https://www.yelp.com/biz/no-thai-ann-arbor" - reviews = get_yelp_reviews(url) - dishes = recommended_dishes(reviews) - print(f"Based on the reviews, the recommended dishes for {url} are {dishes}") diff --git a/examples/only_food/main.py b/examples/only_food/main.py deleted file mode 100644 index 8ef44d2..0000000 --- a/examples/only_food/main.py +++ /dev/null @@ -1,153 +0,0 @@ -import os -from typing import List, Annotated -import openai -from dotenv import load_dotenv -from pydantic import Field - -from examples.utils.main import get_yelp_reviews - -from monkey import Monkey - -load_dotenv() -openai.api_key = os.getenv("OPENAI_API_KEY") - -good_everything = [ - "This restaurant is an absolute gem! From the moment we walked in, we were impressed. The food was out of this " - "world – every dish was a burst of flavor and innovation. The service was impeccable, with attentive staff who " - "made us feel like royalty. The atmosphere was cozy and inviting, and the location was perfect, right in the " - "heart of the city. We'll be returning soon, no doubt about it!", - "What an extraordinary dining experience! This restaurant has it all. The food was a masterpiece, with each dish " - "carefully crafted and bursting with flavor. The service was outstanding; the staff were knowledgeable and " - "courteous. The atmosphere was elegant and romantic, setting the perfect mood. And the location couldn't be " - "better, making it a convenient choice for any occasion. A true culinary haven!", - "This restaurant is a culinary paradise! The food here is a work of art, with flavors that danced on my taste " - "buds. The service was impeccable, with a staff that made sure every need was met. The atmosphere was elegant yet " - "comfortable, and the location was ideal – easy to access. Whether it's a special occasion or a casual dinner, " - "this place exceeds expectations on all fronts.", - "If you're a food lover, this restaurant is a must-visit. The food here is top-notch, with a creative and diverse " - "menu that caters to all tastes. The service is exceptional, with attentive and friendly staff who truly care " - "about your dining experience. The atmosphere is warm and inviting, and the location is centrally located for " - "easy access. I can't recommend this place enough!", - "This restaurant is the epitome of a perfect dining experience. The food is a revelation, with dishes that are " - "both visually stunning and incredibly delicious. The service is unparalleled, with a staff that goes above and " - "beyond to ensure your satisfaction. The atmosphere is cozy and intimate, setting the stage for memorable meals. " - "And the location is just right – easy to find. I can't praise this place enough; it's a culinary delight!" -] - -good_food_bad_service = [ - "I visited this restaurant with high hopes for their food, and I must say, it did not disappoint. The dishes were " - "absolutely delicious, and the flavors were spot on. However, that's where the positives end. The service was " - "abysmal, with slow and inattentive waitstaff, and it seemed like they were more interested in chatting among " - "themselves than taking care of the customers. The atmosphere was lackluster, with uncomfortable seating and a " - "noisy environment. And let's not even get started on the location; it's in the middle of nowhere, making it a " - "hassle to get to. Great food, but not worth the trouble.", - "I have mixed feelings about this place. The food is fantastic; there's no denying that. But everything else is a " - "letdown. The service is unbelievably slow, and the servers seem disinterested in providing even the most basic " - "customer service. The atmosphere is dull and uninspiring, and the location is in the middle of an industrial " - "park – definitely not the kind of place you'd expect to find a good restaurant. If you're a true foodie who can " - "overlook everything else, the dishes might be worth the trek, but I wouldn't recommend it for a special night out.", - "I had high hopes for this restaurant due to the raving reviews about their food, and it did not disappoint in " - "that department. The dishes were indeed superb. However, everything else was a letdown. The service was " - "incredibly slow, and the staff seemed more interested in ignoring us than attending to our needs. The atmosphere " - "was sterile and uninspiring, and the location in a remote, industrial area is far from ideal. If you're a " - "die-hard foodie and can tolerate terrible service, a dismal atmosphere, and a terrible location, this might be " - "the place for you.", - "I have a love-hate relationship with this restaurant. The food is mind-blowingly good; I can't deny that. " - "However, the service is painfully slow, and the servers act like they'd rather be anywhere else but here. The " - "atmosphere is uninspiring, with no effort put into decor or ambiance. And don't even get me started on the " - "location; it's in a desolate part of town that's inconvenient to reach. If you're only here for the food, " - "then it might be worth the visit, but be prepared for terrible service, a lackluster atmosphere, and a terrible " - "location." - "I had heard so much about this restaurant's culinary delights, so I decided to give it a try. The food was, " - "without a doubt, exceptional, and I couldn't fault it in any way. However, the service was shockingly slow and " - "inattentive, making the dining experience less enjoyable. The atmosphere was bland and uninspiring, " - "and the location is in a remote area that feels like a trek. If you're willing to put up with terrible service, " - "a lackluster atmosphere, and a lousy location for the sake of excellent food, then this place is for you." - ] - -bad_everything = [ - "Where do I even begin with this restaurant? It's a complete disaster on all fronts. The food was inedible – I've " - "had better microwave dinners. The service was a joke; it took an eternity to get our orders, and the staff " - "seemed utterly disinterested. The atmosphere was depressing, with dim lighting and outdated decor that " - "transported me back to the '70s. And let's not even talk about the location – it's in the middle of nowhere. " - "Avoid this place at all costs.", - "I cannot express enough how terrible this restaurant is. The food was not just bad; it was revolting. I wouldn't " - "serve it to my worst enemy. The service was equally abysmal; the staff were rude, and it felt like they resented " - "having customers. The atmosphere was gloomy, and the furniture was falling apart. As for the location, " - "it's a hidden gem in the world of awful dining spots. Save your money and your sanity; don't ever set foot in " - "this place.", - "This restaurant is a disaster in every way imaginable. The food was disgusting; I couldn't even finish a single " - "bite. The service was a nightmare; the waitstaff seemed to have no idea what they were doing, and they were " - "incredibly slow. The atmosphere was dismal, with a strange smell in the air, and the decor was straight out of a " - "horror movie. The location is the cherry on top – it's in a sketchy part of town that I wouldn't recommend " - "anyone venture into. Stay far, far away from this place.", - "I wouldn't wish this restaurant on my worst enemy. The food was a culinary catastrophe; I've never tasted " - "anything so terrible. The service was non-existent; it took forever to even get a menu, and the waitstaff seemed " - "to be on another planet. The atmosphere was gloomy and depressing, and the location was in a dodgy area that " - "left me feeling unsafe. If you value your taste buds, your time, your mood, and your safety, stay far away from " - "this restaurant.", - "I made a grave mistake by dining at this wretched establishment. The food was inedible, and it left me " - "questioning the culinary skills of the chef. The service was horrendous; the waitstaff were clueless and " - "apathetic. The atmosphere was dismal, with peeling wallpaper and flickering lights that added to the overall " - "misery. And the location? Well, it's in the sketchiest part of town. Save yourself the agony and avoid this " - "restaurant like the plague."] - -bad_food_good_service = [ - "I had high hopes for this restaurant after hearing raving reviews about its atmosphere, service, and location. " - "The ambiance was indeed delightful, with a charming decor and cozy lighting. The service was impeccable, " - "with attentive and friendly staff. The location was perfect, right in the heart of the city. But the one crucial " - "aspect, the food, was a major disappointment. It was bland and uninspiring, a stark contrast to the rest of the " - "experience. I wish the menu lived up to the rest of the restaurant's offerings.", - "This restaurant has all the right ingredients for a perfect dining experience, except for the most important one " - "– the food. The atmosphere was exquisite, with a chic and cozy interior that set the mood perfectly. The service " - "was top-notch, with knowledgeable and attentive staff. The location was convenient, with easy access. But the " - "food, oh, the food was a letdown. It lacked flavor, creativity, and passion. If only the culinary aspect matched " - "the rest of the restaurant, it would be a dining paradise.", - "It pains me to give this restaurant a less than stellar review, but I must be honest. The atmosphere was " - "enchanting, the service was flawless, and the location was ideal – all of these aspects were beyond reproach. " - "However, the food was a colossal letdown. It lacked the depth of flavors and creativity I was hoping for. It " - "felt like the chef was just going through the motions. If only the culinary team could match the excellence of " - "the rest of the establishment.", - "This restaurant is a true paradox. The atmosphere was charming, the service was exemplary, and the location was " - "convenient – all of these were fantastic. But, and it's a big \"but,\" the food was a significant " - "disappointment. It lacked the taste and innovation I expected. It was as if the culinary team forgot the most " - "crucial aspect of dining. I truly wish the kitchen could measure up to the excellence of the rest of the " - "experience.", - "I wanted to love this restaurant; I really did. The atmosphere was enchanting, the service was exceptional, " - "and the location was perfect – all signs pointed to an outstanding dining experience. Alas, the food fell flat. " - "It was mediocre at best, lacking the complexity and flavor that I had anticipated. It's a shame that the " - "culinary aspect didn't match the excellence of the restaurant's other attributes." - ] - - - - - -@Monkey.patch -def rate_food(reviews: List[str]) -> Annotated[int, Field(ge=1, le=5)]: - """ - Taking into account only remarks made specifically about the food - and disregarding anything pertaining to atmosphere, location, service, etc. What would the rating be from 1 to 5? - """ - - -@Monkey.align -def test_food_rating(): - """We can test the function as normal using Pytest or Unittest""" - -if __name__ == '__main__': - # rating = rate_food(good_everything) - # print(f"When the EVERYTHING was positive the rating is {rating} out of 5") - # - # rating = rate_food(bad_everything) - # print(f"When the EVERYTHING was negative the rating is {rating} out of 5") - # - # rating = rate_food(good_food_bad_service) - # print(f"When the food is good and service is bad the rating is {rating} out of 5") - # - # rating = rate_food(bad_food_good_service) - # print(f"When the food is bad and service is good the rating is {rating} out of 5") - url = "https://www.yelp.com/biz/no-thai-ann-arbor" - reviews = get_yelp_reviews(url) - rating = rate_food(reviews) - print(f"The food (only) rating for {url} is {rating} out of 5") \ No newline at end of file diff --git a/examples/utils/main.py b/examples/utils/main.py deleted file mode 100644 index fd4b725..0000000 --- a/examples/utils/main.py +++ /dev/null @@ -1,10 +0,0 @@ -import requests -from bs4 import BeautifulSoup -from typing import List, Annotated - -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] \ No newline at end of file From f494a0f4024317c2846c406fb883e1f7f0a45f10 Mon Sep 17 00:00:00 2001 From: MichaelSel Date: Fri, 27 Oct 2023 17:39:37 -0400 Subject: [PATCH 5/5] POC Food review ratings --- apps/routers/food_router.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/routers/food_router.py b/apps/routers/food_router.py index eb04827..b8f964b 100644 --- a/apps/routers/food_router.py +++ b/apps/routers/food_router.py @@ -15,7 +15,7 @@ @router.get("/") -async def analyze_reviews(url: str) -> dict[str, str]: +async def analyze_reviews(url: str): reviews = get_yelp_reviews(url) ratings = get_ratings(reviews) best_dishes = get_best_dishes(reviews)