Spaces:
Running
Running
from flask import Flask, render_template, request, jsonify | |
from gradio_client import Client, handle_file | |
import os | |
import json | |
import random # For demo data variation | |
app = Flask(__name__) | |
app.config['UPLOAD_FOLDER'] = 'uploads' | |
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB max upload size | |
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
API_TOKEN_HF = os.environ['API_TOKEN_HF'] | |
# --- Demo Data --- | |
# This will be used for initial page load and if the API call fails or is mocked | |
BASE_AROMA_NAMES_ORDER = [ # Keep this order consistent with frontend | |
"Rose", "Ocean Breeze", "Fresh Cut Grass", "Lemon Zest", "Lavender", | |
"Sweet Orange", "Cool Mint", "Vanilla Bean", "Wild Berry", "Spring Rain" | |
] | |
client = Client("doevent/gemini_others", hf_token=API_TOKEN_HF, download_files="uploads") | |
def get_demo_perfume_data(): | |
perfume_name = random.choice(["Demo Garden", "Demo Whisper", "Demo Flare", "Demo Dream"]) | |
slogan = random.choice([ | |
"Awaken your senses.", "Dare to dream.", "The essence of you.", "An unforgettable journey." | |
]) | |
# Create a random set of aromas and doses | |
num_active_aromas = random.randint(2, 10) | |
active_aromas_sample = random.sample(BASE_AROMA_NAMES_ORDER, num_active_aromas) | |
aromas_data = [] | |
total_dose_for_demo = 0 # To simulate filling the flask | |
for i, name in enumerate(BASE_AROMA_NAMES_ORDER): | |
if name in active_aromas_sample and total_dose_for_demo < 0.8: # Limit total demo dose | |
dose = round(random.uniform(0.1, 0.3), 2) | |
aromas_data.append({"name": name, "dose": dose}) | |
total_dose_for_demo += dose | |
# else: # We can include all aromas with 0 dose if needed by frontend for table population | |
# aromas_data.append({"name": name, "dose": 0.0}) | |
return { | |
"perfume_name": perfume_name, | |
"slogan": slogan, | |
"aromas": aromas_data # This list might only contain active aromas | |
} | |
def index(): | |
initial_data = get_demo_perfume_data() | |
return render_template('index.html', initial_data=initial_data, base_aromas_ordered=BASE_AROMA_NAMES_ORDER) | |
def analyze_image_route(): | |
if 'imageFile' not in request.files: | |
return jsonify({"error": "No image file provided"}), 400 | |
file = request.files['imageFile'] | |
if file.filename == '': | |
return jsonify({"error": "No image selected"}), 400 | |
if file: | |
try: | |
filename = "uploaded_image_" + file.filename # Add some uniqueness if needed | |
image_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
file.save(image_path) | |
custom_prompt_for_perfume = ( | |
"Based on the visual elements, mood, and potential theme of this image, " | |
"invent a unique perfume. I need the following information structured as a JSON object:\n" | |
"1. 'perfume_name': A creative and fitting name for the perfume.\n" | |
"2. 'slogan': A short, catchy slogan for this perfume.\n" | |
"3. 'aromas': A list of 2 to 10 base aroma notes. For each note, provide its 'name' " | |
f"(chosen from this list: {', '.join(BASE_AROMA_NAMES_ORDER)}, or a very similar common scent if appropriate) " | |
"and its 'dose' as a decimal proportion (e.g., 0.3 for 30%). " | |
"Ideally, the total dose should be equal to a full bottle of 10.0 for 100%" | |
"\nExample of 'aromas' list: [{'name': 'Rose', 'dose': 0.4}, {'name': 'Lavender', 'dose': 0.2}]" | |
) | |
api_result_raw = client.predict( | |
files_list=[handle_file(image_path)], | |
message=custom_prompt_for_perfume, | |
model_name="gemini-2.0-flash", | |
temperature=0.7, | |
max_output_tokens=1024, | |
system_prompt_load= "", | |
type_mime_name="application/json", | |
output_schema=None, | |
google_search_opt=False, | |
other_options_json=None, | |
thinking_mode=False, | |
thinking_budget=None, | |
api_name="/predict" | |
) | |
os.remove(image_path) # Clean up uploaded file | |
# print("Raw API Result:", api_result_raw) | |
api_result_raw = api_result_raw[0]["candidates"][0]["content"]["parts"][0]['text'] | |
print("Raw API Result:", api_result_raw) | |
return api_result_raw | |
except Exception as e: | |
print(f"Error during API call or processing: {e}") | |
# In case of any error, return demo data for now for frontend testing | |
# os.remove(image_path) # Ensure cleanup even on error | |
error_data = get_demo_perfume_data() | |
error_data["api_error"] = f"An error occurred: {str(e)}. Displaying demo data." | |
return jsonify(error_data), 500 # Send 500 to indicate server-side error | |
return jsonify({"error": "Invalid file"}), 400 | |
if __name__ == '__main__': | |
app.run(host="0.0.0.0", port=7860, debug=True) # Use a different port if 5000 is common | |