Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import os | |
| from datetime import date | |
| import pandas as pd | |
| # ---------------------- API Config ---------------------- | |
| API_KEY = os.getenv("AIML_API_KEY") or "your_aimlapi_key_here" | |
| API_URL = "https://api.aimlapi.com/v1/chat/completions" | |
| SYSTEM_PROMPT = ( | |
| "You are a highly knowledgeable and friendly veterinary assistant AI. " | |
| "Provide clear, thorough, and helpful responses to users about pets (dogs and cats). " | |
| "Responses should be detailed, covering causes, symptoms, treatments, nutrition, precautions, " | |
| "recovery time, and practical advice. Use friendly, empathetic language and encourage consulting a vet for serious concerns. " | |
| "Avoid using markdown or special characters like asterisks. Use plain text and label sections clearly with headings such as 'Causes:', 'Symptoms:', etc." | |
| ) | |
| # ---------------------- AI State ---------------------- | |
| chat_history = [] | |
| followup_count = 0 | |
| # ---------------------- Dropdowns ---------------------- | |
| breed_options = { | |
| "Cat": ["Persian", "Siamese", "Maine Coon", "British Shorthair", "Other"], | |
| "Dog": ["German Shepherd", "Labrador", "Bulldog", "Pomeranian", "Other"] | |
| } | |
| symptom_list = [ | |
| "Vomiting", "Diarrhea", "Loss of Appetite", "Coughing", "Scratching", "Hair Loss", "Lethargy", "Other" | |
| ] | |
| breed_info_topics = [ | |
| "Favourite Food", "Most Common Diseases", "Precautions", "Allergies", "Favourite Activities", "Other" | |
| ] | |
| # ---------------------- Helper Functions ---------------------- | |
| def update_breed(pet_type): | |
| return gr.update(choices=breed_options.get(pet_type, []), value=None, visible=True), gr.update(visible=False, value="") | |
| def handle_breed_other(breed_choice): | |
| return gr.update(visible=(breed_choice == "Other"), value="") | |
| def handle_symptom_other(symptom): | |
| return gr.update(visible=(symptom == "Other"), value="") | |
| def handle_info_other(info): | |
| return gr.update(visible=(info == "Other"), value="") | |
| def ask_ai(pet, breed, other_breed, age, gender, weight, topic, symptom, other_symptom, condition, info_topic, other_info, user_detail): | |
| global chat_history, followup_count | |
| followup_count = 0 | |
| pet = pet.strip() | |
| final_breed = other_breed.strip() if breed == "Other" else breed | |
| final_symptom = other_symptom.strip() if symptom == "Other" else symptom | |
| final_info = other_info.strip() if info_topic == "Other" else info_topic | |
| age = age.strip() | |
| gender = gender.strip() | |
| weight = weight.strip() | |
| condition = condition.strip() | |
| user_detail = user_detail.strip()[:100] | |
| prompt_parts = [ | |
| f"Pet: {pet}", | |
| f"Breed: {final_breed}", | |
| f"Age: {age}", | |
| f"Gender: {gender}", | |
| f"Weight: {weight}" | |
| ] | |
| if topic == "Symptom Checker": | |
| prompt_parts.append(f"Symptom: {final_symptom}") | |
| prompt_parts.append( | |
| "Please provide a detailed explanation including: typical causes, when and how this symptom usually appears, " | |
| "recommended treatments and home care, expected recovery timeline, preventive measures, and when to seek a vet." | |
| ) | |
| elif topic == "Nutrition": | |
| prompt_parts.append(f"Condition: {condition if condition else 'None'}") | |
| prompt_parts.append( | |
| "Provide a comprehensive nutrition guide for this breed/condition: best foods available locally (Pakistan), benefits of each food, " | |
| "recommended feeding quantity and frequency, and tips for maintaining optimal health." | |
| ) | |
| elif topic == "Breed Info": | |
| prompt_parts.append(f"Information Requested: {final_info}") | |
| prompt_parts.append( | |
| "Give detailed and interesting information on the selected topic related to the breed, covering key facts, practical tips, " | |
| "common concerns, and any special advice." | |
| ) | |
| if user_detail: | |
| prompt_parts.append(f"User Detail: {user_detail}") | |
| user_prompt = "\n".join(prompt_parts) | |
| messages = [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": user_prompt} | |
| ] | |
| payload = { | |
| "model": "gpt-4o-mini-2024-07-18", | |
| "messages": messages, | |
| "temperature": 0.7, | |
| "max_tokens": 1200 # Increased token limit | |
| } | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {API_KEY}" | |
| } | |
| try: | |
| response = requests.post(API_URL, json=payload, headers=headers) | |
| response.raise_for_status() | |
| result = response.json() | |
| answer = result['choices'][0]['message']['content'].strip() | |
| chat_history.clear() | |
| chat_history.extend(messages + [{"role": "assistant", "content": answer}]) | |
| return answer | |
| except Exception as e: | |
| return f"β Error: {str(e)}" | |
| def handle_followup(user_input): | |
| global chat_history, followup_count | |
| if followup_count >= 5: | |
| return "β οΈ Max of 5 follow-up questions reached." | |
| chat_history.append({"role": "user", "content": user_input}) | |
| payload = { | |
| "model": "gpt-4o-mini-2024-07-18", | |
| "messages": chat_history, | |
| "temperature": 0.6, | |
| "max_tokens": 600 | |
| } | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {API_KEY}" | |
| } | |
| try: | |
| response = requests.post(API_URL, json=payload, headers=headers) | |
| response.raise_for_status() | |
| result = response.json() | |
| reply = result['choices'][0]['message']['content'].strip() | |
| chat_history.append({"role": "assistant", "content": reply}) | |
| followup_count += 1 | |
| return reply | |
| except Exception as e: | |
| return f"β Error: {str(e)}" | |
| # ---------------------- Vaccination Tracker ---------------------- | |
| vaccination_records = [] | |
| def save_vaccination_record(pet_type, breed, pet_name, age, last_date, total_doses, upcoming_date, vaccine_type, notes): | |
| record = { | |
| "Pet Type": pet_type, | |
| "Breed": breed, | |
| "Pet Name": pet_name, | |
| "Age": age, | |
| "Last Vaccination Date": last_date, | |
| "Total Doses": total_doses, | |
| "Upcoming Dose Date": upcoming_date, | |
| "Vaccine Type": vaccine_type, | |
| "Notes": notes | |
| } | |
| vaccination_records.append(record) | |
| return f"β Record saved for {pet_name} ({breed})" | |
| def view_all_vaccination_records(): | |
| if not vaccination_records: | |
| return "π No records saved yet." | |
| df = pd.DataFrame(vaccination_records) | |
| return df | |
| # ---------------------- UI ---------------------- | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# πΎ Smart Paws: AI Assistant + Vaccination Tracker") | |
| with gr.Tabs(): | |
| # --- Tab 1: AI Assistant --- | |
| with gr.TabItem("π§ Smart Paws AI Assistant"): | |
| with gr.Row(): | |
| pet = gr.Dropdown(["Cat", "Dog"], label="π Pet Type") | |
| breed = gr.Dropdown(label="πΎ Select Breed", visible=False) | |
| other_breed = gr.Textbox(label="βοΈ Enter Breed", visible=False) | |
| pet.change(update_breed, pet, [breed, other_breed]) | |
| breed.change(handle_breed_other, breed, other_breed) | |
| with gr.Row(): | |
| age = gr.Textbox(label="π Age (e.g. 2 years or 8 months)") | |
| gender = gr.Dropdown(["Male", "Female", "Unknown"], label="π» Gender") | |
| weight = gr.Textbox(label="βοΈ Weight (e.g. 10 kg)") | |
| topic = gr.Dropdown(["Symptom Checker", "Nutrition", "Breed Info"], label="π Select Topic") | |
| with gr.Column(visible=False) as symptom_section: | |
| symptom = gr.Dropdown(symptom_list, label="π€ Select Symptom") | |
| other_symptom = gr.Textbox(label="βοΈ Enter Symptom", visible=False) | |
| symptom.change(handle_symptom_other, symptom, other_symptom) | |
| with gr.Column(visible=False) as nutrition_section: | |
| condition = gr.Textbox(label="π©Ί Condition (Optional, e.g. slim, weak)") | |
| with gr.Column(visible=False) as breed_info_section: | |
| info_topic = gr.Dropdown(breed_info_topics, label="βΉοΈ Select Info Type") | |
| other_info = gr.Textbox(label="βοΈ Enter Info Topic", visible=False) | |
| info_topic.change(handle_info_other, info_topic, other_info) | |
| user_detail = gr.Textbox(label="π Extra Detail (optional, max 100 chars)", max_lines=2) | |
| def show_topic_fields(selected_topic): | |
| return [ | |
| gr.update(visible=(selected_topic == "Symptom Checker")), | |
| gr.update(visible=(selected_topic == "Nutrition")), | |
| gr.update(visible=(selected_topic == "Breed Info")) | |
| ] | |
| topic.change(show_topic_fields, topic, [symptom_section, nutrition_section, breed_info_section]) | |
| submit_btn = gr.Button("Get Advice") | |
| output = gr.Textbox(label="π¬ AI Response", lines=20) | |
| gr.Markdown("## π Ask Follow-up") | |
| followup_input = gr.Textbox(label="π£οΈ Follow-up Question") | |
| followup_btn = gr.Button("Ask Follow-up") | |
| followup_output = gr.Textbox(label="π‘ Follow-up Response", lines=8) | |
| submit_btn.click( | |
| ask_ai, | |
| inputs=[pet, breed, other_breed, age, gender, weight, topic, symptom, other_symptom, condition, info_topic, other_info, user_detail], | |
| outputs=output | |
| ) | |
| followup_btn.click(handle_followup, inputs=followup_input, outputs=followup_output) | |
| # --- Tab 2: Vaccination Records --- | |
| with gr.TabItem("π Pet Vaccination Records"): | |
| gr.Markdown("### π Enter Vaccination Details") | |
| with gr.Row(): | |
| v_pet_type = gr.Dropdown(["Dog", "Cat"], label="Pet Type") | |
| v_breed = gr.Textbox(label="Breed") | |
| v_pet_name = gr.Textbox(label="Pet Name") | |
| v_age = gr.Textbox(label="Age") | |
| with gr.Row(): | |
| v_last_vaccination = gr.Textbox(label="Last Vaccination Date (YYYY-MM-DD)") | |
| v_total_doses = gr.Number(label="Total Doses Taken") | |
| v_upcoming_dose = gr.Textbox(label="Upcoming Dose Date (YYYY-MM-DD)") | |
| v_vaccine_type = gr.Dropdown(["Rabies", "DHPP", "FVRCP", "Bordetella", "Leptospirosis", "Other"], label="Vaccine Type") | |
| v_notes = gr.Textbox(label="Additional Notes", lines=3) | |
| save_btn = gr.Button("Save Record") | |
| save_output = gr.Textbox(label="π Status") | |
| view_btn = gr.Button("π View All Records") | |
| table_output = gr.Dataframe(label="π Saved Records", visible=True) | |
| save_btn.click( | |
| save_vaccination_record, | |
| inputs=[v_pet_type, v_breed, v_pet_name, v_age, v_last_vaccination, v_total_doses, v_upcoming_dose, v_vaccine_type, v_notes], | |
| outputs=save_output | |
| ) | |
| view_btn.click(view_all_vaccination_records, inputs=[], outputs=table_output) | |
| # ---------------------- Run App ---------------------- | |
| if __name__ == "__main__": | |
| demo.launch() | |