anilkumar5590 commited on
Commit
0996608
·
verified ·
1 Parent(s): f3bf76d

Update backendapi.py

Browse files
Files changed (1) hide show
  1. backendapi.py +268 -81
backendapi.py CHANGED
@@ -1,10 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  from flask import Flask, request, jsonify
3
  from flask_cors import CORS # Import CORS for cross-origin access
4
  import tensorflow as tf
5
  from tensorflow.keras.preprocessing import image
6
  import numpy as np
7
- import gdown
8
  import io
9
  from PIL import Image
10
  import time
@@ -12,61 +223,6 @@ import traceback
12
  import google.generativeai as genai # Google Gemini AI
13
  import re
14
  from huggingface_hub import hf_hub_download
15
- # Load the pre-trained model (adjust the path as needed)
16
- # model = tf.keras.models.load_model("efficient_model_63.keras")
17
-
18
-
19
- # # Download model from Hugging Face
20
- # model_path = hf_hub_download(
21
- # repo_id="anilkumar5590/image-classification-viit",
22
- # filename="model.keras",
23
- # local_dir="/tmp"
24
- # )
25
-
26
- # # Load the model
27
- # model = tf.keras.models.load_model(model_path)
28
-
29
-
30
-
31
- # MODEL_PATH = "/tmp/model.keras"
32
-
33
- # def load_model_from_huggingface():
34
- # if not os.path.exists(MODEL_PATH):
35
- # print("Downloading model from Hugging Face Hub...")
36
- # hf_hub_download(
37
- # repo_id="anilkumar5590/image-classification-viit",
38
- # filename="model.keras",
39
- # local_dir="/tmp"
40
- # )
41
- # print("Download complete!")
42
- # else:
43
- # print("Model already exists. Loading from /tmp/")
44
-
45
- # model = tf.keras.models.load_model(MODEL_PATH)
46
- # print("Model loaded successfully!")
47
- # return model
48
-
49
-
50
- def load_model_from_huggingface():
51
- cache_dir = "/tmp/huggingface" # Define a writable cache directory
52
- os.makedirs(cache_dir, exist_ok=True) # Ensure it exists
53
-
54
- print("Downloading model from Hugging Face Hub...")
55
-
56
- model_path = hf_hub_download(
57
- repo_id="anilkumar5590/image-classification-viit",
58
- filename="model.keras", # Adjust the filename based on your model
59
- cache_dir=cache_dir # Use the custom directory
60
- )
61
-
62
- print("Model downloaded successfully at:", model_path)
63
- return model_path # You may need to load it using TensorFlow or PyTorch
64
-
65
- # Load model at startup
66
- model = load_model_from_huggingface()
67
-
68
- # In-memory store to simulate prediction processing
69
- prediction_results = {}
70
 
71
  # Create Flask app
72
  app = Flask(__name__)
@@ -78,21 +234,29 @@ CORS(app)
78
  genai.configure(api_key="AIzaSyD0M3hdjekk6w_b9WXXb0T_qLAS0MY5iDQ") # Replace with your actual API key
79
  model_gemini = genai.GenerativeModel("gemini-1.5-flash") # Use a fast Gemini AI model
80
 
 
 
 
81
  # Define preprocessing function for the uploaded image
82
  def preprocess_image(img):
83
- img = img.resize((224, 224)) # Resize image to match model input size
84
- img_array = np.array(img)
85
- img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
86
- img_array = tf.keras.applications.efficientnet.preprocess_input(img_array) # Preprocess for EfficientNet
87
- return img_array
88
-
 
 
 
89
 
 
90
  def clean_explanation(text):
91
  """Remove unnecessary formatting such as * and excess whitespace."""
92
  text = re.sub(r'\*+', '', text) # Remove asterisks
93
  text = re.sub(r'\s+', ' ', text).strip() # Normalize spaces
94
  return text
95
 
 
96
  def generate_explanation(predicted_class):
97
  try:
98
  prompt = f"Get instant feedback with the predicted animal name {predicted_class} along with relevant details like its habitat, diet. Provide a brief yet informative explanation, including unique characteristics, scientific name, and any interesting facts. Keep the response engaging and easy to understand for general users. Avoid technical jargon, but ensure accuracy. Limit the response to 5-6 sentences."
@@ -103,8 +267,7 @@ def generate_explanation(predicted_class):
103
  print(f"Error generating explanation: {e}")
104
  return f"This is a {predicted_class}."
105
 
106
-
107
-
108
  def get_conservation_status(class_name):
109
  """
110
  Extracts and returns the conservation status from the given class name.
@@ -135,37 +298,64 @@ def get_conservation_status(class_name):
135
 
136
  return "Unknown conservation status"
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  # Define route for predictions (POST)
140
  @app.route("/predict", methods=["POST"])
141
  def predict():
142
  print("Request Files:", request.files)
143
-
144
  file = request.files.get('file')
145
 
146
  if not file:
 
147
  return jsonify({"error": "No file part"}), 400
148
 
149
  try:
150
  # Open and preprocess the image
 
151
  img = Image.open(io.BytesIO(file.read()))
152
  print(f"Received image: {img.size}")
153
  img_array = preprocess_image(img)
154
-
155
- # Simulate prediction delay (e.g., processing the image)
156
- time.sleep(2) # Simulating a delay
157
 
158
  # Make prediction
 
159
  predictions = model.predict(img_array)
 
 
 
160
  predicted_class_index = np.argmax(predictions, axis=1)[0]
161
  confidence_level = round(np.max(predictions) * 100, 2)
162
 
 
 
 
 
 
163
 
164
- labels = {0: 'Aardvark-LC', 1: 'African Elephant-EN', 2: 'Alligator-LC', 3: 'Alpaca-LC', 4: 'Anaconda-LC', 5: 'Arctic Fox-VU', 6: 'Armadillo-LC', 7: 'Axolotl-CR', 8: 'Baboon-LC', 9: 'Badger-LC', 10: 'Bald Eagle-LC', 11: 'Barracuda-LC', 12: 'Bat-LC', 13: 'Bison-NT', 14: 'Black Bear-LC', 15: 'Blue Jay-LC', 16: 'Boa Constrictor-LC', 17: 'Bonobo-EN', 18: 'Buffalo-LC', 19: 'Butterfly-LC', 20: 'Caiman-LC', 21: 'Camel-LC', 22: 'Capybara-LC', 23: 'Caracal-LC', 24: 'Cheetah-VU', 25: 'Chimpanzee-EN', 26: 'Cobra-LC', 27: 'Cockatoo-LC', 28: 'Coral-CR', 29: 'Coyote-LC', 30: 'Crocodile-LC', 31: 'Deer-LC', 32: 'Dingo-LC', 33: 'Dodo-EX', 34: 'Dolphin-LC', 35: 'Domestic Cat-LC', 36: 'Donkey-LC', 37: 'Dragonfly-LC', 38: 'Duck-LC', 39: 'Dugong-VU', 40: 'Eagle-LC', 41: 'Earthworm-LC', 42: 'Echidna-LC', 43: 'Eel-LC', 44: 'Elephant-EN', 45: 'Elk-LC', 46: 'Emu-LC', 47: 'Falcon-LC', 48: 'Ferret-EN', 49: 'Finch-LC', 50: 'Firefly-LC', 51: 'Fish-LC', 52: 'Flamingo-LC', 53: 'Fossa-VU', 54: 'Fox-LC', 55: 'Frog-LC', 56: 'Galápagos Tortoise-VU', 57: 'Gazelle-VU', 58: 'Gecko-LC', 59: 'Gibbon-EN', 60: 'Giraffe-VU', 61: 'Goat-LC', 62: 'Goose-LC', 63: 'Gorilla-CR', 64: 'Grasshopper-LC', 65: 'Great White Shark-VU', 66: 'Green Anaconda-LC', 67: 'Grizzly Bear-LC', 68: 'Hammerhead Shark-CR', 69: 'Hamster-LC', 70: 'Hare-LC', 71: 'Hawk-LC', 72: 'Hedgehog-LC', 73: 'Hermit Crab-LC', 74: 'Hippopotamus-VU', 75: 'Honeybee-LC', 76: 'Hornbill-NT', 77: 'Horse-LC', 78: 'Hummingbird-LC', 79: 'Ibex-LC', 80: 'Ibis-LC', 81: 'Indian Cobra-LC', 82: 'Indian Elephant-EN', 83: 'Indian Star Tortoise-VU', 84: 'Indian Wolf-EN', 85: 'Jackal-LC', 86: 'Jaguar-NT', 87: 'Japanese Beetle-LC', 88: 'Jellyfish-LC', 89: 'Kangaroo-LC', 90: 'King Cobra-VU', 91: 'Kingfisher-LC', 92: 'Kiwi-EN', 93: 'Koala-VU', 94: 'Komodo Dragon-EN', 95: 'Ladybug-LC', 96: 'Lemming-LC', 97: 'Lemur-CR', 98: 'Leopard-VU', 99: 'Lion-VU', 100: 'Lizard-LC', 101: 'Llama-LC', 102: 'Lobster-LC', 103: 'Lynx-LC', 104: 'Macaw-EN', 105: 'Magpie-LC', 106: 'Manatee-VU', 107: 'Mandrill-VU', 108: 'Mantis Shrimp-LC', 109: 'Meerkat-LC', 110: 'Mole-LC', 111: 'Moose-LC', 112: 'Moray Eel-LC', 113: 'Mountain Lion-LC', 114: 'Musk Ox-LC', 115: 'Nandu Rhea-LC', 116: 'Narwhal-NT', 117: 'Newt-LC', 118: 'Nightingale-LC', 119: 'Octopus-LC', 120: 'Okapi-EN', 121: 'Opossum-LC', 122: 'Orangutan-CR', 123: 'Ostrich-LC', 124: 'Otter-VU', 125: 'Owl-LC', 126: 'Ox-LC', 127: 'Panda-VU', 128: 'Panther-NT', 129: 'Parrot-LC', 130: 'Peacock-LC', 131: 'Pelican-LC', 132: 'Penguin-NT', 133: 'Pigeon-LC', 134: 'Piranha-LC', 135: 'Platypus-LC', 136: 'Polar Bear-VU', 137: 'Porcupine-LC', 138: 'Possum-LC', 139: 'Praying Mantis-LC', 140: 'Puffin-LC', 141: 'Python-LC', 142: 'Quail-LC', 143: 'Quetzal-NT', 144: 'Quokka-LC', 145: 'Quoll-NT', 146: 'Rabbit-LC', 147: 'Raccoon-LC', 148: 'Ram-LC', 149: 'Rat-LC', 150: 'Raven-LC', 151: 'Red Panda-EN', 152: 'Reindeer-VU', 153: 'Rhinoceros-CR', 154: 'Roadrunner-LC', 155: 'Salamander-LC', 156: 'Scorpion-LC', 157: 'Sea Lion-LC', 158: 'Seahorse-LC', 159: 'Shark-VU', 160: 'Sheep-LC', 161: 'Skunk-LC', 162: 'Sloth-VU', 163: 'Snail-LC', 164: 'Snake-LC', 165: 'Snow Leopard-VU', 166: 'Sparrow-LC', 167: 'Spider-LC', 168: 'Squirrel-LC', 169: 'Starfish-LC', 170: 'Stork-LC', 171: 'Swan-LC', 172: 'Tamarin-EN', 173: 'Tapir-VU', 174: 'Tasmanian Devil-EN', 175: 'Termite-LC', 176: 'Thorny Devil-LC', 177: 'Tiger-EN', 178: 'Toad-LC', 179: 'Toucan-LC', 180: 'Tuna-LC', 181: 'Turkey-LC', 182: 'Turtle-VU', 183: 'Uakari-VU', 184: 'Umbrellabird-VU', 185: 'Urchin-LC', 186: 'Uromastyx-LC', 187: 'Vampire Bat-LC', 188: 'Vaquita-CR', 189: 'Vervet Monkey-LC', 190: 'Vulture-LC', 191: 'Wallaby-LC', 192: 'Walrus-VU', 193: 'Warthog-LC', 194: 'Weasel-LC', 195: 'Whale-EN', 196: 'White Tiger-EN', 197: 'Wild Cat-VU', 198: 'Wolf-VU', 199: 'Wolverine-LC', 200: 'Wombat-LC', 201: 'Woodpecker-LC', 202: 'X-ray Tetra-LC', 203: 'Xenopus-LC', 204: 'Yak-LC', 205: 'Yellowjacket-LC', 206: 'Zebra Finch-LC', 207: 'Zebra-NT', 208: 'Zebu-LC', 209: 'Zorilla-LC'}
165
- # Replace with your model's labels
166
-
167
  predicted_class = labels.get(predicted_class_index, "Unknown")
168
- conservation_status= get_conservation_status(predicted_class)
169
  predicted_class = predicted_class.split('-')[0] # Remove the conservation status from the class name
170
  print(f"Prediction: {predicted_class}, Confidence: {confidence_level}%")
171
 
@@ -173,24 +363,20 @@ def predict():
173
  explanation = generate_explanation(predicted_class)
174
 
175
  # Store the result in the in-memory dictionary
176
- prediction_id = str(time.time()) # Unique ID for the request
177
-
178
  prediction_results[prediction_id] = {
179
  "predicted_class": predicted_class,
180
  "conservation_status": conservation_status,
181
  "confidence_level": confidence_level,
182
  "explanation": explanation
183
  }
184
-
185
  print(f"Prediction ID: {prediction_id}, Result: {prediction_results[prediction_id]}")
186
- # Return the prediction ID to be used for GET request later
187
  return jsonify({"prediction_id": prediction_id}), 200
188
 
189
  except Exception as e:
190
- # Include the traceback in the error response
191
- error_message = traceback.format_exc()
192
- print(error_message) # Print in the server logs
193
- return jsonify({"error": f"Error during prediction: {error_message}"}), 500
194
 
195
  # Define route for retrieving predictions (GET)
196
  @app.route("/get_prediction/<prediction_id>", methods=["GET"])
@@ -203,5 +389,6 @@ def get_prediction(prediction_id):
203
  print(f"No result found for ID: {prediction_id}")
204
  return jsonify({"error": "Prediction not found or still processing"}), 404
205
 
 
206
  if __name__ == "__main__":
207
- app.run(host='0.0.0.0', port=7860,debug=True)
 
1
+ # import os
2
+ # from flask import Flask, request, jsonify
3
+ # from flask_cors import CORS # Import CORS for cross-origin access
4
+ # import tensorflow as tf
5
+ # from tensorflow.keras.preprocessing import image
6
+ # import numpy as np
7
+ # import gdown
8
+ # import io
9
+ # from PIL import Image
10
+ # import time
11
+ # import traceback
12
+ # import google.generativeai as genai # Google Gemini AI
13
+ # import re
14
+ # from huggingface_hub import hf_hub_download
15
+ # # Load the pre-trained model (adjust the path as needed)
16
+ # # model = tf.keras.models.load_model("efficient_model_63.keras")
17
+
18
+
19
+ # # # Download model from Hugging Face
20
+ # # model_path = hf_hub_download(
21
+ # # repo_id="anilkumar5590/image-classification-viit",
22
+ # # filename="model.keras",
23
+ # # local_dir="/tmp"
24
+ # # )
25
+
26
+ # # # Load the model
27
+ # # model = tf.keras.models.load_model(model_path)
28
+
29
+
30
+
31
+ # # MODEL_PATH = "/tmp/model.keras"
32
+
33
+ # # def load_model_from_huggingface():
34
+ # # if not os.path.exists(MODEL_PATH):
35
+ # # print("Downloading model from Hugging Face Hub...")
36
+ # # hf_hub_download(
37
+ # # repo_id="anilkumar5590/image-classification-viit",
38
+ # # filename="model.keras",
39
+ # # local_dir="/tmp"
40
+ # # )
41
+ # # print("Download complete!")
42
+ # # else:
43
+ # # print("Model already exists. Loading from /tmp/")
44
+
45
+ # # model = tf.keras.models.load_model(MODEL_PATH)
46
+ # # print("Model loaded successfully!")
47
+ # # return model
48
+
49
+
50
+ # def load_model_from_huggingface():
51
+ # cache_dir = "/tmp/huggingface" # Define a writable cache directory
52
+ # os.makedirs(cache_dir, exist_ok=True) # Ensure it exists
53
+
54
+ # print("Downloading model from Hugging Face Hub...")
55
+
56
+ # model_path = hf_hub_download(
57
+ # repo_id="anilkumar5590/image-classification-viit",
58
+ # filename="model.keras", # Adjust the filename based on your model
59
+ # cache_dir=cache_dir # Use the custom directory
60
+ # )
61
+
62
+ # print("Model downloaded successfully at:", model_path)
63
+ # return model_path # You may need to load it using TensorFlow or PyTorch
64
+
65
+ # # Load model at startup
66
+ # model = load_model_from_huggingface()
67
+
68
+ # # In-memory store to simulate prediction processing
69
+ # prediction_results = {}
70
+
71
+ # # Create Flask app
72
+ # app = Flask(__name__)
73
+
74
+ # # Enable CORS for all routes
75
+ # CORS(app)
76
+
77
+ # # Configure Google Gemini AI
78
+ # genai.configure(api_key="AIzaSyD0M3hdjekk6w_b9WXXb0T_qLAS0MY5iDQ") # Replace with your actual API key
79
+ # model_gemini = genai.GenerativeModel("gemini-1.5-flash") # Use a fast Gemini AI model
80
+
81
+ # # Define preprocessing function for the uploaded image
82
+ # def preprocess_image(img):
83
+ # img = img.resize((224, 224)) # Resize image to match model input size
84
+ # img_array = np.array(img)
85
+ # img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
86
+ # img_array = tf.keras.applications.efficientnet.preprocess_input(img_array) # Preprocess for EfficientNet
87
+ # return img_array
88
+
89
+
90
+ # def clean_explanation(text):
91
+ # """Remove unnecessary formatting such as * and excess whitespace."""
92
+ # text = re.sub(r'\*+', '', text) # Remove asterisks
93
+ # text = re.sub(r'\s+', ' ', text).strip() # Normalize spaces
94
+ # return text
95
+
96
+ # def generate_explanation(predicted_class):
97
+ # try:
98
+ # prompt = f"Get instant feedback with the predicted animal name {predicted_class} along with relevant details like its habitat, diet. Provide a brief yet informative explanation, including unique characteristics, scientific name, and any interesting facts. Keep the response engaging and easy to understand for general users. Avoid technical jargon, but ensure accuracy. Limit the response to 5-6 sentences."
99
+ # response = model_gemini.generate_content(prompt)
100
+ # raw_text = response.text.strip() if response and response.text else f"This is a {predicted_class}."
101
+ # return clean_explanation(raw_text) # Clean the AI-generated text
102
+ # except Exception as e:
103
+ # print(f"Error generating explanation: {e}")
104
+ # return f"This is a {predicted_class}."
105
+
106
+
107
+
108
+ # def get_conservation_status(class_name):
109
+ # """
110
+ # Extracts and returns the conservation status from the given class name.
111
+
112
+ # Args:
113
+ # class_name (str): The predicted class name, e.g., 'Axolotl-CR', 'African Elephant-EN'.
114
+
115
+ # Returns:
116
+ # str: The full conservation status description.
117
+ # """
118
+ # status_map = {
119
+ # "EX": "Extinct (EX) - No known individuals remaining.",
120
+ # "EW": "Extinct in the Wild (EW) - Survives only in captivity.",
121
+ # "CR": "Critically Endangered (CR) - Faces an extremely high risk of extinction.",
122
+ # "EN": "Endangered (EN) - High risk of extinction in the wild.",
123
+ # "VU": "Vulnerable (VU) - At risk of becoming endangered.",
124
+ # "NT": "Near Threatened (NT) - Likely to become endangered in the future.",
125
+ # "LC": "Least Concern (LC) - Lowest risk of extinction.",
126
+ # "DD": "Data Deficient (DD) - Not enough information to assess the risk.",
127
+ # "NE": "Not Evaluated (NE) - Has not yet been assessed."
128
+ # }
129
+
130
+ # # Extract the conservation status from the class name
131
+ # parts = class_name.split('-')
132
+ # if len(parts) > 1:
133
+ # status_abbr = parts[-1] # The last part should be the conservation status
134
+ # return status_map.get(status_abbr, "Unknown conservation status")
135
+
136
+ # return "Unknown conservation status"
137
+
138
+
139
+ # # Define route for predictions (POST)
140
+ # @app.route("/predict", methods=["POST"])
141
+ # def predict():
142
+ # print("Request Files:", request.files)
143
+
144
+ # file = request.files.get('file')
145
+
146
+ # if not file:
147
+ # return jsonify({"error": "No file part"}), 400
148
+
149
+ # try:
150
+ # # Open and preprocess the image
151
+ # img = Image.open(io.BytesIO(file.read()))
152
+ # print(f"Received image: {img.size}")
153
+ # img_array = preprocess_image(img)
154
+
155
+ # # Simulate prediction delay (e.g., processing the image)
156
+ # time.sleep(2) # Simulating a delay
157
+
158
+ # # Make prediction
159
+ # predictions = model.predict(img_array)
160
+ # predicted_class_index = np.argmax(predictions, axis=1)[0]
161
+ # confidence_level = round(np.max(predictions) * 100, 2)
162
+
163
+
164
+ # labels = {0: 'Aardvark-LC', 1: 'African Elephant-EN', 2: 'Alligator-LC', 3: 'Alpaca-LC', 4: 'Anaconda-LC', 5: 'Arctic Fox-VU', 6: 'Armadillo-LC', 7: 'Axolotl-CR', 8: 'Baboon-LC', 9: 'Badger-LC', 10: 'Bald Eagle-LC', 11: 'Barracuda-LC', 12: 'Bat-LC', 13: 'Bison-NT', 14: 'Black Bear-LC', 15: 'Blue Jay-LC', 16: 'Boa Constrictor-LC', 17: 'Bonobo-EN', 18: 'Buffalo-LC', 19: 'Butterfly-LC', 20: 'Caiman-LC', 21: 'Camel-LC', 22: 'Capybara-LC', 23: 'Caracal-LC', 24: 'Cheetah-VU', 25: 'Chimpanzee-EN', 26: 'Cobra-LC', 27: 'Cockatoo-LC', 28: 'Coral-CR', 29: 'Coyote-LC', 30: 'Crocodile-LC', 31: 'Deer-LC', 32: 'Dingo-LC', 33: 'Dodo-EX', 34: 'Dolphin-LC', 35: 'Domestic Cat-LC', 36: 'Donkey-LC', 37: 'Dragonfly-LC', 38: 'Duck-LC', 39: 'Dugong-VU', 40: 'Eagle-LC', 41: 'Earthworm-LC', 42: 'Echidna-LC', 43: 'Eel-LC', 44: 'Elephant-EN', 45: 'Elk-LC', 46: 'Emu-LC', 47: 'Falcon-LC', 48: 'Ferret-EN', 49: 'Finch-LC', 50: 'Firefly-LC', 51: 'Fish-LC', 52: 'Flamingo-LC', 53: 'Fossa-VU', 54: 'Fox-LC', 55: 'Frog-LC', 56: 'Galápagos Tortoise-VU', 57: 'Gazelle-VU', 58: 'Gecko-LC', 59: 'Gibbon-EN', 60: 'Giraffe-VU', 61: 'Goat-LC', 62: 'Goose-LC', 63: 'Gorilla-CR', 64: 'Grasshopper-LC', 65: 'Great White Shark-VU', 66: 'Green Anaconda-LC', 67: 'Grizzly Bear-LC', 68: 'Hammerhead Shark-CR', 69: 'Hamster-LC', 70: 'Hare-LC', 71: 'Hawk-LC', 72: 'Hedgehog-LC', 73: 'Hermit Crab-LC', 74: 'Hippopotamus-VU', 75: 'Honeybee-LC', 76: 'Hornbill-NT', 77: 'Horse-LC', 78: 'Hummingbird-LC', 79: 'Ibex-LC', 80: 'Ibis-LC', 81: 'Indian Cobra-LC', 82: 'Indian Elephant-EN', 83: 'Indian Star Tortoise-VU', 84: 'Indian Wolf-EN', 85: 'Jackal-LC', 86: 'Jaguar-NT', 87: 'Japanese Beetle-LC', 88: 'Jellyfish-LC', 89: 'Kangaroo-LC', 90: 'King Cobra-VU', 91: 'Kingfisher-LC', 92: 'Kiwi-EN', 93: 'Koala-VU', 94: 'Komodo Dragon-EN', 95: 'Ladybug-LC', 96: 'Lemming-LC', 97: 'Lemur-CR', 98: 'Leopard-VU', 99: 'Lion-VU', 100: 'Lizard-LC', 101: 'Llama-LC', 102: 'Lobster-LC', 103: 'Lynx-LC', 104: 'Macaw-EN', 105: 'Magpie-LC', 106: 'Manatee-VU', 107: 'Mandrill-VU', 108: 'Mantis Shrimp-LC', 109: 'Meerkat-LC', 110: 'Mole-LC', 111: 'Moose-LC', 112: 'Moray Eel-LC', 113: 'Mountain Lion-LC', 114: 'Musk Ox-LC', 115: 'Nandu Rhea-LC', 116: 'Narwhal-NT', 117: 'Newt-LC', 118: 'Nightingale-LC', 119: 'Octopus-LC', 120: 'Okapi-EN', 121: 'Opossum-LC', 122: 'Orangutan-CR', 123: 'Ostrich-LC', 124: 'Otter-VU', 125: 'Owl-LC', 126: 'Ox-LC', 127: 'Panda-VU', 128: 'Panther-NT', 129: 'Parrot-LC', 130: 'Peacock-LC', 131: 'Pelican-LC', 132: 'Penguin-NT', 133: 'Pigeon-LC', 134: 'Piranha-LC', 135: 'Platypus-LC', 136: 'Polar Bear-VU', 137: 'Porcupine-LC', 138: 'Possum-LC', 139: 'Praying Mantis-LC', 140: 'Puffin-LC', 141: 'Python-LC', 142: 'Quail-LC', 143: 'Quetzal-NT', 144: 'Quokka-LC', 145: 'Quoll-NT', 146: 'Rabbit-LC', 147: 'Raccoon-LC', 148: 'Ram-LC', 149: 'Rat-LC', 150: 'Raven-LC', 151: 'Red Panda-EN', 152: 'Reindeer-VU', 153: 'Rhinoceros-CR', 154: 'Roadrunner-LC', 155: 'Salamander-LC', 156: 'Scorpion-LC', 157: 'Sea Lion-LC', 158: 'Seahorse-LC', 159: 'Shark-VU', 160: 'Sheep-LC', 161: 'Skunk-LC', 162: 'Sloth-VU', 163: 'Snail-LC', 164: 'Snake-LC', 165: 'Snow Leopard-VU', 166: 'Sparrow-LC', 167: 'Spider-LC', 168: 'Squirrel-LC', 169: 'Starfish-LC', 170: 'Stork-LC', 171: 'Swan-LC', 172: 'Tamarin-EN', 173: 'Tapir-VU', 174: 'Tasmanian Devil-EN', 175: 'Termite-LC', 176: 'Thorny Devil-LC', 177: 'Tiger-EN', 178: 'Toad-LC', 179: 'Toucan-LC', 180: 'Tuna-LC', 181: 'Turkey-LC', 182: 'Turtle-VU', 183: 'Uakari-VU', 184: 'Umbrellabird-VU', 185: 'Urchin-LC', 186: 'Uromastyx-LC', 187: 'Vampire Bat-LC', 188: 'Vaquita-CR', 189: 'Vervet Monkey-LC', 190: 'Vulture-LC', 191: 'Wallaby-LC', 192: 'Walrus-VU', 193: 'Warthog-LC', 194: 'Weasel-LC', 195: 'Whale-EN', 196: 'White Tiger-EN', 197: 'Wild Cat-VU', 198: 'Wolf-VU', 199: 'Wolverine-LC', 200: 'Wombat-LC', 201: 'Woodpecker-LC', 202: 'X-ray Tetra-LC', 203: 'Xenopus-LC', 204: 'Yak-LC', 205: 'Yellowjacket-LC', 206: 'Zebra Finch-LC', 207: 'Zebra-NT', 208: 'Zebu-LC', 209: 'Zorilla-LC'}
165
+ # # Replace with your model's labels
166
+
167
+ # predicted_class = labels.get(predicted_class_index, "Unknown")
168
+ # conservation_status= get_conservation_status(predicted_class)
169
+ # predicted_class = predicted_class.split('-')[0] # Remove the conservation status from the class name
170
+ # print(f"Prediction: {predicted_class}, Confidence: {confidence_level}%")
171
+
172
+ # # Generate explanation using Gemini AI
173
+ # explanation = generate_explanation(predicted_class)
174
+
175
+ # # Store the result in the in-memory dictionary
176
+ # prediction_id = str(time.time()) # Unique ID for the request
177
+
178
+ # prediction_results[prediction_id] = {
179
+ # "predicted_class": predicted_class,
180
+ # "conservation_status": conservation_status,
181
+ # "confidence_level": confidence_level,
182
+ # "explanation": explanation
183
+ # }
184
+
185
+ # print(f"Prediction ID: {prediction_id}, Result: {prediction_results[prediction_id]}")
186
+ # # Return the prediction ID to be used for GET request later
187
+ # return jsonify({"prediction_id": prediction_id}), 200
188
+
189
+ # except Exception as e:
190
+ # # Include the traceback in the error response
191
+ # error_message = traceback.format_exc()
192
+ # print(error_message) # Print in the server logs
193
+ # return jsonify({"error": f"Error during prediction: {error_message}"}), 500
194
+
195
+ # # Define route for retrieving predictions (GET)
196
+ # @app.route("/get_prediction/<prediction_id>", methods=["GET"])
197
+ # def get_prediction(prediction_id):
198
+ # print(f"Fetching prediction result for ID: {prediction_id}")
199
+ # result = prediction_results.get(prediction_id)
200
+ # if result:
201
+ # return jsonify(result)
202
+ # else:
203
+ # print(f"No result found for ID: {prediction_id}")
204
+ # return jsonify({"error": "Prediction not found or still processing"}), 404
205
+
206
+ # if __name__ == "__main__":
207
+ # app.run(host='0.0.0.0', port=7860,debug=True)
208
+
209
+
210
+
211
+
212
+
213
  import os
214
  from flask import Flask, request, jsonify
215
  from flask_cors import CORS # Import CORS for cross-origin access
216
  import tensorflow as tf
217
  from tensorflow.keras.preprocessing import image
218
  import numpy as np
 
219
  import io
220
  from PIL import Image
221
  import time
 
223
  import google.generativeai as genai # Google Gemini AI
224
  import re
225
  from huggingface_hub import hf_hub_download
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
  # Create Flask app
228
  app = Flask(__name__)
 
234
  genai.configure(api_key="AIzaSyD0M3hdjekk6w_b9WXXb0T_qLAS0MY5iDQ") # Replace with your actual API key
235
  model_gemini = genai.GenerativeModel("gemini-1.5-flash") # Use a fast Gemini AI model
236
 
237
+ # In-memory store to simulate prediction processing
238
+ prediction_results = {}
239
+
240
  # Define preprocessing function for the uploaded image
241
  def preprocess_image(img):
242
+ try:
243
+ img = img.resize((224, 224)) # Resize image to match model input size
244
+ img_array = np.array(img)
245
+ img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
246
+ img_array = tf.keras.applications.efficientnet.preprocess_input(img_array) # Preprocess for EfficientNet
247
+ return img_array
248
+ except Exception as e:
249
+ print(f"Error during image preprocessing: {e}")
250
+ raise
251
 
252
+ # Clean Gemini AI explanation
253
  def clean_explanation(text):
254
  """Remove unnecessary formatting such as * and excess whitespace."""
255
  text = re.sub(r'\*+', '', text) # Remove asterisks
256
  text = re.sub(r'\s+', ' ', text).strip() # Normalize spaces
257
  return text
258
 
259
+ # Generate explanation using Gemini AI
260
  def generate_explanation(predicted_class):
261
  try:
262
  prompt = f"Get instant feedback with the predicted animal name {predicted_class} along with relevant details like its habitat, diet. Provide a brief yet informative explanation, including unique characteristics, scientific name, and any interesting facts. Keep the response engaging and easy to understand for general users. Avoid technical jargon, but ensure accuracy. Limit the response to 5-6 sentences."
 
267
  print(f"Error generating explanation: {e}")
268
  return f"This is a {predicted_class}."
269
 
270
+ # Get conservation status
 
271
  def get_conservation_status(class_name):
272
  """
273
  Extracts and returns the conservation status from the given class name.
 
298
 
299
  return "Unknown conservation status"
300
 
301
+ # Load model from Hugging Face Hub
302
+ def load_model_from_huggingface():
303
+ cache_dir = "/tmp/huggingface" # Define a writable cache directory
304
+ os.makedirs(cache_dir, exist_ok=True) # Ensure it exists
305
+
306
+ print("Downloading model from Hugging Face Hub...")
307
+ try:
308
+ model_path = hf_hub_download(
309
+ repo_id="anilkumar5590/image-classification-viit",
310
+ filename="model.keras", # Adjust the filename based on your model
311
+ cache_dir=cache_dir # Use the custom directory
312
+ )
313
+ print(f"Model downloaded successfully at: {model_path}")
314
+ model = tf.keras.models.load_model(model_path)
315
+ print("Model loaded successfully!")
316
+ return model
317
+ except Exception as e:
318
+ print(f"Error loading model: {e}")
319
+ raise
320
+
321
+ # Load model at startup
322
+ model = load_model_from_huggingface()
323
 
324
  # Define route for predictions (POST)
325
  @app.route("/predict", methods=["POST"])
326
  def predict():
327
  print("Request Files:", request.files)
 
328
  file = request.files.get('file')
329
 
330
  if not file:
331
+ print("No file part in the request")
332
  return jsonify({"error": "No file part"}), 400
333
 
334
  try:
335
  # Open and preprocess the image
336
+ print("Opening image...")
337
  img = Image.open(io.BytesIO(file.read()))
338
  print(f"Received image: {img.size}")
339
  img_array = preprocess_image(img)
340
+ print("Image preprocessed successfully")
 
 
341
 
342
  # Make prediction
343
+ print("Making prediction...")
344
  predictions = model.predict(img_array)
345
+ print("Prediction completed")
346
+
347
+ # Process prediction results
348
  predicted_class_index = np.argmax(predictions, axis=1)[0]
349
  confidence_level = round(np.max(predictions) * 100, 2)
350
 
351
+ # Define labels (replace with your model's labels)
352
+ labels = {
353
+ 0: 'Aardvark-LC', 1: 'African Elephant-EN', 2: 'Alligator-LC', 3: 'Alpaca-LC', 4: 'Anaconda-LC',
354
+ # Add the rest of your labels here...
355
+ }
356
 
 
 
 
357
  predicted_class = labels.get(predicted_class_index, "Unknown")
358
+ conservation_status = get_conservation_status(predicted_class)
359
  predicted_class = predicted_class.split('-')[0] # Remove the conservation status from the class name
360
  print(f"Prediction: {predicted_class}, Confidence: {confidence_level}%")
361
 
 
363
  explanation = generate_explanation(predicted_class)
364
 
365
  # Store the result in the in-memory dictionary
366
+ prediction_id = str(time.time())) # Unique ID for the request
 
367
  prediction_results[prediction_id] = {
368
  "predicted_class": predicted_class,
369
  "conservation_status": conservation_status,
370
  "confidence_level": confidence_level,
371
  "explanation": explanation
372
  }
 
373
  print(f"Prediction ID: {prediction_id}, Result: {prediction_results[prediction_id]}")
 
374
  return jsonify({"prediction_id": prediction_id}), 200
375
 
376
  except Exception as e:
377
+ print(f"Error during prediction: {e}")
378
+ print(traceback.format_exc())
379
+ return jsonify({"error": f"Error during prediction: {e}"}), 500
 
380
 
381
  # Define route for retrieving predictions (GET)
382
  @app.route("/get_prediction/<prediction_id>", methods=["GET"])
 
389
  print(f"No result found for ID: {prediction_id}")
390
  return jsonify({"error": "Prediction not found or still processing"}), 404
391
 
392
+ # Run the Flask app
393
  if __name__ == "__main__":
394
+ app.run(host='0.0.0.0', port=7860, debug=True)