doevent commited on
Commit
d08b0e8
·
verified ·
1 Parent(s): 5d88515

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -0
app.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, jsonify
2
+ from gradio_client import Client, handle_file
3
+ import os
4
+ import json
5
+ import random # For demo data variation
6
+
7
+ app = Flask(__name__)
8
+ app.config['UPLOAD_FOLDER'] = 'uploads'
9
+ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB max upload size
10
+ os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
11
+
12
+
13
+ API_TOKEN_HF = os.environ['API_TOKEN_HF']
14
+
15
+ # --- Demo Data ---
16
+ # This will be used for initial page load and if the API call fails or is mocked
17
+ BASE_AROMA_NAMES_ORDER = [ # Keep this order consistent with frontend
18
+ "Rose", "Ocean Breeze", "Fresh Cut Grass", "Lemon Zest", "Lavender",
19
+ "Sweet Orange", "Cool Mint", "Vanilla Bean", "Wild Berry", "Spring Rain"
20
+ ]
21
+
22
+ client = Client("doevent/gemini_others", hf_token=API_TOKEN_HF, download_files="uploads")
23
+
24
+ def get_demo_perfume_data():
25
+ perfume_name = random.choice(["Demo Garden", "Demo Whisper", "Demo Flare", "Demo Dream"])
26
+ slogan = random.choice([
27
+ "Awaken your senses.", "Dare to dream.", "The essence of you.", "An unforgettable journey."
28
+ ])
29
+
30
+ # Create a random set of aromas and doses
31
+ num_active_aromas = random.randint(2, 10)
32
+ active_aromas_sample = random.sample(BASE_AROMA_NAMES_ORDER, num_active_aromas)
33
+
34
+ aromas_data = []
35
+ total_dose_for_demo = 0 # To simulate filling the flask
36
+ for i, name in enumerate(BASE_AROMA_NAMES_ORDER):
37
+ if name in active_aromas_sample and total_dose_for_demo < 0.8: # Limit total demo dose
38
+ dose = round(random.uniform(0.1, 0.3), 2)
39
+ aromas_data.append({"name": name, "dose": dose})
40
+ total_dose_for_demo += dose
41
+ # else: # We can include all aromas with 0 dose if needed by frontend for table population
42
+ # aromas_data.append({"name": name, "dose": 0.0})
43
+
44
+ return {
45
+ "perfume_name": perfume_name,
46
+ "slogan": slogan,
47
+ "aromas": aromas_data # This list might only contain active aromas
48
+ }
49
+
50
+
51
+ @app.route('/')
52
+ def index():
53
+ initial_data = get_demo_perfume_data()
54
+ return render_template('index.html', initial_data=initial_data, base_aromas_ordered=BASE_AROMA_NAMES_ORDER)
55
+
56
+
57
+ @app.route('/analyze_image', methods=['POST'])
58
+ def analyze_image_route():
59
+ if 'imageFile' not in request.files:
60
+ return jsonify({"error": "No image file provided"}), 400
61
+
62
+ file = request.files['imageFile']
63
+ if file.filename == '':
64
+ return jsonify({"error": "No image selected"}), 400
65
+
66
+ if file:
67
+ try:
68
+ filename = "uploaded_image_" + file.filename # Add some uniqueness if needed
69
+ image_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
70
+ file.save(image_path)
71
+
72
+ custom_prompt_for_perfume = (
73
+ "Based on the visual elements, mood, and potential theme of this image, "
74
+ "invent a unique perfume. I need the following information structured as a JSON object:\n"
75
+ "1. 'perfume_name': A creative and fitting name for the perfume.\n"
76
+ "2. 'slogan': A short, catchy slogan for this perfume.\n"
77
+ "3. 'aromas': A list of 2 to 10 base aroma notes. For each note, provide its 'name' "
78
+ f"(chosen from this list: {', '.join(BASE_AROMA_NAMES_ORDER)}, or a very similar common scent if appropriate) "
79
+ "and its 'dose' as a decimal proportion (e.g., 0.3 for 30%). "
80
+ "Ideally, the total dose should be equal to a full bottle of 10.0 for 100%"
81
+ "\nExample of 'aromas' list: [{'name': 'Rose', 'dose': 0.4}, {'name': 'Lavender', 'dose': 0.2}]"
82
+ )
83
+
84
+ api_result_raw = client.predict(
85
+ files_list=[handle_file(image_path)],
86
+ message=custom_prompt_for_perfume,
87
+ model_name="gemini-2.0-flash",
88
+ temperature=0.7,
89
+ max_output_tokens=1024,
90
+ system_prompt_load= "",
91
+ type_mime_name="application/json",
92
+ output_schema=None,
93
+ google_search_opt=False,
94
+ other_options_json=None,
95
+ thinking_mode=False,
96
+ thinking_budget=None,
97
+ api_name="/predict"
98
+ )
99
+
100
+
101
+ os.remove(image_path) # Clean up uploaded file
102
+
103
+ # print("Raw API Result:", api_result_raw)
104
+ api_result_raw = api_result_raw[0]["candidates"][0]["content"]["parts"][0]['text']
105
+ print("Raw API Result:", api_result_raw)
106
+ return api_result_raw
107
+
108
+ except Exception as e:
109
+ print(f"Error during API call or processing: {e}")
110
+ # In case of any error, return demo data for now for frontend testing
111
+ # os.remove(image_path) # Ensure cleanup even on error
112
+ error_data = get_demo_perfume_data()
113
+ error_data["api_error"] = f"An error occurred: {str(e)}. Displaying demo data."
114
+ return jsonify(error_data), 500 # Send 500 to indicate server-side error
115
+
116
+ return jsonify({"error": "Invalid file"}), 400
117
+
118
+
119
+ if __name__ == '__main__':
120
+ app.run(debug=True) # Use a different port if 5000 is common