Update app.py
Browse files
app.py
CHANGED
|
@@ -8,7 +8,10 @@ from groq import Groq
|
|
| 8 |
from deep_translator import GoogleTranslator
|
| 9 |
import os
|
| 10 |
from dotenv import load_dotenv
|
|
|
|
|
|
|
| 11 |
load_dotenv()
|
|
|
|
| 12 |
app = Flask(__name__)
|
| 13 |
|
| 14 |
# Load the model for disease detection
|
|
@@ -18,9 +21,8 @@ model = load_model(MODEL_PATH, compile=False)
|
|
| 18 |
# Load the labels for disease detection
|
| 19 |
class_names = open("s3/labels.txt", "r").readlines()
|
| 20 |
|
| 21 |
-
# Medication suggestions
|
| 22 |
-
medications =
|
| 23 |
-
"1 LUMPY SKIN": "Tips for Lumpy Skin Disease (LSD):"
|
| 24 |
"Isolation: Immediately isolate affected animals to prevent the spread of the disease to other livestock."
|
| 25 |
"Hygiene: Maintain a clean environment by disinfecting animal housing, feeding equipment, and water troughs regularly."
|
| 26 |
"Supportive Care: Ensure animals are well-fed with a nutritious diet to strengthen their immune systems. Providing fresh, clean water is essential."
|
|
@@ -58,12 +60,14 @@ medications = {
|
|
| 58 |
"Monitor: Watch for early signs and isolate any affected animals."
|
| 59 |
}
|
| 60 |
|
| 61 |
-
#
|
| 62 |
-
API_KEY = "
|
|
|
|
|
|
|
|
|
|
| 63 |
client = Groq(api_key=API_KEY)
|
| 64 |
|
| 65 |
def translate_text(text, target_language):
|
| 66 |
-
"""Translates text to the specified target language."""
|
| 67 |
return GoogleTranslator(source="auto", target=target_language).translate(text)
|
| 68 |
|
| 69 |
@app.route("/")
|
|
@@ -76,15 +80,10 @@ def rearing_guidance():
|
|
| 76 |
|
| 77 |
@app.route('/result', methods=['POST'])
|
| 78 |
def result():
|
| 79 |
-
# Get user input
|
| 80 |
animal_type = request.form['animal_type']
|
| 81 |
number_of_animals = int(request.form['number_of_animals'])
|
| 82 |
-
|
| 83 |
-
# Map animal type and count to required features
|
| 84 |
area_size, feed_type, feed_quantity, cost_in_inr, water_supply, hygiene_tips, seasonal_tips = get_animal_data(animal_type, number_of_animals)
|
| 85 |
|
| 86 |
-
# Translate the content to the selected language (if needed here, otherwise handled in JS)
|
| 87 |
-
|
| 88 |
return render_template('s1.html',
|
| 89 |
area_size=area_size,
|
| 90 |
feed_type=feed_type,
|
|
@@ -94,207 +93,72 @@ def result():
|
|
| 94 |
hygiene_tips=hygiene_tips,
|
| 95 |
seasonal_tips=seasonal_tips,
|
| 96 |
animal_type=animal_type,
|
| 97 |
-
number_of_animals=number_of_animals
|
| 98 |
-
)
|
| 99 |
|
| 100 |
-
# Helper function to map animal type and count to required values
|
| 101 |
def get_animal_data(animal_type, count):
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
cost_in_inr = 7483.52 * count
|
| 115 |
-
water_supply = 81.23 * count
|
| 116 |
-
hygiene_tips = 'Ensure proper ventilation'
|
| 117 |
-
seasonal_tips = 'Summer: Provide shade and cool water, Winter: Provide shelter, Rainy: Dry bedding is essential.'
|
| 118 |
-
elif animal_type == 'Pig':
|
| 119 |
-
area_size = 15.25 * count
|
| 120 |
-
feed_type = 'Concentrates'
|
| 121 |
-
feed_quantity = 5.15 * count
|
| 122 |
-
cost_in_inr = 4989.25 * count
|
| 123 |
-
water_supply = 50.60 * count
|
| 124 |
-
hygiene_tips = 'Use disinfectants weekly'
|
| 125 |
-
seasonal_tips = 'Summer: Keep cool and dry, Winter: Ensure warmth, Rainy: Keep pens dry.'
|
| 126 |
-
elif animal_type == 'Goat':
|
| 127 |
-
area_size = 10.21 * count
|
| 128 |
-
feed_type = 'Green Feed'
|
| 129 |
-
feed_quantity = 3.25 * count
|
| 130 |
-
cost_in_inr = 3325.60 * count
|
| 131 |
-
water_supply = 20.55 * count
|
| 132 |
-
hygiene_tips = 'Provide clean bedding'
|
| 133 |
-
seasonal_tips = 'Summer: Provide fresh water and shade, Winter: Ensure dry and warm shelter, Rainy: Avoid damp areas.'
|
| 134 |
-
elif animal_type == 'Sheep':
|
| 135 |
-
area_size = 12.50 * count
|
| 136 |
-
feed_type = 'Green Feed'
|
| 137 |
-
feed_quantity = 4.75 * count
|
| 138 |
-
cost_in_inr = 3741.75 * count
|
| 139 |
-
water_supply = 25.80 * count
|
| 140 |
-
hygiene_tips = 'Check for parasites regularly'
|
| 141 |
-
seasonal_tips = 'Summer: Provide plenty of water, Winter: Keep warm with shelter, Rainy: Keep dry and prevent wool rot.'
|
| 142 |
-
elif animal_type == 'Poultry':
|
| 143 |
-
area_size = 1.5 * count
|
| 144 |
-
feed_type = 'Grain-based Feed'
|
| 145 |
-
feed_quantity = 0.25 * count
|
| 146 |
-
cost_in_inr = 120 * count
|
| 147 |
-
water_supply = 0.5 * count
|
| 148 |
-
hygiene_tips = 'Keep the coop clean and free from pests'
|
| 149 |
-
seasonal_tips = 'Summer: Ensure proper ventilation, Winter: Provide heat and protection, Rainy: Keep the coop dry.'
|
| 150 |
-
elif animal_type == 'Bee Hiving':
|
| 151 |
-
area_size = 10.25 # In square feet, for a beekeeping area
|
| 152 |
-
feed_type = 'Sugar Syrup'
|
| 153 |
-
feed_quantity = 0.5 * count # For hives
|
| 154 |
-
cost_in_inr = 1500.55 * count # Cost per hive
|
| 155 |
-
water_supply = 0.25 * count # Water requirement per hive
|
| 156 |
-
hygiene_tips = 'Check for pests like mites and wax moths'
|
| 157 |
-
seasonal_tips = 'Summer: Provide ample water sources, Winter: Ensure the bees have enough food stores, Rainy: Avoid disturbances.'
|
| 158 |
-
elif animal_type == 'Sericulture':
|
| 159 |
-
area_size = 4.85 * count # In square feet, for silkworms
|
| 160 |
-
feed_type = 'Mulberry Leaves'
|
| 161 |
-
feed_quantity = 0.1 * count # Per silkworm
|
| 162 |
-
cost_in_inr = 198.25 * count # Cost per silkworm
|
| 163 |
-
water_supply = 0.2 * count # Water per silkworm
|
| 164 |
-
hygiene_tips = 'Maintain clean environment, avoid humidity'
|
| 165 |
-
seasonal_tips = 'Summer: Maintain cool and dry conditions, Winter: Keep warm, Rainy: Ensure adequate airflow.'
|
| 166 |
|
| 167 |
-
return area_size, feed_type, feed_quantity, cost_in_inr, water_supply, hygiene_tips, seasonal_tips
|
| 168 |
@app.route("/ai-chatbot")
|
| 169 |
def ai_chatbot():
|
| 170 |
return render_template("s2.html")
|
|
|
|
| 171 |
@app.route("/chat", methods=["POST"])
|
| 172 |
def chat():
|
| 173 |
data = request.json
|
| 174 |
user_message = data.get("message")
|
| 175 |
target_language = data.get("language", "en")
|
| 176 |
-
|
| 177 |
try:
|
| 178 |
-
# Translate user input to English
|
| 179 |
user_message_en = translate_text(user_message, "en")
|
| 180 |
-
|
| 181 |
-
# Call Groq API
|
| 182 |
response = client.chat.completions.create(
|
| 183 |
messages=[{"role": "user", "content": user_message_en}],
|
| 184 |
model="llama-3.3-70b-versatile"
|
| 185 |
)
|
| 186 |
-
|
| 187 |
bot_response_en = response.choices[0].message.content
|
| 188 |
-
|
| 189 |
-
# Translate back
|
| 190 |
bot_response_translated = translate_text(bot_response_en, target_language)
|
| 191 |
-
|
| 192 |
return jsonify({"response": bot_response_translated})
|
| 193 |
-
|
| 194 |
except Exception as e:
|
| 195 |
-
import traceback
|
| 196 |
-
print("Chatbot error:", e)
|
| 197 |
-
traceback.print_exc()
|
| 198 |
return jsonify({"response": f"Error: {str(e)}"}), 500
|
| 199 |
|
| 200 |
-
|
| 201 |
@app.route("/disease-detection", methods=["GET", "POST"])
|
| 202 |
def disease_detection():
|
| 203 |
-
prediction = None
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
error = None
|
| 208 |
-
|
| 209 |
-
if request.method == "POST":
|
| 210 |
-
# Check if file is sent as a Blob (from JavaScript FormData)
|
| 211 |
-
if 'file' in request.files:
|
| 212 |
-
file = request.files["file"]
|
| 213 |
-
if file.filename == "":
|
| 214 |
-
error = "No selected file."
|
| 215 |
-
else:
|
| 216 |
-
try:
|
| 217 |
-
# Read image data from the FileStorage object
|
| 218 |
-
image_bytes = file.read()
|
| 219 |
-
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
| 220 |
-
|
| 221 |
-
# Resize the image to 224x224 and crop from the center
|
| 222 |
-
size = (224, 224)
|
| 223 |
-
image = ImageOps.fit(image, size, Image.Resampling.LANCZOS)
|
| 224 |
-
|
| 225 |
-
# Convert image to numpy array and normalize
|
| 226 |
-
image_array = np.asarray(image)
|
| 227 |
-
normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1
|
| 228 |
-
|
| 229 |
-
# Create the array of the right shape to feed into the keras model
|
| 230 |
-
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
|
| 231 |
-
data[0] = normalized_image_array
|
| 232 |
-
|
| 233 |
-
# Predict the model
|
| 234 |
-
prediction_raw = model.predict(data)
|
| 235 |
-
index = np.argmax(prediction_raw)
|
| 236 |
-
# Ensure class_name is cleaned of potential newlines/spaces from labels.txt
|
| 237 |
-
class_name = class_names[index].strip()
|
| 238 |
-
confidence_score = prediction_raw[0][index] * 100 # Convert to percentage
|
| 239 |
-
|
| 240 |
-
prediction = f"Predicted Disease: {class_name}"
|
| 241 |
-
confidence = f"{confidence_score:.2f}%"
|
| 242 |
-
|
| 243 |
-
# Suggest medication if disease detected
|
| 244 |
-
medication = medications.get(class_name, None)
|
| 245 |
-
|
| 246 |
-
# Convert processed image to base64 for rendering on the webpage
|
| 247 |
-
img_byte_array = io.BytesIO()
|
| 248 |
-
# It's better to save the *processed* image to display, if you want
|
| 249 |
-
# to show what the model actually saw. Otherwise, use the original image_bytes
|
| 250 |
-
image.save(img_byte_array, format="PNG")
|
| 251 |
-
img_data = base64.b64encode(img_byte_array.getvalue()).decode("utf-8")
|
| 252 |
-
|
| 253 |
-
except Exception as e:
|
| 254 |
-
error = f"Error processing uploaded image: {e}"
|
| 255 |
-
# This handles the case if a previous approach sent a data URL directly in a form field.
|
| 256 |
-
# However, the JS change in the previous response sends a Blob via request.files
|
| 257 |
-
# so this block might be less frequently hit but good for robustness.
|
| 258 |
-
elif 'file' in request.form and request.form['file'].startswith('data:image'):
|
| 259 |
-
image_data_url = request.form['file']
|
| 260 |
try:
|
| 261 |
-
|
| 262 |
-
image_bytes = base64.b64decode(encoded)
|
| 263 |
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
| 264 |
-
|
| 265 |
-
# Resize and preprocess just like the file upload
|
| 266 |
-
size = (224, 224)
|
| 267 |
-
image = ImageOps.fit(image, size, Image.Resampling.LANCZOS)
|
| 268 |
image_array = np.asarray(image)
|
| 269 |
normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1
|
| 270 |
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
|
| 271 |
data[0] = normalized_image_array
|
| 272 |
-
|
| 273 |
prediction_raw = model.predict(data)
|
| 274 |
index = np.argmax(prediction_raw)
|
| 275 |
class_name = class_names[index].strip()
|
| 276 |
confidence_score = prediction_raw[0][index] * 100
|
| 277 |
-
|
| 278 |
prediction = f"Predicted Disease: {class_name}"
|
| 279 |
confidence = f"{confidence_score:.2f}%"
|
| 280 |
-
medication = medications.get(class_name
|
| 281 |
-
|
| 282 |
img_byte_array = io.BytesIO()
|
| 283 |
-
image.save(img_byte_array, format="PNG")
|
| 284 |
img_data = base64.b64encode(img_byte_array.getvalue()).decode("utf-8")
|
| 285 |
-
|
| 286 |
except Exception as e:
|
| 287 |
-
error = f"Error processing image
|
| 288 |
else:
|
| 289 |
-
error = "No
|
| 290 |
-
|
| 291 |
-
return render_template("s3.html",
|
| 292 |
-
prediction=prediction,
|
| 293 |
-
confidence=confidence,
|
| 294 |
-
medication=medication,
|
| 295 |
-
img_data=img_data,
|
| 296 |
-
error=error)
|
| 297 |
-
|
| 298 |
|
| 299 |
@app.route("/information")
|
| 300 |
def information():
|
|
@@ -314,4 +178,4 @@ def veterinary_map():
|
|
| 314 |
|
| 315 |
if __name__ == "__main__":
|
| 316 |
port = int(os.environ.get("PORT", 7860))
|
| 317 |
-
app.run(host="0.0.0.0", port=port, debug=True)
|
|
|
|
| 8 |
from deep_translator import GoogleTranslator
|
| 9 |
import os
|
| 10 |
from dotenv import load_dotenv
|
| 11 |
+
|
| 12 |
+
# Load environment variables
|
| 13 |
load_dotenv()
|
| 14 |
+
|
| 15 |
app = Flask(__name__)
|
| 16 |
|
| 17 |
# Load the model for disease detection
|
|
|
|
| 21 |
# Load the labels for disease detection
|
| 22 |
class_names = open("s3/labels.txt", "r").readlines()
|
| 23 |
|
| 24 |
+
# Medication suggestions
|
| 25 |
+
medications = "1 LUMPY SKIN": "Tips for Lumpy Skin Disease (LSD):"
|
|
|
|
| 26 |
"Isolation: Immediately isolate affected animals to prevent the spread of the disease to other livestock."
|
| 27 |
"Hygiene: Maintain a clean environment by disinfecting animal housing, feeding equipment, and water troughs regularly."
|
| 28 |
"Supportive Care: Ensure animals are well-fed with a nutritious diet to strengthen their immune systems. Providing fresh, clean water is essential."
|
|
|
|
| 60 |
"Monitor: Watch for early signs and isolate any affected animals."
|
| 61 |
}
|
| 62 |
|
| 63 |
+
# Groq API initialization from .env
|
| 64 |
+
API_KEY = os.getenv("GROQ_API_KEY")
|
| 65 |
+
if not API_KEY:
|
| 66 |
+
raise ValueError("GROQ_API_KEY is missing from the .env file")
|
| 67 |
+
|
| 68 |
client = Groq(api_key=API_KEY)
|
| 69 |
|
| 70 |
def translate_text(text, target_language):
|
|
|
|
| 71 |
return GoogleTranslator(source="auto", target=target_language).translate(text)
|
| 72 |
|
| 73 |
@app.route("/")
|
|
|
|
| 80 |
|
| 81 |
@app.route('/result', methods=['POST'])
|
| 82 |
def result():
|
|
|
|
| 83 |
animal_type = request.form['animal_type']
|
| 84 |
number_of_animals = int(request.form['number_of_animals'])
|
|
|
|
|
|
|
| 85 |
area_size, feed_type, feed_quantity, cost_in_inr, water_supply, hygiene_tips, seasonal_tips = get_animal_data(animal_type, number_of_animals)
|
| 86 |
|
|
|
|
|
|
|
| 87 |
return render_template('s1.html',
|
| 88 |
area_size=area_size,
|
| 89 |
feed_type=feed_type,
|
|
|
|
| 93 |
hygiene_tips=hygiene_tips,
|
| 94 |
seasonal_tips=seasonal_tips,
|
| 95 |
animal_type=animal_type,
|
| 96 |
+
number_of_animals=number_of_animals)
|
|
|
|
| 97 |
|
|
|
|
| 98 |
def get_animal_data(animal_type, count):
|
| 99 |
+
data = {
|
| 100 |
+
'Cow': (19.81, 'Green Feed', 24.85, 6652.15, 68.52, 'Clean barn daily, vaccinate regularly', 'Summer: Provide shade, Winter: Warmth, Rainy: Avoid damp.'),
|
| 101 |
+
'Buffalo': (24.58, 'Dry Feed', 31.45, 7483.52, 81.23, 'Ensure proper ventilation', 'Summer: Shade, Winter: Shelter, Rainy: Dry bedding.'),
|
| 102 |
+
'Pig': (15.25, 'Concentrates', 5.15, 4989.25, 50.60, 'Use disinfectants weekly', 'Summer: Cool & dry, Winter: Warmth, Rainy: Dry pens.'),
|
| 103 |
+
'Goat': (10.21, 'Green Feed', 3.25, 3325.60, 20.55, 'Provide clean bedding', 'Summer: Shade, Winter: Warm shelter, Rainy: Avoid damp.'),
|
| 104 |
+
'Sheep': (12.50, 'Green Feed', 4.75, 3741.75, 25.80, 'Check for parasites', 'Summer: Water, Winter: Shelter, Rainy: Dry conditions.'),
|
| 105 |
+
'Poultry': (1.5, 'Grain-based Feed', 0.25, 120, 0.5, 'Keep coop clean', 'Summer: Ventilation, Winter: Heat, Rainy: Dry coop.'),
|
| 106 |
+
'Bee Hiving': (10.25, 'Sugar Syrup', 0.5, 1500.55, 0.25, 'Check for pests', 'Summer: Water, Winter: Food stores, Rainy: Avoid disturbance.'),
|
| 107 |
+
'Sericulture': (4.85, 'Mulberry Leaves', 0.1, 198.25, 0.2, 'Clean & dry environment', 'Summer: Cool & dry, Winter: Warm, Rainy: Airflow.')
|
| 108 |
+
}
|
| 109 |
+
base_values = data.get(animal_type)
|
| 110 |
+
return tuple(v * count if isinstance(v, (int, float)) else v for v in base_values)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
|
|
|
| 112 |
@app.route("/ai-chatbot")
|
| 113 |
def ai_chatbot():
|
| 114 |
return render_template("s2.html")
|
| 115 |
+
|
| 116 |
@app.route("/chat", methods=["POST"])
|
| 117 |
def chat():
|
| 118 |
data = request.json
|
| 119 |
user_message = data.get("message")
|
| 120 |
target_language = data.get("language", "en")
|
|
|
|
| 121 |
try:
|
|
|
|
| 122 |
user_message_en = translate_text(user_message, "en")
|
|
|
|
|
|
|
| 123 |
response = client.chat.completions.create(
|
| 124 |
messages=[{"role": "user", "content": user_message_en}],
|
| 125 |
model="llama-3.3-70b-versatile"
|
| 126 |
)
|
|
|
|
| 127 |
bot_response_en = response.choices[0].message.content
|
|
|
|
|
|
|
| 128 |
bot_response_translated = translate_text(bot_response_en, target_language)
|
|
|
|
| 129 |
return jsonify({"response": bot_response_translated})
|
|
|
|
| 130 |
except Exception as e:
|
|
|
|
|
|
|
|
|
|
| 131 |
return jsonify({"response": f"Error: {str(e)}"}), 500
|
| 132 |
|
|
|
|
| 133 |
@app.route("/disease-detection", methods=["GET", "POST"])
|
| 134 |
def disease_detection():
|
| 135 |
+
prediction, confidence, medication, img_data, error = None, None, None, None, None
|
| 136 |
+
if request.method == "POST" and 'file' in request.files:
|
| 137 |
+
file = request.files["file"]
|
| 138 |
+
if file.filename:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
try:
|
| 140 |
+
image_bytes = file.read()
|
|
|
|
| 141 |
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
| 142 |
+
image = ImageOps.fit(image, (224, 224), Image.Resampling.LANCZOS)
|
|
|
|
|
|
|
|
|
|
| 143 |
image_array = np.asarray(image)
|
| 144 |
normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1
|
| 145 |
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
|
| 146 |
data[0] = normalized_image_array
|
|
|
|
| 147 |
prediction_raw = model.predict(data)
|
| 148 |
index = np.argmax(prediction_raw)
|
| 149 |
class_name = class_names[index].strip()
|
| 150 |
confidence_score = prediction_raw[0][index] * 100
|
|
|
|
| 151 |
prediction = f"Predicted Disease: {class_name}"
|
| 152 |
confidence = f"{confidence_score:.2f}%"
|
| 153 |
+
medication = medications.get(class_name)
|
|
|
|
| 154 |
img_byte_array = io.BytesIO()
|
| 155 |
+
image.save(img_byte_array, format="PNG")
|
| 156 |
img_data = base64.b64encode(img_byte_array.getvalue()).decode("utf-8")
|
|
|
|
| 157 |
except Exception as e:
|
| 158 |
+
error = f"Error processing image: {e}"
|
| 159 |
else:
|
| 160 |
+
error = "No file selected."
|
| 161 |
+
return render_template("s3.html", prediction=prediction, confidence=confidence, medication=medication, img_data=img_data, error=error)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
|
| 163 |
@app.route("/information")
|
| 164 |
def information():
|
|
|
|
| 178 |
|
| 179 |
if __name__ == "__main__":
|
| 180 |
port = int(os.environ.get("PORT", 7860))
|
| 181 |
+
app.run(host="0.0.0.0", port=port, debug=True)
|