mk1985 commited on
Commit
8310805
·
verified ·
1 Parent(s): 166ad97

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -161
app.py CHANGED
@@ -1,169 +1,51 @@
1
- import gradio as gr
2
- from langchain_community.vectorstores import Chroma
3
- from langchain_core.documents import Document
4
- from langchain_huggingface import HuggingFaceEmbeddings
5
- import json
 
 
6
  import os
7
 
8
- # -------------------------------
9
- # CONFIGURATION
10
- # -------------------------------
11
- os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "sk-your-key-here")
12
-
13
- # -------------------------------
14
- # LOAD DATA AND BUILD RAG CHAIN
15
- # -------------------------------
16
- def clean_metadata(metadata):
17
- """Convert list values to comma-separated strings for ChromaDB compatibility"""
18
- cleaned = {}
19
- for key, value in metadata.items():
20
- if isinstance(value, list):
21
- cleaned[key] = ", ".join(str(v) for v in value)
22
- elif isinstance(value, (str, int, float, bool)) or value is None:
23
- cleaned[key] = value
24
- else:
25
- cleaned[key] = str(value)
26
- return cleaned
27
-
28
- print("Loading documents...")
29
- docs = []
30
- with open("helpwildlife_rag.jsonl", "r", encoding="utf-8") as f:
31
- for line in f:
32
- entry = json.loads(line)
33
- metadata = entry.get("metadata", {})
34
- docs.append(Document(
35
- page_content=entry["text"],
36
- metadata=clean_metadata(metadata)
37
- ))
38
- print(f"✓ Loaded {len(docs)} documents")
39
-
40
- print("Loading embedding model...")
41
- embeddings = HuggingFaceEmbeddings(
42
- model_name="sentence-transformers/all-MiniLM-L6-v2"
43
  )
44
 
45
- print("Building vector store...")
46
- try:
47
- vectorstore = Chroma.from_documents(docs, embedding=embeddings)
48
- except TypeError:
49
- vectorstore = Chroma.from_documents(docs, embedding_function=embeddings)
50
-
51
- retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
52
- print("✓ Vector store created")
53
-
54
- # Prompt template as string
55
- prompt_template = """
56
- You are a compassionate wildlife advice assistant.
57
- Your only source of information is the text provided in the CONTEXT section below.
58
- Do not use outside knowledge, guesses, or general reasoning.
59
- If the context does not contain enough information to answer fully,
60
- say "I'm not sure based on the available guidance."
61
-
62
- Never suggest killing or harming any animal.
63
- Always emphasise that taking an injured or distressed animal to a local wildlife rescue
64
- or 24/7 animal hospital is the safest and most humane course of action.
65
- Discourage people from trying to handle or treat the animal themselves,
66
- and note that general veterinary clinics may euthanise wild animals unnecessarily.
67
-
68
- Adopt a voice of empathy and respect for all life, consistent with vegan principles:
69
- there are no animals that are pests, vermin, or unworthy of care.
70
- Respond clearly and calmly, with brief, practical, step-by-step guidance suitable for the public.
71
-
72
- ---------------------
73
- CONTEXT (from HelpWildlife data file):
74
- {context}
75
- ---------------------
76
- QUESTION:
77
- {question}
78
-
79
- YOUR ANSWER:
80
- """
81
-
82
- # Global LLM variable - will be initialized lazily
83
- _llm = None
84
-
85
- def get_llm():
86
- """Lazy load the LLM only when first needed"""
87
- global _llm
88
- if _llm is None:
89
- from langchain_openai import ChatOpenAI
90
- from langchain_core.prompts import ChatPromptTemplate
91
- from langchain_core.output_parsers import StrOutputParser
92
- from langchain_core.runnables import RunnablePassthrough
93
-
94
- # --- FIX FOR PYDANTIC CLASS ISSUE ---
95
- try:
96
- ChatOpenAI.model_rebuild(force=True)
97
- except Exception:
98
- pass
99
-
100
- llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)
101
- prompt = ChatPromptTemplate.from_template(prompt_template)
102
-
103
- def format_docs(docs):
104
- return "\n\n".join(doc.page_content for doc in docs)
105
-
106
- _llm = (
107
- {
108
- "context": retriever | format_docs,
109
- "question": RunnablePassthrough()
110
- }
111
- | prompt
112
- | llm
113
- | StrOutputParser()
114
- )
115
- return _llm
116
-
117
- print("✓ Setup complete - LLM will initialize on first use")
118
-
119
- # -------------------------------
120
- # GRADIO INTERFACE
121
- # -------------------------------
122
- def ask_wildlife_question(question):
123
- """Process a wildlife question and return an answer"""
124
- if not question.strip():
125
- return "Please enter a question about wildlife."
126
-
127
- try:
128
- rag_chain = get_llm()
129
- answer = rag_chain.invoke(question)
130
- return answer
131
- except Exception as e:
132
- return f"Error: {str(e)}\n\nPlease check your OpenAI API key is set correctly in Space secrets."
133
-
134
- # Example questions
135
- examples = [
136
- "I found a baby hedgehog out during the day. What should I do?",
137
- "There's a bird that seems injured in my garden. How can I help?",
138
- "I found a baby bird on the ground. Should I put it back in the nest?",
139
- "A fox is limping in my backyard. What should I do?",
140
- "How do I know if a wild animal needs help?"
141
- ]
142
 
143
- # Create Gradio interface
144
- demo = gr.Interface(
145
- fn=ask_wildlife_question,
146
- inputs=gr.Textbox(
147
- label="Ask a Wildlife Question",
148
- placeholder="e.g., I found a baby bird on the ground...",
149
- lines=3
150
- ),
151
- outputs=gr.Textbox(
152
- label="Compassionate Advice",
153
- lines=10
154
- ),
155
- title="🦔 Wildlife Rescue Assistant",
156
- description="""
157
- Ask questions about helping wildlife in distress. This assistant provides compassionate,
158
- evidence-based advice prioritizing the wellbeing of all animals.
159
-
160
- ⚠️ **Important**: This tool provides general guidance only. For urgent situations,
161
- contact your local wildlife rescue or 24/7 animal hospital immediately.
162
- """,
163
- examples=examples,
164
- theme=gr.themes.Soft(),
165
- allow_flagging="never"
166
  )
167
 
 
 
 
168
  if __name__ == "__main__":
169
- demo.launch()
 
 
 
 
1
+ # -----------------------------
2
+ # Imports
3
+ # -----------------------------
4
+ from langchain_openai import ChatOpenAI
5
+ from langchain_core.caches import BaseCache # Must be imported before model_rebuild
6
+ from langchain.chains import LLMChain
7
+ from langchain.prompts import PromptTemplate
8
  import os
9
 
10
+ # -----------------------------
11
+ # Fix for "class not fully defined" Pydantic error
12
+ # -----------------------------
13
+ ChatOpenAI.model_rebuild()
14
+
15
+ # -----------------------------
16
+ # API key setup
17
+ # -----------------------------
18
+ # For local use: ensure OPENAI_API_KEY is set in your environment
19
+ # For Hugging Face Space: add it under Settings → Secrets
20
+ if "OPENAI_API_KEY" not in os.environ:
21
+ raise ValueError("OPENAI_API_KEY not found. Please set it in environment or Space secrets.")
22
+
23
+ # -----------------------------
24
+ # Initialise model
25
+ # -----------------------------
26
+ llm = ChatOpenAI(
27
+ model="gpt-4o-mini", # or "gpt-4o", "gpt-4-turbo" etc.
28
+ temperature=0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  )
30
 
31
+ # -----------------------------
32
+ # Example prompt and chain
33
+ # -----------------------------
34
+ prompt = PromptTemplate(
35
+ input_variables=["topic"],
36
+ template="Summarise the main challenges and opportunities of using AI in {topic}."
37
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ chain = LLMChain(
40
+ llm=llm,
41
+ prompt=prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  )
43
 
44
+ # -----------------------------
45
+ # Run the chain
46
+ # -----------------------------
47
  if __name__ == "__main__":
48
+ topic = "government recordkeeping"
49
+ result = chain.run(topic=topic)
50
+ print("=== Model Output ===")
51
+ print(result)