File size: 5,289 Bytes
d08b0e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a704ca8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
    }


@app.route('/')
def index():
    initial_data = get_demo_perfume_data()
    return render_template('index.html', initial_data=initial_data, base_aromas_ordered=BASE_AROMA_NAMES_ORDER)


@app.route('/analyze_image', methods=['POST'])
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