Spaces:
Runtime error
Runtime error
# 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() | |