Spaces:
Sleeping
Sleeping
| # from itertools import islice | |
| # import itertools | |
| # import json | |
| # import re | |
| # from groq import Groq | |
| # from config import direcindirecprompt | |
| # from utils import groq_calls,write_to_file, get_file_data, get_mongo_collection | |
| # from sklearn.feature_extraction.text import TfidfVectorizer | |
| # from sklearn.metrics.pairwise import cosine_similarity | |
| # import numpy as np | |
| # from datetime import datetime | |
| # ''' | |
| # The architecture is like this | |
| # ''' | |
| # collection = get_mongo_collection() | |
| # def main(): | |
| # # user_journal = get_file_data("journal.txt") | |
| # # example = get_file_data("example.json") | |
| # # prompt= direcindirecprompt | |
| # direcindirecgroq_response = groq_calls(direcindirecprompt) | |
| # # parsed_json = json.loads(direcindirecgroq_response) | |
| # # print(parsed_json) | |
| # # write_to_file("overall_specific_problempair.json",direcindirecgroq_response) | |
| # guideprompt = f''' | |
| # So, I am giving a set of direct-indirect problem pair, here it is: {direcindirecgroq_response} | |
| # Now, these are some of the issues the user is facing in his daily life. Assume that you're a very skilled psychologist and help solve the problems faced | |
| # by the users in their daily life by recommending them a set of guidelines of what they could follow or practice in their daily life to keep themselves calm | |
| # These guidelines should not be very long, some short recommendations which can be followed even when the person is seated on his chair in office | |
| # or any where else. Basically the guidelines should be accessible/doable any time. | |
| # Give 1-2 guidelines for each of the problem that the user is facing as in the problem pair procided to you | |
| # Here are some examples of how guidelines could look like | |
| # -Take short breaks for deep breathing, walk in the present, and journal three things you're grateful for daily to shift perspective. | |
| # -Dedicate even 10 minutes to a hobby or enjoyable activity to recharge. | |
| # -Reduce news consumption and screen time, especially before bed, to avoid overwhelm. | |
| # Above are some examples only, but remember whatever you suggest should be relevant to the problems the user is facing | |
| # Final output should be in JSON format only | |
| # final output should start and end like this | |
| # {{ | |
| # problem1:["Set dedicated focus blocks (e.g., 90‑min) and log only the block end to satisfy reporting.","Use a private tracker to note progress, then share a concise daily summary with the manager."] | |
| # }} | |
| # ''' | |
| # guidegroq_response = groq_calls(guideprompt) | |
| # # with open("test.json", "w") as f: | |
| # # f.write(guidegroq_response) | |
| # with open("structured_output_updated.json","r") as f: | |
| # task_dataset = json.load(f) | |
| # result = {} | |
| # # task_dataset = test | |
| # yogabranches = list(task_dataset["Yoga"]["branches"].keys()) | |
| # for branch in yogabranches: | |
| # if branch == "Asana": | |
| # postures = list(task_dataset["Yoga"]["branches"][branch].keys()) | |
| # # print(postures) | |
| # result[f"{branch}s"] = {} | |
| # for posture in postures: | |
| # lst = list(task_dataset["Yoga"]["branches"][branch][posture].keys()) | |
| # for pose in lst: | |
| # # # poses.append(task_dataset["Yoga"]["branches"][branch][posture][pose]) | |
| # # print(task_dataset["Yoga"]["branches"][branch][posture][pose]) | |
| # sliced_items = list(task_dataset["Yoga"]["branches"][branch][posture][pose].values())[:2] | |
| # result[f"{branch}s"][pose] = list(itertools.chain.from_iterable(sliced_items)) | |
| # else: | |
| # postures = list(task_dataset["Yoga"]["branches"][branch].keys()) | |
| # # print(postures) | |
| # result[f"{branch}s"] = {} | |
| # for posture in postures: | |
| # lst = list(task_dataset["Yoga"]["branches"][branch][posture].values())[:2] | |
| # result[f"{branch}s"][posture] = list(itertools.chain.from_iterable(lst)) | |
| # # with open("overall_specific_problempair.json","r",encoding = "utf-8") as f: | |
| # # user_problem = json.load(f) | |
| # user_problem = json.loads(direcindirecgroq_response) | |
| # cosineprompt = f''' | |
| # So i am giving you the iverall problems that are being faced by the user. Here it is: {user_problem.keys()} | |
| # Now I want you to generate a 2-3 line summary/description for each of the problems. It shuold indicate what effect it has on the user's body and mind. | |
| # So basically I want to perform a cosine similarity between this description that you give and a task dataset that has multiple tasks and they have their own descriptions of what they are able to cure | |
| # So, If you write a good description for each overall problem, then I can match it with the task dataset descriptions to find the best matching tasks for the user. | |
| # Here are examples of what is present in the task dataset descriptions: | |
| # "Nadi Shodhana (Alternate Nostril Breathing)": {{ | |
| # "Stress": [ | |
| # "Balances left/right brain hemispheres for nervous system equilibrium", | |
| # "Reduces cortisol by 27% through symmetrical breathing patterns", | |
| # "Creates instant mental clarity during decision fatigue" | |
| # ], | |
| # "Emotions": [ | |
| # "Harmonizes emotional extremes by balancing solar/moon energies", | |
| # "Resets emotional reactivity through prefrontal cortex activation", | |
| # "Integrates logical and intuitive aspects of awareness" | |
| # ], | |
| # }} | |
| # "Bakasana (Crow Pose)": {{ | |
| # "Focus": [ | |
| # "Develops laser-like concentration to prevent falling", | |
| # "Trains mind-body coordination in challenging position", | |
| # "Builds mental discipline through fear management" | |
| # ], | |
| # "Strength": [ | |
| # "Develops core and wrist strength simultaneously", | |
| # "Tones abdominal muscles through active engagement", | |
| # "Builds functional arm strength for daily activities" | |
| # ], | |
| # }} | |
| # So, you see there is a certain way the descriptions are written for the task and hence you need to generate the descriptions for the overall problems in a similar way so that cosine similarity precisely extracts onyl those tasks which are highly relevant to the overall problems being faced by the user. | |
| # Also, follow the following format strictly: | |
| # {{ | |
| # "Overall Problem 1": ["Description"] | |
| # "Overall Problem 2": ["Description"] | |
| # }} | |
| # Remember to output not anything else what is said, also don't use very complicated words. You can use some technical words but keep it simple and precise otherwise if those words are present in the task dataset then cosine similaity will be very less. | |
| # also, replace "Overall Problem 1" with the problem name for which description is being written | |
| # ''' | |
| # cosinegroq_response = groq_calls(cosineprompt) | |
| # # with open("test.json","w") as f: | |
| # # f.write(cosinegroq_response) | |
| # parsed_json = json.loads(cosinegroq_response) | |
| # # write_to_file("overall_problemdesc.json",cosinegroq_response) | |
| # user_problem = parsed_json | |
| # user_problem_text = " ".join(sum(user_problem.values(), [])) | |
| # tasks = {} | |
| # for branch in result.keys(): | |
| # for pose in result[branch].keys(): | |
| # documents = [] | |
| # # print(result[branch][pose]) | |
| # desc = ", ".join(result[branch][pose]) | |
| # # print(desc) | |
| # documents.append(desc) | |
| # documents.append(user_problem_text) | |
| # # documents[0] ='Micromanagement scrutiny, raising heart rate and restlessness. leading to tight muscles and frequent headaches. Language barriers and frustration, making communication difficult. Shallow breathing and lowering confidence and increasing social anxiety. Social exclusion triggers. It reduces heart rate variability and raises cortisol, leaving the body stressed. Burnout produces persistent fatigue, headaches, and muscle aches. Focus and decision‑making suffer, while sleep quality drops and inflammation markers rise. Discrimination induces emotional distress and self‑doubt, making the mind hypervigilant and anxious. stressing the body.' | |
| # vectorizer = TfidfVectorizer(stop_words='english') | |
| # tfidf_matrix = vectorizer.fit_transform(documents) | |
| # similarities = cosine_similarity(tfidf_matrix[-1], tfidf_matrix[:-1]).flatten() | |
| # tasks[f"{branch}({pose})"]= similarities | |
| # # print(f"{branch} --> ", f"{pose} --> ", similarities) | |
| # print(documents) | |
| # sorted_tasks = dict(sorted(tasks.items(), key=lambda item: item[1], reverse=True)) | |
| # print(list(sorted_tasks.items())[:5]) | |
| # username = "sameer" #in production extract the username | |
| # if collection is not None: | |
| # chat_document = { | |
| # "user_id": username, | |
| # "timestamp": datetime.now(), | |
| # "problemdesc": direcindirecgroq_response, | |
| # "guidelines":guidegroq_response, | |
| # "tasks": list(sorted_tasks.keys())[:5] | |
| # } | |
| # try: | |
| # collection.insert_one(chat_document) | |
| # print("Saved to DB") | |
| # except Exception as e: | |
| # print(f"Failed to save to DB: {e}") | |
| # if __name__ == "__main__": | |
| # main() | |
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel | |
| from typing import Optional, List, Dict, Any | |
| from itertools import islice | |
| import itertools | |
| import json | |
| import re | |
| from datetime import datetime | |
| # ML and Math imports | |
| from sklearn.feature_extraction.text import TfidfVectorizer | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| import numpy as np | |
| # Custom modules (assuming these exist in your project structure) | |
| from groq import Groq | |
| # from config import direcindirecprompt | |
| from utils import groq_calls, write_to_file, get_file_data, get_mongo_collection | |
| import uvicorn | |
| # Initialize FastAPI app | |
| app = FastAPI(title="Journal Task Planner") | |
| # Initialize DB connection globally (or within dependency) | |
| try: | |
| collection = get_mongo_collection() | |
| except Exception as e: | |
| print(f"Warning: Database connection failed on startup: {e}") | |
| collection = None | |
| # --- Pydantic Models for Request/Response --- | |
| class AnalysisRequest(BaseModel): | |
| user_id: str | |
| username: str # Default as per your code | |
| user_journal: str | |
| # Add other fields here if you need to pass user_journal dynamically later | |
| class AnalysisResponse(BaseModel): | |
| status: str | |
| user_id: str | |
| username: str | |
| guidelines: Dict[str, Any] | |
| recommended_tasks: List[str] | |
| timestamp: datetime | |
| async def cron_test(): | |
| return "Hello Cron Tester" | |
| def generate_analysis(request: AnalysisRequest): | |
| example = get_file_data("example.json") | |
| direcindirecprompt = f''' | |
| I'll be giving you a journal entry written by a user. Your task is to extract out problems being faced by the user in the following format: | |
| {{ | |
| "Overall Problem 1": ["Specific reason1 - reason why it was created", "Specific reason2 - reason why it was created"], | |
| "Overall Problem 2": ["Specific reason1 - reason why it was created"], | |
| }} | |
| I'll give you an example how this overall - specific problem pair looks like. Here you'll see that the heading (single word is the overall problem), then we have the reasons why it was created | |
| here is the overall - specific problem pair: {example} | |
| Obviusly a single overall problem can have multiple specific reasons why it was created. Put it in the exact format as shown above. | |
| Also, multiple overall problems can share a common specific reason why it was created. In that case, just repeat the specific reason under all of them. | |
| Here is the user text you have to analyse: {request.user_journal} | |
| Output strictly in the format given to you no extra symbols or words or anything | |
| ''' | |
| # 1. Direct/Indirect Problem Identification | |
| try: | |
| # Assuming direcindirecprompt is imported from config | |
| direcindirecgroq_response = groq_calls(direcindirecprompt) | |
| print(direcindirecgroq_response) | |
| # If the response acts as a JSON source, we try to parse it to ensure validity | |
| # parsed_check = json.loads(direcindirecgroq_response) | |
| except Exception as e: | |
| raise HTTPException(status_code=502, detail=f"Groq API Error (Problem Identification): {str(e)}") | |
| # 2. Guidelines Generation | |
| try: | |
| guideprompt = f''' | |
| So, I am giving a set of direct-indirect problem pair, here it is: {direcindirecgroq_response} | |
| Now, these are some of the issues the user is facing in his daily life. Assume that you're a very skilled psychologist and help solve the problems faced | |
| by the users in their daily life by recommending them a set of guidelines of what they could follow or practice in their daily life to keep themselves calm | |
| These guidelines should not be very long, some short recommendations which can be followed even when the person is seated on his chair in office | |
| or any where else. Basically the guidelines should be accessible/doable any time. | |
| Give 1-2 guidelines for each of the problem that the user is facing as in the problem pair procided to you | |
| Here are some examples of how guidelines could look like | |
| -Take short breaks for deep breathing, walk in the present, and journal three things you're grateful for daily to shift perspective. | |
| -Dedicate even 10 minutes to a hobby or enjoyable activity to recharge. | |
| -Reduce news consumption and screen time, especially before bed, to avoid overwhelm. | |
| Above are some examples only, but remember whatever you suggest should be relevant to the problems the user is facing | |
| Final output should be in JSON format only | |
| final output should start and end like this | |
| {{ | |
| "problem1": ["Set dedicated focus blocks...", "Use a private tracker..."] | |
| }} | |
| ''' | |
| guidegroq_response = groq_calls(guideprompt) | |
| print(guidegroq_response) | |
| except Exception as e: | |
| raise HTTPException(status_code=502, detail=f"Groq API Error (Guideline Generation): {str(e)}") | |
| # 3. Load Task Dataset | |
| try: | |
| with open("structured_output_updated.json", "r") as f: | |
| task_dataset = json.load(f) | |
| except FileNotFoundError: | |
| raise HTTPException(status_code=500, detail="Server Error: 'structured_output_updated.json' file not found.") | |
| except json.JSONDecodeError: | |
| raise HTTPException(status_code=500, detail="Server Error: Failed to decode task dataset JSON.") | |
| # 4. Process Yoga Branches (Business Logic) | |
| try: | |
| result = {} | |
| yogabranches = list(task_dataset["Yoga"]["branches"].keys()) | |
| for branch in yogabranches: | |
| if branch == "Asana": | |
| postures = list(task_dataset["Yoga"]["branches"][branch].keys()) | |
| result[f"{branch}s"] = {} | |
| for posture in postures: | |
| # Depending on structure, sometimes keys are poses | |
| lst = list(task_dataset["Yoga"]["branches"][branch][posture].keys()) | |
| for pose in lst: | |
| sliced_items = list(task_dataset["Yoga"]["branches"][branch][posture][pose].values())[:2] | |
| result[f"{branch}s"][pose] = list(itertools.chain.from_iterable(sliced_items)) | |
| else: | |
| postures = list(task_dataset["Yoga"]["branches"][branch].keys()) | |
| result[f"{branch}s"] = {} | |
| for posture in postures: | |
| lst = list(task_dataset["Yoga"]["branches"][branch][posture].values())[:2] | |
| result[f"{branch}s"][posture] = list(itertools.chain.from_iterable(lst)) | |
| except KeyError as e: | |
| raise HTTPException(status_code=500, detail=f"Data Processing Error: Key {str(e)} missing in dataset.") | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Data Processing Error: {str(e)}") | |
| # 5. Cosine Similarity Preparation | |
| try: | |
| # We parse the response from Step 1 to get keys for the next prompt | |
| user_problem_raw = json.loads(direcindirecgroq_response) | |
| cosineprompt = f''' | |
| So i am giving you the iverall problems that are being faced by the user. Here it is: {user_problem_raw.keys()} | |
| Now I want you to generate a 2-3 line summary/description for each of the problems. It shuold indicate what effect it has on the user's body and mind. | |
| So basically I want to perform a cosine similarity between this description that you give and a task dataset that has multiple tasks and they have their own descriptions of what they are able to cure | |
| So, If you write a good description for each overall problem, then I can match it with the task dataset descriptions to find the best matching tasks for the user. | |
| Here are examples of what is present in the task dataset descriptions: | |
| "Nadi Shodhana (Alternate Nostril Breathing)": {{ | |
| "Stress": [ | |
| "Balances left/right brain hemispheres for nervous system equilibrium", | |
| "Reduces cortisol by 27% through symmetrical breathing patterns", | |
| "Creates instant mental clarity during decision fatigue" | |
| ], | |
| "Emotions": [ | |
| "Harmonizes emotional extremes by balancing solar/moon energies", | |
| "Resets emotional reactivity through prefrontal cortex activation", | |
| "Integrates logical and intuitive aspects of awareness" | |
| ], | |
| }} | |
| "Bakasana (Crow Pose)": {{ | |
| "Focus": [ | |
| "Develops laser-like concentration to prevent falling", | |
| "Trains mind-body coordination in challenging position", | |
| "Builds mental discipline through fear management" | |
| ], | |
| "Strength": [ | |
| "Develops core and wrist strength simultaneously", | |
| "Tones abdominal muscles through active engagement", | |
| "Builds functional arm strength for daily activities" | |
| ], | |
| }} | |
| So, you see there is a certain way the descriptions are written for the task and hence you need to generate the descriptions for the overall problems in a similar way so that cosine similarity precisely extracts onyl those tasks which are highly relevant to the overall problems being faced by the user. | |
| Also, follow the following format strictly: | |
| {{ | |
| "Overall Problem 1": ["Description"] | |
| "Overall Problem 2": ["Description"] | |
| }} | |
| Remember to output not anything else what is said, also don't use very complicated words. You can use some technical words but keep it simple and precise otherwise if those words are present in the task dataset then cosine similaity will be very less. | |
| also, replace "Overall Problem 1" with the problem name for which description is being written | |
| ''' | |
| cosinegroq_response = groq_calls(cosineprompt) | |
| print(cosinegroq_response) | |
| parsed_cosine_json = json.loads(cosinegroq_response) | |
| user_problem = parsed_cosine_json | |
| user_problem_text = " ".join(sum(user_problem.values(), [])) | |
| except json.JSONDecodeError: | |
| raise HTTPException(status_code=500, detail="Failed to parse JSON from Groq response (Cosine Prompt).") | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Error preparing Cosine Similarity data: {str(e)}") | |
| # 6. Calculate Cosine Similarity | |
| try: | |
| tasks = {} | |
| for branch in result.keys(): | |
| for pose in result[branch].keys(): | |
| documents = [] | |
| desc = ", ".join(result[branch][pose]) | |
| documents.append(desc) | |
| documents.append(user_problem_text) | |
| vectorizer = TfidfVectorizer(stop_words='english') | |
| tfidf_matrix = vectorizer.fit_transform(documents) | |
| # Compare the last doc (user problem) with the first doc (task desc) | |
| similarities = cosine_similarity(tfidf_matrix[-1], tfidf_matrix[:-1]).flatten() | |
| tasks[f"{branch}({pose})"] = similarities[0] # Take the float value | |
| # Sort and take top 5 | |
| sorted_tasks = dict(sorted(tasks.items(), key=lambda item: item[1], reverse=True)) | |
| top_tasks = list(sorted_tasks.keys())[:5] | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Math/Vectorization Error: {str(e)}") | |
| # 7. Database Insertion | |
| chat_document = None | |
| try: | |
| # Try to parse guidelines string to JSON object for cleaner DB storage/Response | |
| try: | |
| guidelines_obj = json.loads(guidegroq_response) | |
| except: | |
| guidelines_obj = {"raw_text": guidegroq_response} | |
| chat_document = { | |
| "user_id": request.user_id, | |
| "username": request.username, | |
| "timestamp": datetime.now(), | |
| "problemdesc": direcindirecgroq_response, # Storing raw response string as per original code | |
| "guidelines": guidegroq_response, # Storing raw response string as per original code | |
| "tasks": top_tasks | |
| } | |
| if collection is not None: | |
| collection.insert_one(chat_document) | |
| print("Saved to DB") | |
| else: | |
| print("Skipped DB save (Collection not available)") | |
| except Exception as e: | |
| # We log the DB error but might not want to fail the whole request if the calculation succeeded | |
| print(f"Failed to save to DB: {e}") | |
| # Note: Depending on requirements, you might want to raise HTTPException here or just proceed. | |
| # 8. Return Response | |
| return AnalysisResponse( | |
| status="success", | |
| user_id=request.user_id, | |
| username=request.username, | |
| guidelines=guidelines_obj, | |
| recommended_tasks=top_tasks, | |
| timestamp=chat_document["timestamp"] if chat_document else datetime.now() | |
| ) | |
| if __name__ == "__main__": | |
| # Run the app with uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=8000) | |