alexander-lazarin commited on
Commit
1b0da9b
·
1 Parent(s): b5d162d

Initial version

Browse files
Files changed (3) hide show
  1. .gitignore +37 -0
  2. app.py +164 -0
  3. requirements.txt +7 -0
.gitignore ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables
2
+ .env
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+ *.so
9
+ .Python
10
+ build/
11
+ develop-eggs/
12
+ dist/
13
+ downloads/
14
+ eggs/
15
+ .eggs/
16
+ lib/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ *.egg-info/
23
+ .installed.cfg
24
+ *.egg
25
+
26
+ # Virtual Environment
27
+ venv/
28
+ ENV/
29
+ env/
30
+ .env/
31
+
32
+ # IDE
33
+ .idea/
34
+ .vscode/
35
+ *.swp
36
+ *.swo
37
+ .DS_Store
app.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import base64
4
+ from typing import List, Tuple, Dict
5
+ import gradio as gr
6
+ import httpx
7
+ from sqlalchemy import create_engine, text
8
+ from dotenv import load_dotenv
9
+ import google.generativeai as genai
10
+
11
+ def get_secret(secret_name, service="", username=""):
12
+ try:
13
+ from google.colab import userdata
14
+ return userdata.get(secret_name)
15
+ except:
16
+ try:
17
+ return os.environ[secret_name]
18
+ except:
19
+ import keyring
20
+ return keyring.get_password(service, username)
21
+
22
+ # Load environment variables
23
+ load_dotenv()
24
+
25
+ # Database configuration
26
+ DB_NAME = "kroyscappingdb"
27
+ DB_USER = "read_only"
28
+ DB_PASSWORD = get_secret('FASHION_PG_PASS')
29
+ DB_HOST = "rc1d-vbh2dw5ha0gpsazk.mdb.yandexcloud.net"
30
+ DB_PORT = "6432"
31
+
32
+ DATABASE_URL = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
33
+
34
+ # Create the SQLAlchemy engine
35
+ db_conn = create_engine(DATABASE_URL)
36
+
37
+ # Configure Gemini API
38
+ genai.configure(api_key=get_secret("GEMINI_API_KEY"))
39
+
40
+ def get_marketplace_and_main_image(id_product_money: str) -> Tuple[str, str]:
41
+ """Get marketplace and main image URL for a product."""
42
+ query = text("""
43
+ select mp, image as main_image_url
44
+ from public.products
45
+ where id_product_money = :id_product_money
46
+ """)
47
+
48
+ with db_conn.connect() as connection:
49
+ result = connection.execute(query, {"id_product_money": id_product_money}).first()
50
+ if result is None:
51
+ raise ValueError(f"No product found with id_product_money: {id_product_money}")
52
+ return result.mp, result.main_image_url
53
+
54
+ def get_additional_images(id_product_money: str, marketplace: str) -> List[str]:
55
+ """Get additional images based on marketplace."""
56
+ if marketplace == 'lamoda':
57
+ query = text("""
58
+ select info_chrc->'gallery' as more_images
59
+ from public.lamoda_chrc_and_reviews
60
+ where id_product_money = :id_product_money
61
+ limit 1
62
+ """)
63
+ with db_conn.connect() as connection:
64
+ result = connection.execute(query, {"id_product_money": id_product_money}).first()
65
+ if result and result.more_images:
66
+ paths = json.loads(result.more_images)
67
+ return [f"https://a.lmcdn.ru/product{path}" for path in paths]
68
+
69
+ elif marketplace == 'wildberries':
70
+ query = text("""
71
+ select features->'images' as more_images
72
+ from public.wb_chrc
73
+ where id_product_money = :id_product_money
74
+ limit 1
75
+ """)
76
+ with db_conn.connect() as connection:
77
+ result = connection.execute(query, {"id_product_money": id_product_money}).first()
78
+ if result and result.more_images:
79
+ return json.loads(result.more_images)
80
+
81
+ return []
82
+
83
+ def download_and_encode_images(image_urls: List[str]) -> List[Dict]:
84
+ """Download images and convert them to base64 format for Gemini."""
85
+ encoded_images = []
86
+ with httpx.Client() as client:
87
+ for url in image_urls:
88
+ try:
89
+ response = client.get(url)
90
+ response.raise_for_status()
91
+ encoded_image = base64.b64encode(response.content).decode('utf-8')
92
+ encoded_images.append({
93
+ 'mime_type': 'image/jpeg', # Assuming JPEG format
94
+ 'data': encoded_image
95
+ })
96
+ except Exception as e:
97
+ print(f"Error downloading image {url}: {str(e)}")
98
+ return encoded_images
99
+
100
+ def get_gemini_response(model_name: str, encoded_images: List[Dict], prompt: str) -> str:
101
+ """Get response from a Gemini model."""
102
+ try:
103
+ model = genai.GenerativeModel(model_name)
104
+ response = model.generate_content(encoded_images + [prompt])
105
+ return response.text
106
+ except Exception as e:
107
+ return f"Error with {model_name}: {str(e)}"
108
+
109
+ def process_input(id_product_money: str, prompt: str) -> Tuple[List[str], str, str]:
110
+ """Main processing function."""
111
+ try:
112
+ # Get marketplace and main image
113
+ marketplace, main_image = get_marketplace_and_main_image(id_product_money)
114
+
115
+ # Get additional images
116
+ additional_images = get_additional_images(id_product_money, marketplace)
117
+
118
+ # Combine all images
119
+ all_image_urls = [main_image] + additional_images
120
+
121
+ # Download and encode images
122
+ encoded_images = download_and_encode_images(all_image_urls)
123
+
124
+ if not encoded_images:
125
+ raise ValueError("No images could be downloaded")
126
+
127
+ # Get responses from both models
128
+ gemini_1_5_response = get_gemini_response("gemini-1.5-pro", encoded_images, prompt)
129
+ gemini_2_0_response = get_gemini_response("gemini-pro-vision", encoded_images, prompt)
130
+
131
+ return all_image_urls, gemini_1_5_response, gemini_2_0_response
132
+
133
+ except Exception as e:
134
+ return [], f"Error: {str(e)}", f"Error: {str(e)}"
135
+
136
+ # Create Gradio interface
137
+ with gr.Blocks() as demo:
138
+ gr.Markdown("# Product Image Analysis with Gemini Models")
139
+
140
+ with gr.Row():
141
+ id_input = gr.Textbox(label="Product ID (id_product_money)")
142
+ prompt_input = gr.Textbox(label="Prompt for VLMs")
143
+
144
+ submit_btn = gr.Button("Analyze")
145
+
146
+ with gr.Row():
147
+ image_gallery = gr.Gallery(label="Product Images")
148
+
149
+ with gr.Row():
150
+ with gr.Column():
151
+ gr.Markdown("### Gemini 1.5 Pro Response")
152
+ gemini_1_5_output = gr.Textbox(label="")
153
+ with gr.Column():
154
+ gr.Markdown("### Gemini Pro Vision Response")
155
+ gemini_2_0_output = gr.Textbox(label="")
156
+
157
+ submit_btn.click(
158
+ fn=process_input,
159
+ inputs=[id_input, prompt_input],
160
+ outputs=[image_gallery, gemini_1_5_output, gemini_2_0_output]
161
+ )
162
+
163
+ if __name__ == "__main__":
164
+ demo.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio
2
+ sqlalchemy
3
+ psycopg2-binary
4
+ google-generativeai
5
+ python-dotenv
6
+ httpx
7
+ grpcio