Download main.py from DOOM1812/DPR: direct link, hf CLI and curl.
- Browser
- Download file 5.86 kB
-
https://huggingface.co/spaces/DOOM1812/DPR/resolve/main/main.py
- Command line
-
hf download hf://spaces/DOOM1812/DPR/main.py
-
curl -L -o main.py https://huggingface.co/spaces/DOOM1812/DPR/resolve/main/main.py
5.86 kB
| import os | |
| import json | |
| from datetime import datetime, timedelta | |
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel | |
| from dotenv import load_dotenv | |
| from langchain_openai import ChatOpenAI | |
| from langchain_community.utilities import SQLDatabase | |
| from langchain_core.tools import Tool | |
| from langchain.agents import create_openai_tools_agent, AgentExecutor | |
| from langchain.prompts import ( | |
| PromptTemplate, | |
| SystemMessagePromptTemplate, | |
| HumanMessagePromptTemplate, | |
| MessagesPlaceholder, | |
| ChatPromptTemplate, | |
| ) | |
| import pytz | |
| import uvicorn | |
| # Load environment variables | |
| load_dotenv() | |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") | |
| if not OPENAI_API_KEY: | |
| raise ValueError("OPENAI_API_KEY is not set.") | |
| app = FastAPI() | |
| # Database connection | |
| db_instance = SQLDatabase.from_uri( | |
| "mssql+pyodbc://PMOlogbook_Usr:aPMO86#iaxh@103.239.89.100:21433/PMO360_DB?driver=ODBC Driver 17 for SQL Server", | |
| include_tables=["Logbook", "LogbookHistory", "User", "tbl_Sprint", "tblMs_Projects"] | |
| ) | |
| # Helper: get current week range | |
| def get_week_range(): | |
| today = datetime.now(pytz.timezone("Asia/Kolkata")) | |
| start = today - timedelta(days=today.weekday()) | |
| end = start + timedelta(days=6) | |
| return start.strftime("%Y-%m-%d"), end.strftime("%Y-%m-%d") | |
| # Helper: SQL Query Builder | |
| def build_sql(first_name: str, last_name: str = None, start_date: str = None, end_date: str = None) -> str: | |
| if not start_date or not end_date: | |
| start_date, end_date = get_week_range() | |
| name_filter = f"u.FirstName = '{first_name}'" | |
| if last_name: | |
| name_filter += f" AND u.LastName = '{last_name}'" | |
| return f""" | |
| SELECT | |
| COALESCE(u.FirstName + ' ' + u.LastName, 'Unknown') AS Name, | |
| lh.LogbookId, | |
| lh.CreatedDate, | |
| p.ProjectName, | |
| s.Track, | |
| s.SubTrack, | |
| lh.Description, | |
| lh.Comment | |
| FROM LogbookHistory lh | |
| LEFT JOIN [User] u ON lh.AssisgnTo = u.UserId | |
| LEFT JOIN [Logbook] l ON lh.LogbookId = l.LogbookId | |
| LEFT JOIN [tblMs_Projects] p ON l.ProjectName = p.ProjectID | |
| LEFT JOIN [tbl_Sprint] s ON lh.LogbookId = s.LogbookId | |
| WHERE {name_filter} | |
| AND lh.CreatedDate BETWEEN '{start_date}' AND '{end_date}' | |
| ORDER BY lh.CreatedDate ASC | |
| """ | |
| # SQL tool for agent | |
| query_weekly_progress = Tool( | |
| name="query_weekly_progress", | |
| func=lambda query: db_instance.run(query) if query.lower().strip().startswith("select") else "Only SELECT queries are allowed.", | |
| description="Runs a SQL SELECT query to retrieve user progress report." | |
| ) | |
| # System prompt for clean HTML output | |
| system_prompt = SystemMessagePromptTemplate( | |
| prompt=PromptTemplate( | |
| input_variables=[], | |
| template=""" | |
| You are a weekly reporting agent for PMO360. | |
| Return a clean HTML <table> using SQL output: | |
| - Fields: Name, LogbookId, Date, Project Name, Track, Sub Track, Description, Comment | |
| - Include headers | |
| - Align text to the left | |
| - Add table borders using a constant CSS class | |
| - No extra explanation, only output the HTML table | |
| """ | |
| ) | |
| ) | |
| # Human prompt | |
| human_prompt = HumanMessagePromptTemplate( | |
| prompt=PromptTemplate(input_variables=["input"], template="{input}") | |
| ) | |
| # Chat prompt | |
| chat_prompt = ChatPromptTemplate.from_messages([ | |
| system_prompt, | |
| MessagesPlaceholder(variable_name="chat_history", optional=True), | |
| human_prompt, | |
| MessagesPlaceholder(variable_name="agent_scratchpad") | |
| ]) | |
| # Setup LLM + agent executor | |
| llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0, openai_api_key=OPENAI_API_KEY) | |
| agent = create_openai_tools_agent(llm=llm, tools=[query_weekly_progress], prompt=chat_prompt) | |
| agent_executor = AgentExecutor(agent=agent, tools=[query_weekly_progress], verbose=True) | |
| # Name extractor LLM | |
| name_extractor = ChatOpenAI(model="gpt-3.5-turbo", temperature=0, openai_api_key=OPENAI_API_KEY) | |
| name_prompt = PromptTemplate( | |
| input_variables=["text"], | |
| template=""" | |
| Extract the first name, last name, and optional date range from the following text. Respond ONLY with a dictionary (no strings or quotes): | |
| Examples: | |
| "Show Rahul Kumar's report from April 10 to April 17" → {{"first_name": "Rahul", "last_name": "Kumar", "start_date": "2025-04-10", "end_date": "2025-04-17"}} | |
| "DPR for Anirban this week" → {{"first_name": "Anirban"}} | |
| "DPR is daily progress report" | |
| Prompt: {text} | |
| """ | |
| ) | |
| # FastAPI model for prompt input | |
| class PromptRequest(BaseModel): | |
| prompt: str | |
| # API endpoint | |
| async def get_prompt_based_dpr(request: PromptRequest): | |
| try: | |
| prompt_text = request.prompt.strip() | |
| name_response = name_extractor.invoke(name_prompt.format_prompt(text=prompt_text).to_string()) | |
| print("LLM raw output:", name_response.content) | |
| # Parse extracted names | |
| parsed = name_response.content.strip() | |
| if parsed.startswith("\"") or parsed.startswith("'"): | |
| parsed = parsed[1:-1] | |
| name_json = json.loads(parsed.replace("'", '"')) | |
| first = name_json.get("first_name") | |
| last = name_json.get("last_name") | |
| start_date = name_json.get("start_date") | |
| end_date = name_json.get("end_date") | |
| if not first: | |
| raise ValueError("No valid first name extracted.") | |
| sql = build_sql(first, last, start_date, end_date) | |
| context = f"Generate HTML weekly report for: {first} {last or ''} using this query:\n{sql}. Table must include Name, LogbookId, CreatedDate, ProjectName, Track, SubTrack, Description, Comment, and use a CSS class for bordered tables." | |
| response = agent_executor.invoke({"input": context}) | |
| return response.get("output", "No output generated.") | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"DPR Error: {e}") | |
| # Run the app | |
| if __name__ == "__main__": | |
| uvicorn.run("main:app", host="0.0.0.0", port=7860, reload=True) | |