SoumyaJ commited on
Commit
c875fdf
·
verified ·
1 Parent(s): 3dd42be

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -158
app.py CHANGED
@@ -1,158 +1,158 @@
1
- from tools import RetrievalTool
2
- from dotenv import load_dotenv
3
- from langchain_core.prompts import PromptTemplate
4
- from langchain_groq import ChatGroq
5
- from pydantic import BaseModel, Field
6
- from fastapi import FastAPI, HTTPException
7
- from fastapi.middleware.cors import CORSMiddleware
8
- from fastapi.responses import JSONResponse
9
- import pandas as pd
10
- import uvicorn
11
- import re
12
- import os
13
-
14
- load_dotenv()
15
-
16
- app = FastAPI()
17
-
18
- app.add_middleware(
19
- CORSMiddleware,
20
- allow_origins=["*"],
21
- allow_credentials=True,
22
- allow_methods=["*"],
23
- allow_headers=["*"],
24
- )
25
-
26
- os.environ["ASTRA_DB_API_ENDPOINT"] = os.getenv("ASTRA_DB_API_ENDPOINT")
27
- os.environ["ASTRA_DB_APPLICATION_TOKEN"] = os.getenv("ASTRA_DB_APPLICATION_TOKEN")
28
- os.environ["ASTRA_DB_NAMESPACE"] = os.getenv("ASTRA_DB_NAMESPACE")
29
- os.environ["HF_TOKEN"] = os.getenv("HF_TOKEN")
30
- os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY")
31
- os.environ["CALENDARIFIC_API_KEY"] = os.getenv("CALENDARIFIC_API_KEY")
32
-
33
- retrieval_tool = RetrievalTool()
34
-
35
- class ScheduleRecommendationModel(BaseModel):
36
- programme_schedule: str = Field(description="The entire list of recommended programs..")
37
- reasoning: str = Field(description="The reasoning behind the recommendation.")
38
-
39
- template = """
40
- You are a smart TV schedule assistant.
41
-
42
- Your job is to generate a clean, formatted program schedule for a specific day.
43
-
44
- Constraints:
45
- - Do NOT include any explanation, notes, or Markdown.
46
- - Do NOT repeat any program on the same day.
47
- - Format must be exactly: HH:MM - HH:MM : ProgramName
48
- - Use the provided channel start time as the beginning of the schedule.
49
- - Prime time is from 18:00 to 22:00 — prioritize the highest-rated programs here.
50
- - If the date is a holiday (e.g., Christmas), ensure 2 to 3 holiday-themed programs (based on keywords like "Christmas", "Santa", or "Carol" in the synopsis) are included in the schedule.
51
- - If it's a weekend, favor family-friendly or entertainment-heavy content.
52
- - If it's a weekday, prefer shorter or lighter content during the day and prioritize core genre in prime time.
53
- - Do not schedule past 23:59.
54
-
55
- Inputs:
56
- - Genre: {genre}
57
- - DayType: {day_type} # Either "weekday" or "weekend"
58
- - Holiday: {holiday_event} # Either "Christmas", "New year" or None
59
- - Start Time: {start_time}
60
- - Available Programs:
61
- {program_list}
62
-
63
- Now generate the full day schedule starting from {start_time} using the above constraints.
64
- """
65
- summary_template = """
66
- You are a smart TV reasoning summary assistant.
67
-
68
- Your task is to clearly explain the thought process behind a given TV schedule recommendation.
69
-
70
- The summary should help the user understand why specific programs were selected, why they appear at certain times, and how the genre, ratings, time of day, day type (weekday/weekend), and special events (e.g., holidays like Christmas) influenced the schedule.
71
-
72
- ✳️ Instructions:
73
-
74
- Do not add any information that is not already present in the reasoning.Do not hallucinate or make assumptions.
75
-
76
- The summary must reflect the actual reasoning provided by the model.
77
-
78
- Write in a natural, human-readable tone, suitable for a user reading a TV planner explanation.
79
-
80
- Keep it concise but detailed enough to convey scheduling logic (approx. 8-10 lines).
81
-
82
- Highlight how prime-time slots (18:00–22:00) were used for high-rated programs.
83
-
84
- If applicable, explain how holiday content or weekend scheduling influenced the selection.
85
- Use the reasoning provided to you and summarize it in a clear and concise manner.
86
- {reasoning}
87
- """
88
- prompt = PromptTemplate.from_template(template)
89
- summary_prompt = PromptTemplate.from_template(summary_template)
90
- llm = ChatGroq(model_name = "deepseek-r1-distill-llama-70b", api_key = os.environ["GROQ_API_KEY"])
91
- summary_llm = ChatGroq(model_name = "gemma2-9b-it", api_key = os.environ["GROQ_API_KEY"])
92
-
93
- chain = prompt | llm
94
- summary_chain = summary_prompt | summary_llm
95
-
96
- def get_dynamic_schedule(program_df:str, genre:str, start_time:str, day_type:str, holiday_event:str):
97
- try:
98
- response = chain.invoke({"program_list": program_df,
99
- "genre": genre,
100
- "day_type": day_type,
101
- "holiday_event": holiday_event,
102
- "start_time": start_time})
103
-
104
- text_data = response.content
105
- think_match = re.search(r'<think>(.*?)</think>', text_data, re.DOTALL)
106
- if think_match:
107
- reasoning = think_match.group(1).strip()
108
- reasoning_answer = summarize_reasoning(reasoning)
109
- final_answer = text_data.split("</think>")[-1].strip()
110
- return ScheduleRecommendationModel(programme_schedule=final_answer, reasoning=reasoning_answer)
111
-
112
- # if text_data and "</think>" in text_data:
113
- # result = re.split(r'</think>', text_data, maxsplit=1)[-1].strip()
114
- # return result
115
-
116
- return ScheduleRecommendationModel(programme_schedule=response, reasoning="Error while generating reasoning.")
117
-
118
- except Exception as e:
119
- return f"Error: {str(e)}"
120
-
121
- def get_weekday_or_weekend(date:str):
122
- try:
123
- schedule_date = pd.to_datetime(date)
124
- if schedule_date.weekday() < 5: # Monday to Friday
125
- return "weekday"
126
- else: # Saturday and Sunday
127
- return "weekend"
128
- except ValueError:
129
- raise ValueError("Invalid date format. Please use YYYY-MM-DD.")
130
-
131
- def get_schedule_recommendation(genre:str, date:str, start_time:str):
132
- program_list, holidayEvent = retrieval_tool.get_relevant_programmes(genre, date)
133
-
134
- day_of_week = get_weekday_or_weekend(date)
135
- schedule_recommendation = get_dynamic_schedule(program_list, genre, start_time, day_of_week, holidayEvent)
136
- print("Schedule Recommendation:", schedule_recommendation)
137
- return schedule_recommendation
138
-
139
-
140
- def summarize_reasoning(reasoning:str):
141
- if reasoning:
142
- response = summary_chain.invoke({"reasoning": reasoning})
143
- return response.content
144
- return "Error while generating reasoning."
145
-
146
- @app.post("/api/v1/getScheduleRecommendation/")
147
- async def extract_details(genre:str, date:str, start_time:str):
148
- try:
149
- return get_schedule_recommendation(genre, date, start_time)
150
- except HTTPException as e:
151
- return JSONResponse(status_code=500, content={"error": str(e)})
152
-
153
- if __name__ == "__main__":
154
- uvicorn.run(app, host="0.0.0.0", port=8000)
155
-
156
- # if __name__ == "__main__":
157
- # get_schedule_recommendation('comedy', '2023-12-25', '09:00')
158
-
 
1
+ from tools import RetrievalTool
2
+ from dotenv import load_dotenv
3
+ from langchain_core.prompts import PromptTemplate
4
+ from langchain_groq import ChatGroq
5
+ from pydantic import BaseModel, Field
6
+ from fastapi import FastAPI, HTTPException
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+ from fastapi.responses import JSONResponse
9
+ import pandas as pd
10
+ import uvicorn
11
+ import re
12
+ import os
13
+
14
+ load_dotenv()
15
+
16
+ app = FastAPI()
17
+
18
+ app.add_middleware(
19
+ CORSMiddleware,
20
+ allow_origins=["*"],
21
+ allow_credentials=True,
22
+ allow_methods=["*"],
23
+ allow_headers=["*"],
24
+ )
25
+
26
+ os.environ["ASTRA_DB_API_ENDPOINT"] = os.getenv("ASTRA_DB_API_ENDPOINT")
27
+ os.environ["ASTRA_DB_APPLICATION_TOKEN"] = os.getenv("ASTRA_DB_APPLICATION_TOKEN")
28
+ os.environ["ASTRA_DB_NAMESPACE"] = os.getenv("ASTRA_DB_NAMESPACE")
29
+ os.environ["HF_TOKEN"] = os.getenv("HF_TOKEN")
30
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY")
31
+ os.environ["CALENDARIFIC_API_KEY"] = os.getenv("CALENDARIFIC_API_KEY")
32
+
33
+ retrieval_tool = RetrievalTool()
34
+
35
+ class ScheduleRecommendationModel(BaseModel):
36
+ programme_schedule: str = Field(description="The entire list of recommended programs..")
37
+ reasoning: str = Field(description="The reasoning behind the recommendation.")
38
+
39
+ template = """
40
+ You are a smart TV schedule assistant.
41
+
42
+ Your job is to generate a clean, formatted program schedule for a specific day.
43
+
44
+ Constraints:
45
+ - Do NOT include any explanation, notes, or Markdown.
46
+ - Do NOT repeat any program on the same day.
47
+ - Format must be exactly: HH:MM - HH:MM : ProgramName
48
+ - Use the provided channel start time as the beginning of the schedule.
49
+ - Prime time is from 18:00 to 22:00 — prioritize the highest-rated programs here.
50
+ - If the date is a holiday (e.g., Christmas), ensure 2 to 3 holiday-themed programs (based on keywords like "Christmas", "Santa", or "Carol" in the synopsis) are included in the schedule.
51
+ - If it's a weekend, favor family-friendly or entertainment-heavy content.
52
+ - If it's a weekday, prefer shorter or lighter content during the day and prioritize core genre in prime time.
53
+ - Do not schedule past 23:59.
54
+
55
+ Inputs:
56
+ - Genre: {genre}
57
+ - DayType: {day_type} # Either "weekday" or "weekend"
58
+ - Holiday: {holiday_event} # Either "Christmas", "New year" or None
59
+ - Start Time: {start_time}
60
+ - Available Programs:
61
+ {program_list}
62
+
63
+ Now generate the full day schedule starting from {start_time} using the above constraints.
64
+ """
65
+ summary_template = """
66
+ You are a smart TV reasoning summary assistant.
67
+
68
+ Your task is to clearly explain the thought process behind a given TV schedule recommendation.
69
+
70
+ The summary should help the user understand why specific programs were selected, why they appear at certain times, and how the genre, ratings, time of day, day type (weekday/weekend), and special events (e.g., holidays like Christmas) influenced the schedule.
71
+
72
+ ✳️ Instructions:
73
+
74
+ Do not add any information that is not already present in the reasoning.Do not hallucinate or make assumptions.
75
+
76
+ The summary must reflect the actual reasoning provided by the model.
77
+
78
+ Write in a natural, human-readable tone, suitable for a user reading a TV planner explanation.
79
+
80
+ Keep it concise but detailed enough to convey scheduling logic (approx. 8-10 lines).
81
+
82
+ Highlight how prime-time slots (18:00–22:00) were used for high-rated programs.
83
+
84
+ If applicable, explain how holiday content or weekend scheduling influenced the selection.
85
+ Use the reasoning provided to you and summarize it in a clear and concise manner.
86
+ {reasoning}
87
+ """
88
+ prompt = PromptTemplate.from_template(template)
89
+ summary_prompt = PromptTemplate.from_template(summary_template)
90
+ llm = ChatGroq(model_name = "deepseek-r1-distill-llama-70b", api_key = os.environ["GROQ_API_KEY"])
91
+ summary_llm = ChatGroq(model_name = "gemma2-9b-it", api_key = os.environ["GROQ_API_KEY"])
92
+
93
+ chain = prompt | llm
94
+ summary_chain = summary_prompt | summary_llm
95
+
96
+ def get_dynamic_schedule(program_df:str, genre:str, start_time:str, day_type:str, holiday_event:str):
97
+ try:
98
+ response = chain.invoke({"program_list": program_df,
99
+ "genre": genre,
100
+ "day_type": day_type,
101
+ "holiday_event": holiday_event,
102
+ "start_time": start_time})
103
+
104
+ text_data = response.content
105
+ think_match = re.search(r'<think>(.*?)</think>', text_data, re.DOTALL)
106
+ if think_match:
107
+ reasoning = think_match.group(1).strip()
108
+ reasoning_answer = summarize_reasoning(reasoning)
109
+ final_answer = text_data.split("</think>")[-1].strip()
110
+ return ScheduleRecommendationModel(programme_schedule=final_answer, reasoning=reasoning_answer)
111
+
112
+ # if text_data and "</think>" in text_data:
113
+ # result = re.split(r'</think>', text_data, maxsplit=1)[-1].strip()
114
+ # return result
115
+
116
+ return ScheduleRecommendationModel(programme_schedule=response, reasoning="Error while generating reasoning.")
117
+
118
+ except Exception as e:
119
+ return f"Error: {str(e)}"
120
+
121
+ def get_weekday_or_weekend(date:str):
122
+ try:
123
+ schedule_date = pd.to_datetime(date)
124
+ if schedule_date.weekday() < 5: # Monday to Friday
125
+ return "weekday"
126
+ else: # Saturday and Sunday
127
+ return "weekend"
128
+ except ValueError:
129
+ raise ValueError("Invalid date format. Please use YYYY-MM-DD.")
130
+
131
+ def get_schedule_recommendation(genre:str, date:str, start_time:str):
132
+ program_list, holidayEvent = retrieval_tool.get_relevant_programmes(genre, date)
133
+
134
+ day_of_week = get_weekday_or_weekend(date)
135
+ schedule_recommendation = get_dynamic_schedule(program_list, genre, start_time, day_of_week, holidayEvent)
136
+ print("Schedule Recommendation:", schedule_recommendation)
137
+ return schedule_recommendation
138
+
139
+
140
+ def summarize_reasoning(reasoning:str):
141
+ if reasoning:
142
+ response = summary_chain.invoke({"reasoning": reasoning})
143
+ return response.content
144
+ return "Error while generating reasoning."
145
+
146
+ @app.get("/api/v1/getScheduleRecommendation/")
147
+ async def extract_details(genre:str, date:str, start_time:str):
148
+ try:
149
+ return get_schedule_recommendation(genre, date, start_time)
150
+ except HTTPException as e:
151
+ return JSONResponse(status_code=500, content={"error": str(e)})
152
+
153
+ if __name__ == "__main__":
154
+ uvicorn.run(app, host="0.0.0.0", port=8000)
155
+
156
+ # if __name__ == "__main__":
157
+ # get_schedule_recommendation('comedy', '2023-12-25', '09:00')
158
+