ciaochris commited on
Commit
34dda42
·
verified ·
1 Parent(s): 57ee5cb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -0
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ import base64
4
+ import logging
5
+ from typing import Dict, Any
6
+
7
+ from dotenv import load_dotenv
8
+ from flask import Flask, request, jsonify
9
+ from huggingface_hub import login
10
+ import requests
11
+ from PIL import Image
12
+ from werkzeug.utils import secure_filename
13
+
14
+ # Configure logging
15
+ logging.basicConfig(level=logging.INFO)
16
+ logger = logging.getLogger(__name__)
17
+
18
+ # Load environment variables
19
+ load_dotenv()
20
+
21
+ # Initialize Flask app
22
+ app = Flask(__name__)
23
+
24
+ # Hugging Face and Groq API configuration
25
+ HUGGINGFACE_TOKEN = os.environ.get("HUGGINGFACE_TOKEN")
26
+ GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
27
+ GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
28
+
29
+ # Login to Hugging Face
30
+ if HUGGINGFACE_TOKEN:
31
+ login(HUGGINGFACE_TOKEN)
32
+ else:
33
+ logger.warning("HUGGINGFACE_TOKEN not set. Some features may be limited.")
34
+
35
+ # Define allowed file extensions
36
+ ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
37
+
38
+ def allowed_file(filename: str) -> bool:
39
+ return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
40
+
41
+ def groq_process(image: Image.Image) -> Dict[str, Any]:
42
+ """
43
+ Process the image using Groq's API for medical image analysis.
44
+ """
45
+ headers = {
46
+ "Authorization": f"Bearer {GROQ_API_KEY}",
47
+ "Content-Type": "application/json"
48
+ }
49
+
50
+ # Convert image to base64
51
+ buffered = io.BytesIO()
52
+ image.save(buffered, format="PNG")
53
+ img_str = base64.b64encode(buffered.getvalue()).decode()
54
+
55
+ payload = {
56
+ "model": "mixtral-8x7b-32768",
57
+ "messages": [
58
+ {"role": "system", "content": "You are an AI trained to analyze medical images. Provide a detailed analysis of the image, noting any abnormalities or potential areas of concern. Remember to state that this is an AI analysis and should be reviewed by a medical professional."},
59
+ {"role": "user", "content": f"Analyze this medical image in detail: data:image/png;base64,{img_str}"}
60
+ ],
61
+ "max_tokens": 500
62
+ }
63
+
64
+ try:
65
+ response = requests.post(GROQ_API_URL, headers=headers, json=payload, timeout=30)
66
+ response.raise_for_status()
67
+ return {"success": True, "analysis": response.json()['choices'][0]['message']['content']}
68
+ except requests.exceptions.RequestException as e:
69
+ logger.error(f"Error in Groq API request: {str(e)}")
70
+ return {"success": False, "error": "Error in processing the image"}
71
+
72
+ def analyze_medical_image(image_file) -> Dict[str, Any]:
73
+ """
74
+ Analyze a medical image file.
75
+ """
76
+ try:
77
+ image = Image.open(image_file)
78
+ analysis_result = groq_process(image)
79
+ return analysis_result
80
+ except Exception as e:
81
+ logger.error(f"Error in image analysis: {str(e)}")
82
+ return {"success": False, "error": "Error in analyzing the image"}
83
+
84
+ @app.route('/analyze-medical-image', methods=['POST'])
85
+ def analyze_route():
86
+ """
87
+ Route to handle medical image analysis requests.
88
+ """
89
+ if 'image' not in request.files:
90
+ return jsonify({"error": "No image file provided"}), 400
91
+
92
+ file = request.files['image']
93
+ if file.filename == '':
94
+ return jsonify({"error": "No selected file"}), 400
95
+
96
+ if file and allowed_file(file.filename):
97
+ filename = secure_filename(file.filename)
98
+ analysis_result = analyze_medical_image(file)
99
+
100
+ if analysis_result['success']:
101
+ return jsonify({
102
+ "filename": filename,
103
+ "analysis": analysis_result['analysis'],
104
+ "disclaimer": "This analysis is provided by an AI system and should be reviewed by a qualified medical professional. It is not a substitute for professional medical advice, diagnosis, or treatment."
105
+ })
106
+ else:
107
+ return jsonify({"error": analysis_result['error']}), 500
108
+ else:
109
+ return jsonify({"error": "Invalid file type. Allowed types are png, jpg, jpeg"}), 400
110
+
111
+ @app.route('/', methods=['GET'])
112
+ def index():
113
+ return "Medical Image Analysis Tool - For research and educational purposes only. Not for clinical use."
114
+
115
+ if __name__ == "__main__":
116
+ app.run(host="0.0.0.0", port=7860)