figh8back's picture
Update app.py
ac13981 verified
# import gradio as gr
# import requests
# from PIL import Image
# import base64
# from io import BytesIO
# import logging
# # Set up logging
# logging.basicConfig(level=logging.DEBUG)
# logger = logging.getLogger(__name__)
# # skin_metrics_url = 'https://huggingface.co/spaces/Fynd/skin-care-recommendation-system/backend/upload'
# # recommendation_url = 'https://huggingface.co/spaces/Fynd/skin-care-recommendation-system/backend/recommend'
# # Define the API endpoints
# skin_metrics_url = 'http://127.0.0.1:5000/upload' # Flask backend URL
# recommendation_url = 'http://127.0.0.1:5000/recommend' # Another backend endpoint
# def capture_face_image(file):
# try:
# if file is None:
# return "Please upload an image", None
# # Open the uploaded image file (directly using the file object passed from Gradio)
# image = Image.open(file)
# # Convert image to base64
# buffered = BytesIO()
# image.save(buffered, format="PNG")
# img_str = base64.b64encode(buffered.getvalue()).decode('utf-8')
# # Send to backend for skin analysis
# try:
# response = requests.put(
# skin_metrics_url,
# json={'file': img_str},
# timeout=10 # Add timeout
# )
# response.raise_for_status() # Raise exception for bad status codes
# skin_data = response.json() # Skin analysis data from backend
# return skin_data, image # Return both the analysis data and image
# except requests.exceptions.RequestException as e:
# logger.error(f"API request failed: {str(e)}")
# return f"Error in skin analysis: {str(e)}", image
# except Exception as e:
# logger.error(f"Image processing error: {str(e)}")
# return f"Error processing image: {str(e)}", None
# def get_recommendations(tone, skin_type, concerns):
# try:
# # Define the full list of features that the model expects (18 in total)
# all_features = [
# 'normal', 'dry', 'oily', 'combination', 'acne', 'sensitive', 'fine lines', 'wrinkles', 'redness',
# 'dull', 'pore', 'pigmentation', 'blackheads', 'whiteheads', 'blemishes', 'dark circles', 'eye bags', 'dark spots'
# ]
# # Prepare the features dict with all the values set to 0 initially
# features_dict = {feature: 0 for feature in all_features}
# # Update the dictionary with features selected by the user
# for concern in concerns:
# if concern in features_dict:
# features_dict[concern] = 1
# # Prepare the data to send to the backend
# data = {
# 'tone': tone,
# 'type': skin_type,
# 'features': features_dict # Send the full features dictionary
# }
# # Log the data being sent to the backend
# logger.info(f"Sending recommendation request with data: {data}")
# # Make a request to the backend for recommendations
# try:
# response = requests.put(
# recommendation_url,
# json=data,
# timeout=10 # Add timeout
# )
# response.raise_for_status()
# # Log the response status code and content
# logger.info(f"Recommendation API response status: {response.status_code}")
# recommendations = response.json() # Receive recommendations from backend
# # Log the recommendations received from the backend
# logger.info(f"Received recommendations: {recommendations}")
# return recommendations # Return the product recommendations
# except requests.exceptions.RequestException as e:
# logger.error(f"Recommendation API request failed: {str(e)}")
# return {"error": f"Error fetching recommendations: {str(e)}"}
# except Exception as e:
# logger.error(f"Recommendation processing error: {str(e)}")
# return {"error": str(e)}
# # Build the Gradio interface
# with gr.Blocks() as demo:
# # Image upload section
# with gr.Row():
# with gr.Column():
# image_input = gr.Image(
# label="Upload Face Image",
# type="filepath", # Change 'file' to 'filepath'
# interactive=True
# )
# submit_button = gr.Button("Analyze Face")
# # Form section
# with gr.Row():
# with gr.Column():
# tone_input = gr.Slider(
# minimum=1,
# maximum=6,
# label="Skin Tone",
# value=5,
# step=1
# )
# skin_type_input = gr.Radio(
# choices=["All", "Oily", "Normal", "Dry"],
# label="Skin Type",
# value="All"
# )
# acne_input = gr.Radio(
# choices=['Low', 'Moderate', 'Severe'],
# label="Acne Severity",
# value="Moderate", # Default selected value
# interactive=True # Make sure interactive is properly set
# )
# concerns_input = gr.CheckboxGroup(
# choices=[
# 'normal', 'dry', 'oily', 'combination', 'acne', 'sensitive', 'fine lines', 'wrinkles', 'redness',
# 'dull', 'pore', 'pigmentation', 'blackheads', 'whiteheads', 'blemishes', 'dark circles', 'eye bags', 'dark spots'
# ],
# label="Skin Concerns"
# )
# form_submit_button = gr.Button("Get Recommendations")
# # Output section
# with gr.Row():
# recommendation_output = gr.JSON(label="Recommendations")
# # Event handlers
# submit_button.click(
# fn=capture_face_image,
# inputs=image_input,
# outputs=[recommendation_output, image_input]
# )
# form_submit_button.click(
# fn=get_recommendations,
# inputs=[tone_input, skin_type_input, concerns_input],
# outputs=recommendation_output
# )
# # Launch the interface
# demo.launch(
# # server_name="127.0.1",
# # server_port=7863,
# debug=True,
# share=True
# )
# gr.close_all()
import os
import threading
import gradio as gr
import requests
from flask import Flask, jsonify
from flask_restful import Api, Resource, reqparse
from PIL import Image
from io import BytesIO
import base64
import logging
# Initialize Flask app
app = Flask(__name__)
api = Api(app)
# Set up logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# Define the model loading and prediction logic (for illustration)
def load_image(img_path):
img = Image.open(img_path)
img_tensor = np.expand_dims(np.array(img), axis=0) # Dummy placeholder for model processing
img_tensor /= 255.0
return img_tensor
def prediction_skin(img_path):
return "Dry_skin" # Placeholder
def prediction_acne(img_path):
return "Low" # Placeholder
# Flask API resources
class SkinMetrics(Resource):
def put(self):
args = img_put_args.parse_args()
file = args['file']
starter = file.find(',')
image_data = file[starter + 1:]
image_data = bytes(image_data, encoding="ascii")
im = Image.open(BytesIO(base64.b64decode(image_data + b'==')))
filename = 'image.png'
file_path = os.path.join('./static', filename)
im.save(file_path)
skin_type = prediction_skin(file_path)
acne_type = prediction_acne(file_path)
return jsonify({'type': skin_type, 'acne': acne_type})
class Recommendation(Resource):
def put(self):
args = rec_args.parse_args()
features = args['features']
tone = args['tone']
skin_type = args['type'].lower()
# Recommendation logic here
return jsonify({'message': 'Recommendation response'})
# Flask API URL arguments
img_put_args = reqparse.RequestParser()
img_put_args.add_argument("file", help="Please provide a valid image file", required=True)
rec_args = reqparse.RequestParser()
rec_args.add_argument("tone", type=int, help="Argument required", required=True)
rec_args.add_argument("type", type=str, help="Argument required", required=True)
rec_args.add_argument("features", type=dict, help="Argument required", required=True)
# Add resources to the Flask app
api.add_resource(SkinMetrics, "/upload")
api.add_resource(Recommendation, "/recommend")
# Gradio frontend code
def capture_face_image(file):
try:
if file is None:
return "Please upload an image", None
image = Image.open(file)
buffered = BytesIO()
image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue()).decode('utf-8')
# Send to backend for skin analysis
response = requests.put(
"http://127.0.0.1:5000/upload",
json={'file': img_str},
timeout=10
)
response.raise_for_status()
skin_data = response.json()
return skin_data, image
except requests.exceptions.RequestException as e:
logger.error(f"API request failed: {str(e)}")
return f"Error in skin analysis: {str(e)}", None
def get_recommendations(tone, skin_type, concerns):
try:
all_features = [
'normal', 'dry', 'oily', 'combination', 'acne', 'sensitive', 'fine lines', 'wrinkles', 'redness',
'dull', 'pore', 'pigmentation', 'blackheads', 'whiteheads', 'blemishes', 'dark circles', 'eye bags', 'dark spots'
]
# Update the features_dict based on selected concerns
features_dict = {feature: 0 for feature in all_features}
for concern in concerns:
if concern in features_dict:
features_dict[concern] = 1
data = {
'tone': tone,
'type': skin_type,
'features': features_dict
}
response = requests.put(
"http://127.0.0.1:5000/recommend",
json=data,
timeout=10
)
response.raise_for_status()
recommendations = response.json()
# Generate HTML content for cards (simplified for this example)
product_cards = ""
if recommendations.get("general"):
for category, products in recommendations["general"].items():
for product in products:
card_html = f"""
<div style="border: 1px solid #ddd; padding: 10px; width: calc(33.33% - 20px); text-align: center; margin: 10px; border-radius: 10px; box-sizing: border-box; display: inline-block;">
<img src="{product['img']}" alt="{product['name']}" style="width: 100%; height: auto; border-radius: 10px;">
<h3>{product['name']}</h3>
<p>{product['brand']}</p>
<p><strong>{product['price']}</strong></p>
<a href="{product['url']}" target="_blank" style="display: inline-block; background-color: #1E90FF; color: white; padding: 10px 15px; border-radius: 5px; text-decoration: none;">Buy Now</a>
</div>
"""
product_cards += card_html
grid_html = f"""
<div style="display: flex; flex-wrap: wrap; justify-content: space-around;">
{product_cards}
</div>
"""
return grid_html
except requests.exceptions.RequestException as e:
logger.error(f"Recommendation API request failed: {str(e)}")
return f"Error fetching recommendations: {str(e)}"
# Gradio UI
with gr.Blocks() as demo:
with gr.Row():
image_input = gr.Image(type="filepath")
submit_button = gr.Button("Analyze Face")
with gr.Row():
tone_input = gr.Slider(minimum=1, maximum=6)
skin_type_input = gr.Radio(choices=["All", "Oily", "Normal", "Dry"])
acne_input = gr.Radio(choices=["Low", "Moderate", "Severe"])
concerns_input = gr.CheckboxGroup(choices=all_features)
form_submit_button = gr.Button("Get Recommendations")
recommendation_output = gr.HTML()
submit_button.click(fn=capture_face_image, inputs=image_input, outputs=recommendation_output)
form_submit_button.click(fn=get_recommendations, inputs=[tone_input, skin_type_input, concerns_input], outputs=recommendation_output)
# Function to run Flask app
def run_flask():
app.run(debug=False, use_reloader=False, host="0.0.0.0", port=5000)
# Function to run Gradio app
def run_gradio():
demo.launch(share=True, server_name="0.0.0.0", server_port=7861)
# Run both Flask and Gradio together using threads
if __name__ == "__main__":
flask_thread = threading.Thread(target=run_flask)
gradio_thread = threading.Thread(target=run_gradio)
flask_thread.start()
gradio_thread.start()
flask_thread.join()
gradio_thread.join()