scottie201 commited on
Commit
4d1f388
·
1 Parent(s): 2086646
app.py CHANGED
@@ -1,4 +1,31 @@
1
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  # Set page config
4
  st.set_page_config(
@@ -8,63 +35,12 @@ st.set_page_config(
8
  initial_sidebar_state="expanded"
9
  )
10
 
11
- # Add custom CSS for modern sidebar styling
12
- st.markdown("""
13
- <style>
14
- [data-testid="stSidebarContent"] {
15
- background-color: #444444;
16
- padding: 1rem;
17
- }
18
- .cart-header {
19
- display: flex;
20
- justify-content: space-between;
21
- align-items: center;
22
- margin-bottom: 15px;
23
- padding-bottom: 10px;
24
- border-bottom: 1px solid #eee;
25
- }
26
- .cart-item {
27
- background-color: #555555;
28
- border-radius: 8px;
29
- padding: 10px;
30
- margin-bottom: 10px;
31
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
32
- }
33
- .cart-controls {
34
- display: flex;
35
- align-items: center;
36
- justify-content: space-between;
37
- margin-top: 8px;
38
- }
39
- .quantity-display {
40
- text-align: center;
41
- font-weight: bold;
42
- margin: 5px 0;
43
- }
44
- .cart-total {
45
- margin-top: 15px;
46
- padding-top: 15px;
47
- border-top: 1px solid #eee;
48
- font-weight: bold;
49
- font-size: 16px;
50
- }
51
- .empty-cart {
52
- text-align: center;
53
- padding: 20px 0;
54
- }
55
- .quantity-row {
56
- display: flex;
57
- justify-content: center;
58
- align-items: center;
59
- gap: 10px;
60
- margin-top: 8px;
61
- }
62
- </style>
63
- """, unsafe_allow_html=True)
64
 
65
  # Initialize session state variables
66
  if 'cart' not in st.session_state:
67
- st.session_state.cart = []
68
 
69
  if 'show_cart' not in st.session_state:
70
  st.session_state.show_cart = False
@@ -74,13 +50,13 @@ if 'show_cart' not in st.session_state:
74
 
75
  def add_to_cart(product_name, price, quantity):
76
  for item in st.session_state.cart:
77
- if item["name"] == product_name:
78
  item["quantity"] += quantity
79
  st.toast(f"Added {quantity} more {product_name} to cart!")
80
  return
81
 
82
  st.session_state.cart.append({
83
- "name": product_name,
84
  "price": price,
85
  "quantity": quantity
86
  })
@@ -89,89 +65,86 @@ def add_to_cart(product_name, price, quantity):
89
 
90
  # Define your pages
91
  home_page = st.Page("pages/home.py", title="Home", icon="🏠")
92
- prints_page = st.Page("pages/prints.py", title="Prints", icon="🖼️")
93
- clothing_page = st.Page("pages/charcuterie_boards.py",
94
- title="Charcuterie Boards", icon="👕")
 
95
  accessories_page = st.Page("pages/accessories.py",
96
  title="Accessories", icon="🧢")
97
  about_page = st.Page("pages/about.py", title="About", icon="ℹ️")
 
 
98
 
99
  # Create navigation
100
- pg = st.navigation([home_page, prints_page, clothing_page,
101
- accessories_page, about_page])
102
 
103
  # Cart in sidebar
104
  with st.sidebar:
105
  cart_count = sum(item.get("quantity", 1) for item in st.session_state.cart)
106
 
107
- st.markdown(
108
- f"""
109
- <div class="cart-header">
110
- <span style="font-size: 18px; font-weight: bold;">Shopping Cart</span>
111
- <span style="background-color: #1E90FF; color: white; padding: 2px 8px; border-radius: 12px; font-size: 14px;">{cart_count}</span>
112
- </div>
113
- """,
114
- unsafe_allow_html=True
115
- )
 
116
 
117
  if not st.session_state.cart:
118
- st.markdown('<div class="empty-cart">Your cart is empty</div>',
119
- unsafe_allow_html=True)
 
120
  else:
121
  for i, item in enumerate(st.session_state.cart):
 
122
  price_display = item['price']
123
  quantity = item.get('quantity', 1)
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  st.markdown(
126
  f"""
127
- <div class="cart-item">
128
- <div style="display: flex; justify-content: space-between;">
129
- <span style="font-weight: bold;">{item['name']}</span>
130
- <span>{price_display}</span>
131
- </div>
132
  </div>
133
  """,
134
  unsafe_allow_html=True
135
  )
136
 
137
- st.markdown('<div class="quantity-row">', unsafe_allow_html=True)
138
- col1, col2, col3 = st.columns([1, 2, 1])
139
- with col1:
140
- if st.button("➖", key=f"decrease_{i}", help="Decrease quantity"):
141
- if item["quantity"] > 1:
142
- item["quantity"] -= 1
143
- else:
144
- st.session_state.cart.pop(i)
145
- st.rerun()
146
- with col2:
147
- st.markdown(
148
- f"<span style='font-weight: bold;'>{quantity}</span>", unsafe_allow_html=True)
149
- with col3:
150
- if st.button("➕", key=f"increase_{i}", help="Increase quantity"):
151
- item["quantity"] += 1
152
- st.rerun()
153
- st.markdown('</div>', unsafe_allow_html=True)
154
-
155
- if st.button("🗑️", key=f"remove_{i}", help="Remove from cart"):
156
- st.session_state.cart.pop(i)
157
- st.rerun()
158
-
159
- total = sum(float(item["price"].replace(
160
- "$", "")) * item.get("quantity", 1) for item in st.session_state.cart)
161
-
162
- st.markdown(
163
- f"""
164
- <div class="cart-total">
165
- Total: <span style="color: #1E90FF;">${total:.2f}</span>
166
- </div>
167
- """,
168
- unsafe_allow_html=True
169
- )
170
-
171
  if st.button("Proceed to Checkout", key="checkout", use_container_width=True):
172
- st.success("Thank you for your purchase! (This is a demo)")
173
- st.session_state.cart = []
174
- st.rerun()
175
 
176
  # Run the current page
177
  pg.run()
 
1
  import streamlit as st
2
+ import json
3
+ import yaml
4
+
5
+ # Load logged-in user data from YAML file
6
+
7
+
8
+ def load_logged_in_user():
9
+ user_file = "/home/vscode/Brads_Store/config/logged_in_user.yml"
10
+ try:
11
+ with open(user_file, "r") as file:
12
+ user_data = yaml.safe_load(file)
13
+ return user_data.get("username", "")
14
+ except FileNotFoundError:
15
+ return ""
16
+
17
+ # Load cart data from JSON file, filtered by logged-in user
18
+
19
+
20
+ def load_cart_data(username):
21
+ cart_file = "/home/vscode/Brads_Store/pages/config/cart_data.json"
22
+ try:
23
+ with open(cart_file, "r") as file:
24
+ cart_data = json.load(file)
25
+ return [item for item in cart_data if item.get("username") == username]
26
+ except FileNotFoundError:
27
+ return []
28
+
29
 
30
  # Set page config
31
  st.set_page_config(
 
35
  initial_sidebar_state="expanded"
36
  )
37
 
38
+ # Get logged-in user
39
+ logged_in_user = load_logged_in_user()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  # Initialize session state variables
42
  if 'cart' not in st.session_state:
43
+ st.session_state.cart = load_cart_data(logged_in_user)
44
 
45
  if 'show_cart' not in st.session_state:
46
  st.session_state.show_cart = False
 
50
 
51
  def add_to_cart(product_name, price, quantity):
52
  for item in st.session_state.cart:
53
+ if item["product_name"] == product_name:
54
  item["quantity"] += quantity
55
  st.toast(f"Added {quantity} more {product_name} to cart!")
56
  return
57
 
58
  st.session_state.cart.append({
59
+ "product_name": product_name,
60
  "price": price,
61
  "quantity": quantity
62
  })
 
65
 
66
  # Define your pages
67
  home_page = st.Page("pages/home.py", title="Home", icon="🏠")
68
+ cutting_boards_page = st.Page(
69
+ "pages/cutting_boards.py", title="Cutting Boards", icon="🥠")
70
+ charcuterie_page = st.Page(
71
+ "pages/charcuterie_boards.py", title="Charcuterie Boards", icon="🍴")
72
  accessories_page = st.Page("pages/accessories.py",
73
  title="Accessories", icon="🧢")
74
  about_page = st.Page("pages/about.py", title="About", icon="ℹ️")
75
+ cart_page = st.Page("pages/cart.py", title="Shopping Cart", icon="🛒")
76
+ login_page = st.Page("pages/login_page.py", title="User Login Page", icon="🔒")
77
 
78
  # Create navigation
79
+ pg = st.navigation([home_page, cutting_boards_page, charcuterie_page,
80
+ accessories_page, cart_page, about_page, login_page])
81
 
82
  # Cart in sidebar
83
  with st.sidebar:
84
  cart_count = sum(item.get("quantity", 1) for item in st.session_state.cart)
85
 
86
+ with st.container(border=True):
87
+ st.markdown(
88
+ f"""
89
+ <div class="cart-header">
90
+ <span style="font-size: 18px; font-weight: bold;">Shopping Cart</span>
91
+ <span style="background-color: #1E90FF; color: white; padding: 2px 8px; border-radius: 12px; font-size: 14px;">{cart_count}</span>
92
+ </div>
93
+ """,
94
+ unsafe_allow_html=True
95
+ )
96
 
97
  if not st.session_state.cart:
98
+ with st.container(border=True):
99
+ st.markdown(
100
+ '<div class="empty-cart">Your cart is empty</div>', unsafe_allow_html=True)
101
  else:
102
  for i, item in enumerate(st.session_state.cart):
103
+ product_name = item['product_name']
104
  price_display = item['price']
105
  quantity = item.get('quantity', 1)
106
 
107
+ # Create an expander for each item
108
+ with st.expander(f"{product_name} - {price_display}", expanded=False):
109
+ with st.container(border=True):
110
+ st.markdown(
111
+ '<div class="quantity-row" style="display: flex; justify-content: center; align-items: center;">', unsafe_allow_html=True)
112
+ col1, col2, col3 = st.columns([1, 2, 1])
113
+ with col1:
114
+ if st.button("➖", key=f"decrease_{i}", help="Decrease quantity"):
115
+ if item["quantity"] > 1:
116
+ item["quantity"] -= 1
117
+ else:
118
+ st.session_state.cart.pop(i)
119
+ st.rerun()
120
+ with col2:
121
+ st.markdown(
122
+ f"<div style='text-align: center; font-weight: bold;'>Qty: {quantity}</div>", unsafe_allow_html=True)
123
+ with col3:
124
+ if st.button("➕", key=f"increase_{i}", help="Increase quantity"):
125
+ item["quantity"] += 1
126
+ st.rerun()
127
+ st.markdown('</div>', unsafe_allow_html=True)
128
+
129
+ if st.button("🗑️ Remove", key=f"remove_{i}", help="Remove from cart", use_container_width=True):
130
+ st.session_state.cart.pop(i)
131
+ st.rerun()
132
+
133
+ total = sum(float(item["price"].replace(
134
+ "$", "")) * item.get("quantity", 1) for item in st.session_state.cart)
135
+
136
+ with st.container(border=True):
137
  st.markdown(
138
  f"""
139
+ <div class="cart-total">
140
+ Total: <span style="color: #1E90FF;">${total:.2f}</span>
 
 
 
141
  </div>
142
  """,
143
  unsafe_allow_html=True
144
  )
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  if st.button("Proceed to Checkout", key="checkout", use_container_width=True):
147
+ st.switch_page("pages/cart.py")
 
 
148
 
149
  # Run the current page
150
  pg.run()
config/logged_in_user.yml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ role: user
2
+ username: testtt
pages/about.py CHANGED
@@ -10,7 +10,6 @@ load_dotenv()
10
  st.title("SambaNova Chat with Llama-3.3-70B")
11
 
12
  # File paths
13
- SEARCH_RESULTS_PATH = "search_results.txt"
14
  PROMPT_TEMPLATE_PATH = "summary_prompt.txt"
15
 
16
  # Initialize the client with API key from .env
@@ -56,31 +55,25 @@ def stream_sambanova_response(messages_for_api):
56
 
57
  # Chat input
58
  if user_input := st.chat_input("Ask something..."):
59
- # Dynamically load the latest contents of the files
60
  prompt_template = read_file(PROMPT_TEMPLATE_PATH)
61
- search_results = read_file(SEARCH_RESULTS_PATH)
62
 
63
- # Ensure that the content of both files is available
64
- if not prompt_template or not search_results:
65
- st.error("Error loading necessary files.")
66
  else:
67
- # Display the loaded search results so we can verify they're being fetched correctly
68
- st.subheader("Loaded Search Results:")
69
- st.text_area("Search Results", search_results, height=300)
70
-
71
- # Prepare the full prompt with the latest file contents
72
  full_prompt = prompt_template.replace("{user_input}", user_input)
73
- full_prompt = full_prompt.replace("{search_results}", search_results)
74
 
75
  # Add user message to chat history
76
  st.session_state.messages.append(
77
- {"role": "user", "content": full_prompt})
78
 
79
  # Display user message
80
  with st.chat_message("user"):
81
- st.markdown(full_prompt)
82
 
83
- # Prepare API call with conversation history
84
  messages_for_api = st.session_state.messages[:-1] + [
85
  {"role": "user", "content": full_prompt}]
86
 
 
10
  st.title("SambaNova Chat with Llama-3.3-70B")
11
 
12
  # File paths
 
13
  PROMPT_TEMPLATE_PATH = "summary_prompt.txt"
14
 
15
  # Initialize the client with API key from .env
 
55
 
56
  # Chat input
57
  if user_input := st.chat_input("Ask something..."):
58
+ # Load the latest contents of the prompt template
59
  prompt_template = read_file(PROMPT_TEMPLATE_PATH)
 
60
 
61
+ # Ensure the prompt template is available
62
+ if not prompt_template:
63
+ st.error("Error loading the prompt template.")
64
  else:
65
+ # Prepare the full prompt in the background, without displaying it
 
 
 
 
66
  full_prompt = prompt_template.replace("{user_input}", user_input)
 
67
 
68
  # Add user message to chat history
69
  st.session_state.messages.append(
70
+ {"role": "user", "content": user_input})
71
 
72
  # Display user message
73
  with st.chat_message("user"):
74
+ st.markdown(user_input)
75
 
76
+ # Prepare API call with conversation history, ensuring the model sees the full prompt
77
  messages_for_api = st.session_state.messages[:-1] + [
78
  {"role": "user", "content": full_prompt}]
79
 
pages/accessories.py CHANGED
@@ -1,143 +1,122 @@
1
  import streamlit as st
2
  import yaml
 
3
  import os
4
- import base64
5
-
6
- # Define the path to the custom icon
7
- icon_path = "/home/vscode/Brads_Store/pages/config/images/icon2.png"
8
-
9
-
10
- def load_image_as_base64(image_path):
11
- with open(image_path, "rb") as img_file:
12
- return base64.b64encode(img_file.read()).decode()
13
-
14
-
15
- # Load the icon image as base64
16
- icon_base64 = load_image_as_base64(icon_path)
17
-
18
- # Custom CSS for container styling
19
- custom_css = f"""
20
- <style>
21
- .title-container {{
22
- display: flex;
23
- align-items: center;
24
- background-color: #444;
25
- padding: 10px 20px;
26
- border-radius: 15px;
27
- transition: background-color 0.3s ease, transform 0.3s ease;
28
- box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
29
- margin-bottom: 30px;
30
- border: 2px solid #007BFF;
31
- }}
32
- .title-icon {{
33
- width: 80px;
34
- height: 80px;
35
- background-image: url(data:image/png;base64,{icon_base64});
36
- background-size: cover;
37
- margin-right: 15px;
38
- transition: transform 0.5s ease;
39
- }}
40
- .title-container:hover .title-icon {{
41
- transform: rotate(360deg);
42
- }}
43
- .title-text {{
44
- font-size: 2.5em;
45
- font-weight: bold;
46
- color: white;
47
- transition: color 0.3s ease;
48
- }}
49
- .title-container:hover .title-text {{
50
- color: #007BFF;
51
- }}
52
- .product-card {{
53
- text-align: center;
54
- margin-bottom: 20px;
55
- padding: 15px;
56
- border: 2px solid #007BFF;
57
- border-radius: 10px;
58
- background-color: #444;
59
- color: white;
60
- }}
61
- .product-card h3 {{
62
- background-color: #444;
63
- color: white;
64
- padding: 10px;
65
- border-radius: 5px;
66
- }}
67
- .product-card p {{
68
- background-color: #444;
69
- color: white;
70
- padding: 5px;
71
- border-radius: 5px;
72
- display: inline-block;
73
- font-weight: bold;
74
- }}
75
- </style>
76
- <div class="title-container">
77
- <div class="title-icon"></div>
78
- <div class="title-text">Charcuterie Boards Collection</div>
79
- </div>
80
- """
81
-
82
- # Inject the custom CSS and HTML into the Streamlit app
83
- st.markdown(custom_css, unsafe_allow_html=True)
84
-
85
- # Header Section with Container
86
- with st.container(border=True):
87
- st.markdown("""
88
- <h3 style='margin-bottom: 20px; color: white;'>Cutting boards that tell a story: handmade with love.</h3>
89
- """, unsafe_allow_html=True)
90
-
91
- # Load YAML file
92
- yaml_file_path = "/home/vscode/Brads_Store/pages/config/images_config_cuttting_boards.yml"
93
- if not os.path.exists(yaml_file_path):
94
- st.error("Configuration file not found!")
95
- st.stop()
96
-
97
- with open(yaml_file_path, "r") as file:
98
- product_data = yaml.safe_load(file)
99
-
100
- # Filter products
101
- prints = {name: info for name, info in product_data["items"].items(
102
- ) if info.get("category", "") == "print"} or product_data["items"]
103
-
104
- # Display products in a structured container
105
- total_products = len(prints)
106
- num_columns = 3
107
-
108
- with st.container(border=True):
109
- for i in range(0, total_products, num_columns):
110
- cols = st.columns(num_columns)
111
- for j in range(num_columns):
112
- if i + j < total_products:
113
- product_name = list(prints.keys())[i + j]
114
- product_info = prints[product_name]
115
- with cols[j]:
116
- with st.container(border=True):
117
- st.markdown(f"""
118
- <div class="product-card">
119
- <h3>{product_name}</h3>
120
- <p><b>{product_info['price']}</b></p>
121
- </div>
122
- """, unsafe_allow_html=True)
123
- st.image(product_info["image_path"],
124
- use_container_width=True)
125
-
126
- with st.expander("View Details"):
127
- st.subheader(product_name)
128
- st.write(f"**Price:** {product_info['price']}")
129
- st.write(product_info["description"])
130
-
131
- quantity = st.number_input(
132
- "Quantity:", min_value=1, value=1, step=1, key=f"quantity_{i + j}"
133
- )
134
- if st.button("🛒 Add to Cart", key=f"btn_{i + j}"):
135
- if 'cart' not in st.session_state:
136
- st.session_state.cart = []
137
- st.session_state.cart.append({
138
- "name": product_name,
139
- "price": product_info['price'],
140
- "quantity": quantity
141
- })
142
- st.success(
143
- f"Added {quantity} {product_name} to cart!")
 
1
  import streamlit as st
2
  import yaml
3
+ import hashlib
4
  import os
5
+
6
+ # File paths
7
+ USERS_FILE = "/home/vscode/Brads_Store/pages/config/users.yml"
8
+ LOGGED_IN_FILE = "/home/vscode/Brads_Store/config/logged_in_user.yml"
9
+
10
+ # Load users from YAML file
11
+
12
+
13
+ def load_users():
14
+ with open(USERS_FILE, "r") as file:
15
+ return yaml.safe_load(file)["users"]
16
+
17
+ # Save users to YAML file
18
+
19
+
20
+ def save_users(users):
21
+ with open(USERS_FILE, "w") as file:
22
+ yaml.dump({"users": users}, file)
23
+
24
+ # Save logged in user
25
+
26
+
27
+ def save_logged_in_user(username, role):
28
+ # Create directory if it doesn't exist
29
+ os.makedirs(os.path.dirname(LOGGED_IN_FILE), exist_ok=True)
30
+ with open(LOGGED_IN_FILE, "w") as file:
31
+ yaml.dump({"username": username, "role": role}, file)
32
+
33
+ # Hash function for passwords
34
+
35
+
36
+ def hash_password(password):
37
+ return hashlib.sha256(password.encode()).hexdigest()
38
+
39
+ # Authenticate user
40
+
41
+
42
+ def authenticate(username, password):
43
+ users = load_users()
44
+ for user in users:
45
+ if user["username"] == username and user["password"] == password:
46
+ return user["role"]
47
+ return None
48
+
49
+ # Add new user
50
+
51
+
52
+ def add_user(username, password, role):
53
+ users = load_users()
54
+ if any(user["username"] == username for user in users):
55
+ return False # Username already exists
56
+ users.append({"username": username, "password": password, "role": role})
57
+ save_users(users)
58
+ return True
59
+
60
+
61
+ # Streamlit UI
62
+ st.title("Login Page")
63
+ username = st.text_input("Username")
64
+ password = st.text_input("Password", type="password")
65
+
66
+ if st.button("Login"):
67
+ role = authenticate(username, password)
68
+ if role:
69
+ save_logged_in_user(username, role)
70
+ st.success(f"Welcome, {username}! Role: {role}")
71
+ st.session_state.logged_in = True
72
+ st.session_state.username = username
73
+ st.session_state.role = role
74
+ else:
75
+ st.error("Invalid username or password")
76
+
77
+ # Add New User section in a popover
78
+ with st.popover("Add New User"):
79
+ new_username = st.text_input("New Username")
80
+ new_password = st.text_input("New Password", type="password")
81
+ confirm_password = st.text_input("Confirm Password", type="password")
82
+ new_role = st.selectbox("Role", ["user", "admin"])
83
+
84
+ # Check if passwords match
85
+ passwords_match = new_password == confirm_password
86
+
87
+ # Show match status if both fields have input
88
+ if new_password and confirm_password:
89
+ if passwords_match:
90
+ st.success("Passwords match!")
91
+ else:
92
+ st.warning("Sorry, the passwords didn't match")
93
+
94
+ if st.button("Add User"):
95
+ if not new_username or not new_password:
96
+ st.error("Username and password are required")
97
+ elif not passwords_match:
98
+ st.error("Passwords do not match. Please try again.")
99
+ elif add_user(new_username, new_password, new_role):
100
+ # Log in the new user automatically
101
+ save_logged_in_user(new_username, new_role)
102
+ st.success(
103
+ f"User added successfully! You are now logged in as {new_username}")
104
+ st.session_state.logged_in = True
105
+ st.session_state.username = new_username
106
+ st.session_state.role = new_role
107
+ st.rerun() # Rerun the app to update the UI
108
+ else:
109
+ st.error("Username already exists. Please choose a different one.")
110
+
111
+ # Display logged in status if in session state
112
+ if st.session_state.get('logged_in'):
113
+ st.sidebar.success(f"Logged in as: {st.session_state.username}")
114
+ if st.sidebar.button("Log out"):
115
+ # Clear the logged in user file
116
+ if os.path.exists(LOGGED_IN_FILE):
117
+ os.remove(LOGGED_IN_FILE)
118
+ # Clear session state
119
+ st.session_state.logged_in = False
120
+ st.session_state.pop('username', None)
121
+ st.session_state.pop('role', None)
122
+ st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/cart.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import json
3
+ import yaml
4
+ from pathlib import Path
5
+
6
+ # Load logged-in user data from YAML file
7
+
8
+
9
+ def load_logged_in_user():
10
+ user_file = Path("/home/vscode/Brads_Store/config/logged_in_user.yml")
11
+ try:
12
+ with user_file.open("r") as file:
13
+ user_data = yaml.safe_load(file)
14
+ return user_data.get("username", "")
15
+ except FileNotFoundError:
16
+ return ""
17
+
18
+ # Load cart data from JSON file, filtered by logged-in user
19
+
20
+
21
+ def load_cart_data(username):
22
+ cart_file = Path("/home/vscode/Brads_Store/pages/config/cart_data.json")
23
+ try:
24
+ with cart_file.open("r") as file:
25
+ cart_data = json.load(file)
26
+ return [item for item in cart_data if item.get("username") == username]
27
+ except FileNotFoundError:
28
+ return []
29
+
30
+ # Save updated cart data to JSON file
31
+
32
+
33
+ def save_cart_data(cart_data):
34
+ cart_file = Path("/home/vscode/Brads_Store/pages/config/cart_data.json")
35
+ try:
36
+ with cart_file.open("w") as file:
37
+ json.dump(cart_data, file, indent=4)
38
+ except Exception as e:
39
+ st.error(f"Error saving cart data: {e}")
40
+
41
+ # Load product details from combined_items.yml
42
+
43
+
44
+ def load_product_details():
45
+ items_file = Path(
46
+ "/home/vscode/Brads_Store/pages/config/combined_items.yml")
47
+ try:
48
+ with items_file.open("r") as file:
49
+ items_data = yaml.safe_load(file)
50
+ return items_data.get("items", {})
51
+ except FileNotFoundError:
52
+ return {}
53
+
54
+
55
+ # Main app container
56
+ main_container = st.container(border=False)
57
+
58
+ # Sidebar user info with styling
59
+ with st.sidebar:
60
+ st.divider()
61
+ user_container = st.container(border=True)
62
+ with user_container:
63
+ # Get logged-in user
64
+ logged_in_user = load_logged_in_user()
65
+ st.subheader(f"Logged in as: {logged_in_user}")
66
+ st.divider()
67
+
68
+ # Initialize session state variables
69
+ if 'cart' not in st.session_state:
70
+ st.session_state.cart = load_cart_data(logged_in_user)
71
+
72
+ # Load product details
73
+ product_details = load_product_details()
74
+
75
+ with main_container:
76
+ st.title("🛒 Your Shopping Cart")
77
+ st.divider()
78
+
79
+ # Cart items container
80
+ cart_container = st.container(border=False)
81
+ with cart_container:
82
+ st.subheader("Your Cart Items")
83
+
84
+ if not st.session_state.cart:
85
+ empty_cart = st.container(border=True, height=100)
86
+ empty_cart.write("Your cart is empty.")
87
+ else:
88
+ updated_cart = []
89
+ for i, item in enumerate(st.session_state.cart):
90
+ # Create a container for each item with border
91
+ item_container = st.container(border=True)
92
+ with item_container:
93
+ product_name = item['product_name']
94
+ product_info = product_details.get(product_name, {})
95
+ image_path = product_info.get('image_path', '')
96
+ description = product_info.get(
97
+ 'description', 'No description available.')
98
+
99
+ # Create columns for layout
100
+ col1, col2, col3 = st.columns([1, 2, 1])
101
+ with col1:
102
+ if image_path:
103
+ st.image(image_path, width=100)
104
+ with col2:
105
+ st.markdown(f"**{product_name}**")
106
+ st.caption(description)
107
+ quantity = st.number_input(
108
+ "Qty",
109
+ min_value=1,
110
+ value=item.get('quantity', 1),
111
+ key=f"qty_{product_name}_{i}", # Ensure uniqueness
112
+ label_visibility="collapsed",
113
+ format="%d",
114
+ step=1
115
+ )
116
+ item['quantity'] = quantity
117
+ with col3:
118
+ # Unique key
119
+ if st.button("Remove", key=f"remove_{product_name}_{i}"):
120
+ st.session_state.cart.pop(i) # Remove the item
121
+ # Save updated cart
122
+ save_cart_data(st.session_state.cart)
123
+ st.rerun() # Refresh the UI after removal
124
+
125
+ updated_cart.append(item)
126
+
127
+ # Add a small divider between items (except after the last item)
128
+ if i < len(st.session_state.cart) - 1:
129
+ st.markdown("<br>", unsafe_allow_html=True)
130
+
131
+ # Update the session state with the modified cart
132
+ st.session_state.cart = updated_cart
133
+ save_cart_data(st.session_state.cart)
134
+
135
+ st.divider()
136
+
137
+ # Total container with styling
138
+ total_container = st.container(border=True)
139
+ with total_container:
140
+ # Total Calculation
141
+ total = sum(float(item["price"].replace("$", "")) *
142
+ item.get("quantity", 1) for item in st.session_state.cart)
143
+ st.subheader(f"**Total: ${total:.2f}**")
pages/charcuterie_boards.py CHANGED
@@ -2,9 +2,17 @@ import streamlit as st
2
  import yaml
3
  import os
4
  import base64
 
 
5
 
6
- # Define the path to the custom icon
7
- icon_path = "/home/vscode/Brads_Store/pages/config/images/icon1.png"
 
 
 
 
 
 
8
 
9
 
10
  def load_image_as_base64(image_path):
@@ -15,96 +23,86 @@ def load_image_as_base64(image_path):
15
  # Load the icon image as base64
16
  icon_base64 = load_image_as_base64(icon_path)
17
 
18
- # Custom CSS for padding and styling
19
- custom_css = f"""
20
- <style>
21
- /* Title Container */
22
- .title-container {{
23
- display: flex;
24
- align-items: center;
25
- background-color: rgba(255, 255, 255, 0.8);
26
- padding: 10px 20px;
27
- border-radius: 15px;
28
- transition: background-color 0.3s ease, transform 0.3s ease;
29
- box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
30
- margin-bottom: 30px; /* Adds space between title and header */
31
- }}
32
- .title-container:hover {{
33
- background-color: rgba(255, 255, 255, 1);
34
- transform: scale(1.05);
35
- }}
36
- .title-icon {{
37
- width: 80px;
38
- height: 80px;
39
- background-image: url(data:image/png;base64,{icon_base64});
40
- background-size: cover;
41
- margin-right: 15px;
42
- transition: transform 0.5s ease;
43
- }}
44
- .title-container:hover .title-icon {{
45
- transform: rotate(360deg);
46
- }}
47
- .title-text {{
48
- font-size: 2.5em;
49
- font-weight: bold;
50
- color: #333;
51
- transition: color 0.3s ease;
52
- }}
53
- .title-container:hover .title-text {{
54
- color: #007BFF;
55
- }}
56
-
57
- /* Section Styling */
58
- .section {{
59
- margin-top: 50px; /* Adds space between sections */
60
- }}
61
-
62
- /* Product Card Styling */
63
- .product-card {{
64
- text-align: center;
65
- margin-bottom: 30px;
66
- }}
67
- .product-card h3 {{
68
- margin-bottom: 10px;
69
- }}
70
- .product-card p {{
71
- margin-top: 0;
72
- }}
73
-
74
- /* Expander Customization */
75
- .streamlit-expanderHeader {{
76
- background-color: #f0f2f6; /* Header background color */
77
- color: #333; /* Header text color */
78
- font-weight: bold;
79
- padding: 10px;
80
- border-radius: 5px;
81
- }}
82
- .streamlit-expanderContent {{
83
- background-color: #ffffff; /* Content background color */
84
- padding: 10px;
85
- border: 1px solid #e6e6e6;
86
- border-top: none;
87
- border-radius: 0 0 5px 5px;
88
- }}
89
- </style>
90
- <div class="title-container">
91
- <div class="title-icon"></div>
92
- <div class="title-text">Charcuterie Boards Collection</div>
93
- </div>
94
- """
95
-
96
- # Inject the custom CSS and HTML into the Streamlit app
97
- st.markdown(custom_css, unsafe_allow_html=True)
98
-
99
- # Header text with padding
100
- st.markdown("""
101
- <div style='margin-bottom: 50px;'>
102
- <h3>Vibrant psychedelic prints for your walls</h3>
103
- </div>
104
  """, unsafe_allow_html=True)
105
 
106
- # Load YAML file
107
- yaml_file_path = "/home/vscode/Brads_Store/pages/config/images_config_cuttting_boards.yml"
108
  if not os.path.exists(yaml_file_path):
109
  st.error("Configuration file not found!")
110
  st.stop()
@@ -112,55 +110,64 @@ if not os.path.exists(yaml_file_path):
112
  with open(yaml_file_path, "r") as file:
113
  product_data = yaml.safe_load(file)
114
 
115
- # Filter for prints only (assuming you have a category field in your YAML)
116
  prints = {name: info for name, info in product_data["items"].items(
117
- ) if info.get("category", "") == "print"}
118
-
119
- # If no prints found, show all products
120
- if not prints:
121
- prints = product_data["items"]
122
 
123
- # Display prints in a grid layout
124
- product_names = list(prints.keys())
125
- num_products = len(product_names)
126
  num_columns = 3
127
 
128
- for i in range(0, num_products, num_columns):
129
- cols = st.columns(num_columns)
130
- for j in range(num_columns):
131
- if i + j < num_products:
132
- product_name = product_names[i + j]
133
- product_info = prints[product_name]
134
- with cols[j]:
135
- st.markdown(f"""
136
- <div class="product-card">
137
- <h3>{product_name}</h3>
138
- <p><b>{product_info['price']}</b></p>
139
- </div>
140
- """, unsafe_allow_html=True)
141
-
142
- st.image(product_info["image_path"], use_container_width=True)
143
-
144
- with st.expander("View Details"):
145
- st.subheader(product_name)
146
- st.write(f"**Price:** {product_info['price']}")
147
- st.write(product_info["description"])
148
-
149
- # Add quantity selector in expander
150
- quantity = st.number_input(
151
- "Quantity:",
152
- min_value=1,
153
- value=1,
154
- step=1,
155
- key=f"quantity_{i + j}"
156
- )
157
-
158
- if st.button("🛒 Add to Cart", key=f"btn_{i + j}"):
159
- if 'cart' not in st.session_state:
160
- st.session_state.cart = []
161
- st.session_state.cart.append({
162
- "name": product_name,
163
- "price": product_info['price'],
164
- "quantity": quantity
165
- })
166
- st.success(f"Added {quantity} {product_name} to cart!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import yaml
3
  import os
4
  import base64
5
+ import json
6
+ from datetime import datetime
7
 
8
+ # Define file paths
9
+ icon_path = "pages/config/images/icon1.png"
10
+ css_path = "pages/styles/page_style1.css"
11
+ yaml_file_path = "pages/config/items/images_config_charcuterie_boards.yml"
12
+ CART_FILE = "pages/config/cart_data.json"
13
+ logged_user_file = "config/logged_in_user.yml"
14
+
15
+ # Function to load an image as base64
16
 
17
 
18
  def load_image_as_base64(image_path):
 
23
  # Load the icon image as base64
24
  icon_base64 = load_image_as_base64(icon_path)
25
 
26
+ # Function to load CSS from file
27
+
28
+
29
+ def load_css(file_path):
30
+ with open(file_path, "r") as f:
31
+ return f"<style>{f.read()}</style>"
32
+
33
+
34
+ st.markdown(load_css(css_path), unsafe_allow_html=True)
35
+
36
+ # Function to load the logged-in user from YAML
37
+
38
+
39
+ def load_logged_in_user():
40
+ if os.path.exists(logged_user_file):
41
+ with open(logged_user_file, "r") as f:
42
+ data = yaml.safe_load(f)
43
+ return data.get("username", "guest")
44
+ return "guest"
45
+
46
+
47
+ # Use the logged-in user automatically
48
+ username = load_logged_in_user()
49
+
50
+ # Functions to load and save cart data from/to JSON file
51
+
52
+
53
+ def load_cart_data():
54
+ if os.path.exists(CART_FILE):
55
+ with open(CART_FILE, "r") as f:
56
+ try:
57
+ return json.load(f)
58
+ except json.JSONDecodeError:
59
+ return []
60
+ return []
61
+
62
+
63
+ def save_cart_data(data):
64
+ with open(CART_FILE, "w") as f:
65
+ json.dump(data, f, indent=4)
66
+
67
+
68
+ # Header Section with Icon and Title
69
+ st.markdown(f"""
70
+ <style>
71
+ .title-container {{
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ background-color: #444;
76
+ padding: 10px 20px;
77
+ border-radius: 15px;
78
+ box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
79
+ margin-bottom: 30px;
80
+ border: 2px solid #007BFF;
81
+ }}
82
+ .title-icon {{
83
+ width: 80px;
84
+ height: 80px;
85
+ background-image: url(data:image/png;base64,{icon_base64});
86
+ background-size: cover;
87
+ margin-right: 15px;
88
+ }}
89
+ .title-text {{
90
+ font-size: 2.5em;
91
+ font-weight: bold;
92
+ color: white;
93
+ transition: color 0.3s ease;
94
+ }}
95
+ .title-container:hover .title-text {{
96
+ color: #007BFF;
97
+ }}
98
+ </style>
99
+ <div class="title-container">
100
+ <div class="title-icon"></div>
101
+ <div class="title-text">Cutting Boards That Tell a Story</div>
102
+ </div>
 
 
 
 
 
 
 
 
 
103
  """, unsafe_allow_html=True)
104
 
105
+ # Load product data from YAML file
 
106
  if not os.path.exists(yaml_file_path):
107
  st.error("Configuration file not found!")
108
  st.stop()
 
110
  with open(yaml_file_path, "r") as file:
111
  product_data = yaml.safe_load(file)
112
 
113
+ # Filter products (if 'category' equals "print", otherwise use all products)
114
  prints = {name: info for name, info in product_data["items"].items(
115
+ ) if info.get("category", "") == "print"} or product_data["items"]
 
 
 
 
116
 
117
+ # Display products in a structured container
118
+ total_products = len(prints)
 
119
  num_columns = 3
120
 
121
+ with st.container(border=True):
122
+ for i in range(0, total_products, num_columns):
123
+ cols = st.columns(num_columns)
124
+ for j in range(num_columns):
125
+ if i + j < total_products:
126
+ product_name = list(prints.keys())[i + j]
127
+ product_info = prints[product_name]
128
+ with cols[j]:
129
+ with st.container(border=True):
130
+ st.markdown(f"""
131
+ <div class="product-card">
132
+ <h3>{product_name}</h3>
133
+ <p><b>{product_info['price']}</b></p>
134
+ </div>
135
+ """, unsafe_allow_html=True)
136
+ st.image(product_info["image_path"],
137
+ use_container_width=True)
138
+
139
+ with st.expander("View Details"):
140
+ st.subheader(product_name)
141
+ st.write(f"**Price:** {product_info['price']}")
142
+ st.write(product_info["description"])
143
+
144
+ quantity = st.number_input(
145
+ "Quantity:", min_value=1, value=1, step=1, key=f"quantity_{i + j}")
146
+ if st.button("🛒 Add to Cart", key=f"btn_{i + j}"):
147
+ # Create a new cart entry with username, timestamp, and product details
148
+ new_entry = {
149
+ "username": username,
150
+ "timestamp": datetime.now().isoformat(),
151
+ "product_name": product_name,
152
+ "price": product_info["price"],
153
+ "quantity": quantity
154
+ }
155
+ # Optionally, update session state for the current session cart
156
+ if 'cart' not in st.session_state:
157
+ st.session_state.cart = []
158
+ st.session_state.cart.append(new_entry)
159
+
160
+ # Append the new entry to the persistent cart JSON file
161
+ cart_data = load_cart_data()
162
+ cart_data.append(new_entry)
163
+ save_cart_data(cart_data)
164
+
165
+ st.success(
166
+ f"Added {quantity} {product_name} to cart!")
167
+
168
+ # Footer Section
169
+ st.markdown("""
170
+ <div class="footer-container">
171
+ <p>&copy; 2025 Charcuterie Boards Store. All rights reserved.</p>
172
+ </div>
173
+ """, unsafe_allow_html=True)
pages/config/cart_data.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "username": "testtt",
4
+ "timestamp": "2025-03-17T23:44:40.281767",
5
+ "product_name": "Psychedelic Poster 1",
6
+ "price": "$19.99",
7
+ "quantity": 2
8
+ },
9
+ {
10
+ "username": "testtt",
11
+ "timestamp": "2025-03-17T23:55:41.790624",
12
+ "product_name": "Psychedelic Cutting Board",
13
+ "price": "$29.99",
14
+ "quantity": 4
15
+ },
16
+ {
17
+ "username": "testtt",
18
+ "timestamp": "2025-03-17T23:55:41.790624",
19
+ "product_name": "Psychedelic Cutting Board",
20
+ "price": "$29.99",
21
+ "quantity": 5
22
+ },
23
+ {
24
+ "username": "testtt",
25
+ "timestamp": "2025-03-27T23:55:41.790624",
26
+ "product_name": "Psychedelic Cutting Board",
27
+ "price": "$29.99",
28
+ "quantity": 2
29
+ }
30
+ ]
pages/config/combined_items.yml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ items:
2
+ Charcuterie Board 1:
3
+ description: A mesmerizing psychedelic art print, perfect for your wall.
4
+ image_path: /home/vscode/Brads_Store/pages/config/images/cutting_boards/board1.png
5
+ price: $19.99
6
+ Psychedelic Art Coaster:
7
+ description: A psychedelic-themed coaster to add a trippy vibe to your drinks.
8
+ image_path: /home/vscode/project_assistant_dashboard/pages/config/images/download
9
+ (1).png
10
+ price: $9.99
11
+ Psychedelic Canvas:
12
+ description: A high-quality psychedelic canvas print for art lovers.
13
+ image_path: /home/vscode/project_assistant_dashboard/pages/config/images/image
14
+ (2).png
15
+ price: $49.99
16
+ Psychedelic Cutting Board:
17
+ description: The best money can buy!!!!
18
+ image_path: /home/vscode/Brads_Store/pages/config/images/cutting_boards/abstract1.png
19
+ price: $29.99
20
+ Psychedelic Poster 1:
21
+ description: A mesmerizing psychedelic art print, perfect for your wall.
22
+ image_path: /home/vscode/Brads_Store/pages/config/images/cutting_boards/image
23
+ (2).png
24
+ price: $19.99
25
+ Psychedelic Poster 2:
26
+ description: An intense, vibrant psychedelic poster to captivate any space.
27
+ image_path: /home/vscode/project_assistant_dashboard/pages/config/images/image
28
+ (1).png
29
+ price: $24.99
pages/config/images_config.yml CHANGED
@@ -1,21 +1,25 @@
1
  items:
2
- Psychedelic Cutting Board:
3
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/download.png"
4
- price: "$29.99"
5
- description: "A stunning psychedelic cutting board to add a splash of color to your kitchen."
6
- Psychedelic Poster 1:
 
7
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image.png"
8
- price: "$19.99"
9
- description: "A mesmerizing psychedelic art print, perfect for your wall."
10
- Psychedelic Poster 2:
 
11
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image (1).png"
12
- price: "$24.99"
13
- description: "An intense, vibrant psychedelic poster to captivate any space."
14
- Psychedelic Canvas:
 
15
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image (2).png"
16
  price: "$49.99"
17
- description: "A high-quality psychedelic canvas print for art lovers."
18
- Psychedelic Art Coaster:
 
19
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/download (1).png"
20
- price: "$9.99"
21
- description: "A psychedelic-themed coaster to add a trippy vibe to your drinks."
 
1
  items:
2
+ Classic Wood Charcuterie Board:
3
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/download.png"
4
+ price: "$34.99"
5
+ description: "A timeless wooden charcuterie board, perfect for serving cheeses and meats in style."
6
+
7
+ Elegant Marble Charcuterie Board:
8
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image.png"
9
+ price: "$44.99"
10
+ description: "A luxurious marble charcuterie board designed for upscale presentations."
11
+
12
+ Modern Slate Charcuterie Board:
13
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image (1).png"
14
+ price: "$39.99"
15
+ description: "A sleek and durable slate charcuterie board for a contemporary serving experience."
16
+
17
+ Rustic Acacia Charcuterie Board:
18
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image (2).png"
19
  price: "$49.99"
20
+ description: "A premium acacia wood charcuterie board with a natural rustic finish."
21
+
22
+ Compact Bamboo Charcuterie Board:
23
  image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/download (1).png"
24
+ price: "$24.99"
25
+ description: "A lightweight and eco-friendly bamboo charcuterie board, ideal for small gatherings."
pages/config/images_config_cuttting_boards.yml CHANGED
@@ -1,16 +1,15 @@
1
  items:
2
- Psychedelic Cutting Board:
3
  image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/abstract1.png"
4
- price: "$29.99"
5
- description: "The best money can buy!!!!"
6
- Psychedelic Poster 1:
7
- image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/image (2).png"
8
- price: "$19.99"
9
- description: "A mesmerizing psychedelic art print, perfect for your wall."
10
- Charcuterie Board 1:
11
- image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/board1.png"
12
- price: "$19.99"
13
- description: "A mesmerizing psychedelic art print, perfect for your wall."
14
-
15
 
 
 
 
 
16
 
 
 
 
 
 
1
  items:
2
+ Artistic Abstract Charcuterie Board:
3
  image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/abstract1.png"
4
+ price: "$34.99"
5
+ description: "A beautifully designed charcuterie board with a unique abstract pattern."
 
 
 
 
 
 
 
 
 
6
 
7
+ Elegant Display Charcuterie Board:
8
+ image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/image (2).png"
9
+ price: "$24.99"
10
+ description: "A stylish and functional charcuterie board, ideal for serving snacks and appetizers."
11
 
12
+ Premium Hardwood Charcuterie Board:
13
+ image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/board1.png"
14
+ price: "$39.99"
15
+ description: "A durable hardwood charcuterie board with a smooth finish, perfect for hosting events."
pages/config/items/images_config_charcuterie_boards.yml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ items:
2
+ Classic Wood Charcuterie Board:
3
+ image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/download.png"
4
+ price: "$34.99"
5
+ description: "A timeless wooden charcuterie board, perfect for serving cheeses and meats in style."
6
+
7
+ Elegant Marble Charcuterie Board:
8
+ image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image.png"
9
+ price: "$44.99"
10
+ description: "A luxurious marble charcuterie board designed for upscale presentations."
11
+
12
+ Modern Slate Charcuterie Board:
13
+ image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image (1).png"
14
+ price: "$39.99"
15
+ description: "A sleek and durable slate charcuterie board for a contemporary serving experience."
16
+
17
+ Rustic Acacia Charcuterie Board:
18
+ image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/image (2).png"
19
+ price: "$49.99"
20
+ description: "A premium acacia wood charcuterie board with a natural rustic finish."
21
+
22
+ Compact Bamboo Charcuterie Board:
23
+ image_path: "/home/vscode/project_assistant_dashboard/pages/config/images/download (1).png"
24
+ price: "$24.99"
25
+ description: "A lightweight and eco-friendly bamboo charcuterie board, ideal for small gatherings."
pages/config/items/images_config_cuttting_boards.yml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ items:
2
+ Artistic Abstract Charcuterie Board:
3
+ image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/abstract1.png"
4
+ price: "$34.99"
5
+ description: "A beautifully designed charcuterie board with a unique abstract pattern."
6
+
7
+ Elegant Display Charcuterie Board:
8
+ image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/image (2).png"
9
+ price: "$24.99"
10
+ description: "A stylish and functional charcuterie board, ideal for serving snacks and appetizers."
11
+
12
+ Premium Hardwood Charcuterie Board:
13
+ image_path: "/home/vscode/Brads_Store/pages/config/images/cutting_boards/board1.png"
14
+ price: "$39.99"
15
+ description: "A durable hardwood charcuterie board with a smooth finish, perfect for hosting events."
pages/config/users.yml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ users:
2
+ - password: admin123
3
+ role: admin
4
+ username: admin
5
+ - password: userpass1
6
+ role: user
7
+ username: user1
8
+ - password: userpass2
9
+ role: user
10
+ username: user2
11
+ - password: test
12
+ role: user
13
+ username: test
14
+ - password: test
15
+ role: user
16
+ username: testt
17
+ - password: test
18
+ role: user
19
+ username: testtt
pages/config/wishlist_data.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "username": "testtt",
4
+ "timestamp": "2025-03-17T23:44:40.281767",
5
+ "product_name": "Psychedelic Poster 1",
6
+ "price": "$19.99",
7
+ "quantity": 2
8
+ },
9
+ {
10
+ "username": "testtt",
11
+ "timestamp": "2025-03-17T23:55:41.790624",
12
+ "product_name": "Psychedelic Cutting Board",
13
+ "price": "$29.99",
14
+ "quantity": 4
15
+ },
16
+ {
17
+ "username": "testtt",
18
+ "timestamp": "2025-03-17T23:55:41.790624",
19
+ "product_name": "Psychedelic Cutting Board",
20
+ "price": "$29.99",
21
+ "quantity": 5
22
+ },
23
+ {
24
+ "username": "testtt",
25
+ "timestamp": "2025-03-27T23:55:41.790624",
26
+ "product_name": "Psychedelic Cutting Board",
27
+ "price": "$29.99",
28
+ "quantity": 2
29
+ }
30
+ ]
pages/cutting_boards.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yaml
3
+ import os
4
+ import base64
5
+ import json
6
+ from datetime import datetime
7
+
8
+ # Define file paths
9
+ icon_path = "pages/config/images/icon2.png"
10
+ css_path = "pages/styles/page_style1.css"
11
+ yaml_file_path = "pages/config/items/images_config_cuttting_boards.yml"
12
+ CART_FILE = "pages/config/cart_data.json"
13
+ logged_user_file = "config/logged_in_user.yml"
14
+
15
+ # Function to load an image as base64
16
+
17
+
18
+ def load_image_as_base64(image_path):
19
+ with open(image_path, "rb") as img_file:
20
+ return base64.b64encode(img_file.read()).decode()
21
+
22
+
23
+ # Load the icon image as base64
24
+ icon_base64 = load_image_as_base64(icon_path)
25
+
26
+ # Function to load CSS from file
27
+
28
+
29
+ def load_css(file_path):
30
+ with open(file_path, "r") as f:
31
+ return f"<style>{f.read()}</style>"
32
+
33
+
34
+ st.markdown(load_css(css_path), unsafe_allow_html=True)
35
+
36
+ # Function to load the logged-in user from YAML
37
+
38
+
39
+ def load_logged_in_user():
40
+ if os.path.exists(logged_user_file):
41
+ with open(logged_user_file, "r") as f:
42
+ data = yaml.safe_load(f)
43
+ return data.get("username", "guest")
44
+ return "guest"
45
+
46
+
47
+ # Use the logged-in user automatically
48
+ username = load_logged_in_user()
49
+
50
+ # Functions to load and save cart data from/to JSON file
51
+
52
+
53
+ def load_cart_data():
54
+ if os.path.exists(CART_FILE):
55
+ with open(CART_FILE, "r") as f:
56
+ try:
57
+ return json.load(f)
58
+ except json.JSONDecodeError:
59
+ return []
60
+ return []
61
+
62
+
63
+ def save_cart_data(data):
64
+ with open(CART_FILE, "w") as f:
65
+ json.dump(data, f, indent=4)
66
+
67
+
68
+ # Header Section with Icon and Title
69
+ st.markdown(f"""
70
+ <style>
71
+ .title-container {{
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ background-color: #444;
76
+ padding: 15px 30px;
77
+ border-radius: 15px;
78
+ box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
79
+ margin-bottom: 30px;
80
+ border: 2px solid #007BFF;
81
+ }}
82
+ .title-icon {{
83
+ width: 80px;
84
+ height: 80px;
85
+ background-image: url(data:image/png;base64,{icon_base64});
86
+ background-size: cover;
87
+ }}
88
+ .title-text {{
89
+ font-size: 2.5em;
90
+ font-weight: bold;
91
+ color: white;
92
+ margin: 0 40px; /* Adds space between the icons and text */
93
+ transition: color 0.3s ease;
94
+ }}
95
+ .title-container:hover .title-text {{
96
+ color: #007BFF;
97
+ }}
98
+ </style>
99
+ <div class="title-container">
100
+ <div class="title-icon"></div>
101
+ <div class="title-text">Charcuterie Boards: Elevate Your Presentation</div>
102
+ <div class="title-icon"></div>
103
+ </div>
104
+ """, unsafe_allow_html=True)
105
+
106
+
107
+ # Load product data from YAML file
108
+ if not os.path.exists(yaml_file_path):
109
+ st.error("Configuration file not found!")
110
+ st.stop()
111
+
112
+ with open(yaml_file_path, "r") as file:
113
+ product_data = yaml.safe_load(file)
114
+
115
+ # Filter products (if 'category' equals "print", otherwise use all products)
116
+ prints = {name: info for name, info in product_data["items"].items(
117
+ ) if info.get("category", "") == "print"} or product_data["items"]
118
+
119
+ # Display products in a structured container
120
+ total_products = len(prints)
121
+ num_columns = 3
122
+
123
+ with st.container(border=True):
124
+ for i in range(0, total_products, num_columns):
125
+ cols = st.columns(num_columns)
126
+ for j in range(num_columns):
127
+ if i + j < total_products:
128
+ product_name = list(prints.keys())[i + j]
129
+ product_info = prints[product_name]
130
+ with cols[j]:
131
+ with st.container(border=True):
132
+ st.markdown(f"""
133
+ <div class="product-card">
134
+ <h3>{product_name}</h3>
135
+ <p><b>{product_info['price']}</b></p>
136
+ </div>
137
+ """, unsafe_allow_html=True)
138
+ st.image(product_info["image_path"],
139
+ use_container_width=True)
140
+
141
+ with st.expander("View Details"):
142
+ st.subheader(product_name)
143
+ st.write(f"**Price:** {product_info['price']}")
144
+ st.write(product_info["description"])
145
+
146
+ quantity = st.number_input(
147
+ "Quantity:", min_value=1, value=1, step=1, key=f"quantity_{i + j}")
148
+ if st.button("🛒 Add to Cart", key=f"btn_{i + j}"):
149
+ # Create a new cart entry with username, timestamp, and product details
150
+ new_entry = {
151
+ "username": username,
152
+ "timestamp": datetime.now().isoformat(),
153
+ "product_name": product_name,
154
+ "price": product_info["price"],
155
+ "quantity": quantity
156
+ }
157
+ # Optionally, update session state for the current session cart
158
+ if 'cart' not in st.session_state:
159
+ st.session_state.cart = []
160
+ st.session_state.cart.append(new_entry)
161
+
162
+ # Append the new entry to the persistent cart JSON file
163
+ cart_data = load_cart_data()
164
+ cart_data.append(new_entry)
165
+ save_cart_data(cart_data)
166
+
167
+ st.success(
168
+ f"Added {quantity} {product_name} to cart!")
169
+
170
+ # Footer Section
171
+ st.markdown("""
172
+ <div class="footer-container">
173
+ <p>&copy; 2025 Charcuterie Boards Store. All rights reserved.</p>
174
+ </div>
175
+ """, unsafe_allow_html=True)
pages/home.py CHANGED
@@ -1,147 +1,58 @@
1
  import streamlit as st
 
2
  import yaml
3
- import os
4
 
5
- # Add custom CSS
6
- st.markdown("""
7
- <style>
8
- .stButton button {
9
- background-color: #1E90FF; /* Dodger Blue */
10
- color: white;
11
- border-radius: 8px;
12
- padding: 10px 24px;
13
- font-weight: bold;
14
- border: none;
15
- }
16
- .stButton button:hover {
17
- background-color: #007ACC; /* Darker blue on hover */
18
- }
19
- .product-card {
20
- border: 1px solid #eee;
21
- border-radius: 10px;
22
- padding: 10px;
23
- transition: transform 0.3s;
24
- }
25
- .product-card:hover {
26
- transform: scale(1.02);
27
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
28
- }
29
- .category-header {
30
- text-align: center;
31
- margin-bottom: 30px;
32
- color: #333;
33
- }
34
- /* New styles for cart controls */
35
- .cart-controls {
36
- display: flex;
37
- align-items: center;
38
- justify-content: space-between;
39
- margin-top: 10px;
40
- }
41
- .quantity-selector {
42
- border-radius: 8px;
43
- border: 1px solid #ddd;
44
- padding: 5px;
45
- width: 100%;
46
- }
47
- .add-to-cart-btn {
48
- width: 100%;
49
- margin-top: 10px;
50
- }
51
- </style>
52
- """, unsafe_allow_html=True)
53
 
54
- # Main page header
55
- st.title("🌀 Psychedelic Art Gallery")
56
- st.markdown(
57
- "### Explore our collection of trippy, vibrant artwork and accessories!"
58
- )
59
 
60
- # Load YAML file
61
- yaml_file_path = "/home/vscode/project_assistant_dashboard/pages/config/images_config.yml"
62
- if not os.path.exists(yaml_file_path):
63
- st.error("Configuration file not found!")
64
- st.stop()
 
 
 
65
 
66
- with open(yaml_file_path, "r") as file:
67
- product_data = yaml.safe_load(file)
68
 
69
- # Initialize cart in session state if it doesn't exist
70
- if 'cart' not in st.session_state:
71
- st.session_state.cart = []
72
-
73
- # Function to display featured products
74
-
75
-
76
- def display_featured_products():
77
- cols = st.columns(3)
78
-
79
- # Get first 6 products for featured display
80
- featured_items = {}
81
- count = 0
82
-
83
- for product_name, product_info in product_data["items"].items():
84
- if count < 6:
85
- featured_items[product_name] = product_info
86
- count += 1
87
-
88
- for i, (product_name, product_info) in enumerate(featured_items.items()):
89
- with cols[i % 3]: # Distribute products evenly across columns
90
- st.markdown(f"""
91
- <div class="product-card">
92
- <h3>{product_name}</h3>
93
- <p><b>{product_info['price']}</b></p>
94
- </div>
95
- """, unsafe_allow_html=True)
96
 
97
- st.image(product_info["image_path"], use_container_width=True)
 
 
 
 
 
 
 
98
 
99
- with st.expander("View Details & Add to Cart"):
100
- st.subheader(product_name)
101
- st.write(f"**Price:** {product_info['price']}")
102
- st.write(product_info["description"])
103
 
104
- # Create two columns for quantity and add button
105
- qty_col, btn_col = st.columns([1, 1])
106
 
107
- with qty_col:
108
- quantity = st.number_input(
109
- "Quantity",
110
- min_value=1,
111
- value=1,
112
- step=1,
113
- key=f"quantity_{i}",
114
- label_visibility="collapsed"
115
- )
116
-
117
- with btn_col:
118
- if st.button("Add to Cart", key=f"btn_{i}"):
119
- st.session_state.cart.append({
120
- "name": product_name,
121
- "price": product_info['price'],
122
- "quantity": quantity
123
- })
124
- st.toast(f"Added {quantity} {product_name} to cart!")
125
- st.rerun()
126
-
127
-
128
- # Display featured products
129
- st.markdown("<h2 class='category-header'>🔥 Featured Collection</h2>",
130
- unsafe_allow_html=True)
131
- display_featured_products()
132
-
133
- # Category quick links
134
- st.markdown("## Explore Categories")
135
- col1, col2, col3 = st.columns(3)
136
-
137
- with col1:
138
- st.page_link("pages/prints.py", label="Prints Collection", icon="🖼️")
139
- with col2:
140
- st.page_link("pages/clothing.py", label="Clothing Collection", icon="👕")
141
- with col3:
142
- st.page_link("pages/accessories.py",
143
- label="Accessories Collection", icon="🧢")
144
-
145
- # Footer
146
- st.markdown("---")
147
- st.markdown("© 2025 Psychedelic Art Gallery. All rights reserved.")
 
1
  import streamlit as st
2
+ import json
3
  import yaml
 
4
 
5
+ # Load logged-in user data from YAML file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
 
 
 
 
 
7
 
8
+ def load_logged_in_user():
9
+ user_file = "/home/vscode/Brads_Store/config/logged_in_user.yml"
10
+ try:
11
+ with open(user_file, "r") as file:
12
+ user_data = yaml.safe_load(file)
13
+ return user_data.get("username", "")
14
+ except FileNotFoundError:
15
+ return ""
16
 
17
+ # Load cart data from JSON file, filtered by logged-in user
 
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ def load_cart_data(username):
21
+ cart_file = "/home/vscode/Brads_Store/pages/config/cart_data.json"
22
+ try:
23
+ with open(cart_file, "r") as file:
24
+ cart_data = json.load(file)
25
+ return [item for item in cart_data if item.get("username") == username]
26
+ except FileNotFoundError:
27
+ return []
28
 
29
+ # Get logged-in user
30
+ logged_in_user = load_logged_in_user()
 
 
31
 
32
+ # Display logged-in user
33
+ st.sidebar.subheader(f"Logged in as: {logged_in_user}")
34
 
35
+ # Initialize session state variables
36
+ if 'cart' not in st.session_state:
37
+ st.session_state.cart = load_cart_data(logged_in_user)
38
+
39
+ st.title("Shopping Cart Test Page")
40
+
41
+ # Display Cart Items
42
+ st.subheader("Your Cart Items")
43
+ if not st.session_state.cart:
44
+ st.write("Your cart is empty.")
45
+ else:
46
+ for i, item in enumerate(st.session_state.cart):
47
+ st.write(
48
+ f"{item['product_name']} - {item['price']} x {item.get('quantity', 1)}")
49
+
50
+ # Refresh Cart Data Button
51
+ if st.button("Reload Cart Data"):
52
+ st.session_state.cart = load_cart_data(logged_in_user)
53
+ st.rerun()
54
+
55
+ # Total Calculation
56
+ total = sum(float(item["price"].replace("$", "")) *
57
+ item.get("quantity", 1) for item in st.session_state.cart)
58
+ st.subheader(f"Total: ${total:.2f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/login_page.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yaml
3
+ import hashlib
4
+ import os
5
+
6
+ # File paths
7
+ USERS_FILE = "/home/vscode/Brads_Store/pages/config/users.yml"
8
+ LOGGED_IN_FILE = "/home/vscode/Brads_Store/config/logged_in_user.yml"
9
+
10
+ # Load users from YAML file
11
+
12
+
13
+ def load_users():
14
+ with open(USERS_FILE, "r") as file:
15
+ return yaml.safe_load(file)["users"]
16
+
17
+ # Save users to YAML file
18
+
19
+
20
+ def save_users(users):
21
+ with open(USERS_FILE, "w") as file:
22
+ yaml.dump({"users": users}, file)
23
+
24
+ # Save logged in user
25
+
26
+
27
+ def save_logged_in_user(username, role):
28
+ # Create directory if it doesn't exist
29
+ os.makedirs(os.path.dirname(LOGGED_IN_FILE), exist_ok=True)
30
+ with open(LOGGED_IN_FILE, "w") as file:
31
+ yaml.dump({"username": username, "role": role}, file)
32
+
33
+ # Hash function for passwords
34
+
35
+
36
+ def hash_password(password):
37
+ return hashlib.sha256(password.encode()).hexdigest()
38
+
39
+ # Authenticate user
40
+
41
+
42
+ def authenticate(username, password):
43
+ users = load_users()
44
+ for user in users:
45
+ if user["username"] == username and user["password"] == password:
46
+ return user["role"]
47
+ return None
48
+
49
+ # Add new user
50
+
51
+
52
+ def add_user(username, password, role):
53
+ users = load_users()
54
+ if any(user["username"] == username for user in users):
55
+ return False # Username already exists
56
+ users.append({"username": username, "password": password, "role": role})
57
+ save_users(users)
58
+ return True
59
+
60
+
61
+ # Streamlit UI
62
+ st.title("Login Page")
63
+ username = st.text_input("Username")
64
+ password = st.text_input("Password", type="password")
65
+
66
+ if st.button("Login"):
67
+ role = authenticate(username, password)
68
+ if role:
69
+ save_logged_in_user(username, role)
70
+ st.success(f"Welcome, {username}! Role: {role}")
71
+ st.session_state.logged_in = True
72
+ st.session_state.username = username
73
+ st.session_state.role = role
74
+ else:
75
+ st.error("Invalid username or password")
76
+
77
+ # Add New User section in a popover
78
+ with st.popover("Add New User"):
79
+ new_username = st.text_input("New Username")
80
+ new_password = st.text_input("New Password", type="password")
81
+ confirm_password = st.text_input("Confirm Password", type="password")
82
+ new_role = st.selectbox("Role", ["user", "admin"])
83
+
84
+ # Check if passwords match
85
+ passwords_match = new_password == confirm_password
86
+
87
+ # Show match status if both fields have input
88
+ if new_password and confirm_password:
89
+ if passwords_match:
90
+ st.success("Passwords match!")
91
+ else:
92
+ st.warning("Sorry, the passwords didn't match")
93
+
94
+ if st.button("Add User"):
95
+ if not new_username or not new_password:
96
+ st.error("Username and password are required")
97
+ elif not passwords_match:
98
+ st.error("Passwords do not match. Please try again.")
99
+ elif add_user(new_username, new_password, new_role):
100
+ # Log in the new user automatically
101
+ save_logged_in_user(new_username, new_role)
102
+ st.success(
103
+ f"User added successfully! You are now logged in as {new_username}")
104
+ st.session_state.logged_in = True
105
+ st.session_state.username = new_username
106
+ st.session_state.role = new_role
107
+ st.rerun() # Rerun the app to update the UI
108
+ else:
109
+ st.error("Username already exists. Please choose a different one.")
110
+
111
+ # Display logged in status if in session state
112
+ if st.session_state.get('logged_in'):
113
+ st.sidebar.success(f"Logged in as: {st.session_state.username}")
114
+ if st.sidebar.button("Log out"):
115
+ # Clear the logged in user file
116
+ if os.path.exists(LOGGED_IN_FILE):
117
+ os.remove(LOGGED_IN_FILE)
118
+ # Clear session state
119
+ st.session_state.logged_in = False
120
+ st.session_state.pop('username', None)
121
+ st.session_state.pop('role', None)
122
+ st.rerun()
pages/prints.py DELETED
@@ -1,62 +0,0 @@
1
- import streamlit as st
2
- import yaml
3
- import os
4
-
5
- # Page header
6
- st.title("🖼️ Prints Collection")
7
- st.markdown("### Vibrant psychedelic prints for your walls")
8
-
9
- # Load YAML file
10
- yaml_file_path = "/home/vscode/Brads_Store/pages/config/images_config_cuttting_boards.yml"
11
- if not os.path.exists(yaml_file_path):
12
- st.error("Configuration file not found!")
13
- st.stop()
14
-
15
- with open(yaml_file_path, "r") as file:
16
- product_data = yaml.safe_load(file)
17
-
18
- # Filter for prints only (assuming you have a category field in your YAML)
19
- prints = {}
20
- for product_name, product_info in product_data["items"].items():
21
- if product_info.get("category", "") == "print":
22
- prints[product_name] = product_info
23
-
24
- # If no prints found, show all products
25
- if not prints:
26
- prints = product_data["items"]
27
-
28
- # Display prints
29
- cols = st.columns(3)
30
- for i, (product_name, product_info) in enumerate(prints.items()):
31
- with cols[i % 3]:
32
- st.markdown(f"""
33
- <div class="product-card">
34
- <h3>{product_name}</h3>
35
- <p><b>{product_info['price']}</b></p>
36
- </div>
37
- """, unsafe_allow_html=True)
38
-
39
- st.image(product_info["image_path"], use_container_width=True)
40
-
41
- with st.popover("View Details"):
42
- st.subheader(product_name)
43
- st.write(f"**Price:** {product_info['price']}")
44
- st.write(product_info["description"])
45
-
46
- # Add quantity selector in popover
47
- quantity = st.number_input(
48
- "Quantity:",
49
- min_value=1,
50
- value=1,
51
- step=1,
52
- key=f"quantity_{i}"
53
- )
54
-
55
- if st.button("🛒 Add to Cart", key=f"btn_{i}"):
56
- st.session_state.cart.append({
57
- "name": product_name,
58
- "price": product_info['price'],
59
- "quantity": quantity
60
- })
61
- st.toast(f"Added {quantity} {product_name} to cart!")
62
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/styles/page_style1.css ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* styles.css */
2
+ .title-container {
3
+ display: flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ background-color: #444;
7
+ padding: 10px 20px;
8
+ border-radius: 15px;
9
+ transition: background-color 0.3s ease, transform 0.3s ease;
10
+ box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
11
+ margin-bottom: 30px;
12
+ border: 2px solid #007BFF;
13
+ }
14
+
15
+ .title-icon {
16
+ width: 80px;
17
+ height: 80px;
18
+ background-size: cover;
19
+ margin: 0 15px;
20
+ transition: transform 0.5s ease;
21
+ background-image: url(data:image/png;base64, /* your base64 encoded image here */);
22
+ }
23
+
24
+ .title-container:hover .title-icon {
25
+ transform: rotate(360deg);
26
+ }
27
+
28
+ .title-text {
29
+ font-size: 2.5em;
30
+ font-weight: bold;
31
+ color: white;
32
+ transition: color 0.3s ease;
33
+ }
34
+
35
+ .title-container:hover .title-text {
36
+ color: #007BFF;
37
+ }
38
+
39
+ .product-card {
40
+ text-align: center;
41
+ margin-bottom: 20px;
42
+ padding: 15px;
43
+ border: 2px solid #007BFF;
44
+ border-radius: 10px;
45
+ background-color: #444;
46
+ color: white;
47
+ }
48
+
49
+ .product-card h3 {
50
+ background-color: #444;
51
+ color: white;
52
+ padding: 10px;
53
+ border-radius: 5px;
54
+ }
55
+
56
+ .product-card p {
57
+ background-color: #444;
58
+ color: white;
59
+ padding: 5px;
60
+ border-radius: 5px;
61
+ display: inline-block;
62
+ font-weight: bold;
63
+ }
64
+
65
+ .footer-container {
66
+ text-align: center;
67
+ padding: 20px;
68
+ background-color: #222;
69
+ color: white;
70
+ border-top: 2px solid #007BFF;
71
+ margin-top: 30px;
72
+ }
prompts/customer_service_prompt.txt ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ You are an AI-powered customer service assistant for a website. Your primary role is to assist users by answering their questions, providing relevant information, and helping them navigate the website. You should always be professional, polite, and helpful.
2
+
3
+ How to Use Information:
4
+ You will be provided with a separate reference document containing detailed information about the website, its products, services, policies, and other relevant topics. Use this reference information to generate responses when applicable. Do not disclose the full contents of the reference document unless explicitly asked. Instead, summarize or provide answers based on the user’s question.
5
+
6
+ Response Guidelines:
7
+
8
+ Prioritize User Input – The user’s message is the most important factor in generating responses.
9
+ Be Concise but Informative – Provide clear and accurate answers without overwhelming the user with unnecessary details.
10
+ Use a Friendly and Professional Tone – Responses should be courteous and engaging.
11
+ Acknowledge Limitations – If you do not have information, politely guide the user to customer support or relevant resources.
12
+ Adapt to the User's Needs – Adjust responses based on the user’s tone and question complexity.
13
+ Example Scenarios:
14
+
15
+ If a user asks about a product, refer to the product details in the reference document.
16
+ If a user has a technical issue, guide them through troubleshooting steps.
17
+ If a user inquires about company policies, summarize key points from the reference document.
18
+ If the user asks for something beyond your knowledge, suggest alternative support channels.
19
+ Example User Interactions:
20
+
21
+ User: “What is your return policy?”
22
+ AI: “Our return policy allows returns within 30 days of purchase. Items must be in their original condition. Would you like me to provide more details or help with a return request?”
23
+
24
+ User: “Tell me about [Product X].”
25
+ AI: “Certainly! [Product X] is designed for [feature overview]. It includes [key features] and is available for [pricing]. Would you like to know about shipping options?”
26
+
27
+ User: “Can I speak to a human representative?”
28
+ AI: “Of course! You can reach our customer support team at [contact info] or via live chat. Is there anything I can assist you with in the meantime?”
search_results.txt CHANGED
@@ -1,27 +1 @@
1
- Search Query: training an image classification model
2
- ==================================================
3
- Result 1: Create_a_dataset_for_training.txt
4
- Similarity Score: 0.3584
5
- Full Content:
6
- Create a dataset for training Hugging Face Models Datasets Spaces Posts Docs Enterprise Pricing Log In Sign Up Diffusers documentation Create a dataset for training Diffusers 🏡 View all docs AWS Trainium & Inferentia Accelerate Amazon SageMaker Argilla AutoTrain Bitsandbytes Chat UI Competitions Dataset viewer Datasets Diffusers Distilabel Evaluate Google Cloud Google TPUs Gradio Hub Hub Python Library Hugging Face Generative AI Services (HUGS) Huggingface.js Inference API (serverless) Inference Endpoints (dedicated) Leaderboards Lighteval Optimum PEFT Safetensors Sentence Transformers TRL Tasks Text Embeddings Inference Text Generation Inference Tokenizers Transformers Transformers.js smolagents timm Search documentation main v0.32.2 v0.31.0 v0.30.3 v0.29.2 v0.28.2 v0.27.2 v0.26.3 v0.25.1 v0.24.0 v0.23.1 v0.22.3 v0.21.0 v0.20.0 v0.19.3 v0.18.2 v0.17.1 v0.16.0 v0.15.0 v0.14.0 v0.13.0 v0.12.0 v0.11.0 v0.10.2 v0.9.0 v0.8.0 v0.7.0 v0.6.0 v0.5.1 v0.4.1 v0.3.0 v0.2.4 EN JA KO PT ZH Get started 🧨 Diffusers Quicktour Effective and efficient diffusion Installation Tutorials Overview Understanding pipelines, models and schedulers AutoPipeline Train a diffusion model Load LoRAs for inference Accelerate inference of text-to-image diffusion models Working with big models Load pipelines and adapters Load pipelines Load community pipelines and components Load schedulers and models Model files and layouts Load adapters Push files to the Hub Generative tasks Unconditional image generation Text-to-image Image-to-image Inpainting Text or image-to-video Depth-to-image Inference techniques Overview Create a server Distributed inference Merge LoRAs Scheduler features Pipeline callbacks Reproducible pipelines Controlling image quality Prompt techniques Advanced inference Outpainting Specific pipeline examples CogVideoX Stable Diffusion XL SDXL Turbo Kandinsky IP-Adapter PAG ControlNet T2I-Adapter Latent Consistency Model Textual inversion Shap-E DiffEdit Trajectory Consistency Distillation-LoRA Stable Video Diffusion Marigold Computer Vision Training Overview Create a dataset for training Adapt a model to a new task Models Methods Quantization Methods Getting Started bitsandbytes gguf torchao Accelerate inference and reduce memory Speed up inference Reduce memory usage PyTorch 2.0 xFormers Token merging DeepCache TGATE xDiT Optimized model formats JAX/Flax ONNX OpenVINO Core ML Optimized hardware Metal Performance Shaders (MPS) Habana Gaudi AWS Neuron Conceptual Guides Philosophy Controlled generation How to contribute? Diffusers' Ethical Guidelines Evaluating Diffusion Models Community Projects Projects built with Diffusers API Main Classes Loaders Models Pipelines Schedulers Internal classes Join the Hugging Face community and get access to the augmented documentation experience Collaborate on models, datasets and Spaces Faster examples with accelerated inference Switch between documentation themes Sign Up to get started Create a dataset for training There are many datasets on the Hub to train a model on, but if you can’t find one you’re interested in or want to use your own, you can create a dataset with the 🤗 Datasets library. The dataset structure depends on the task you want to train your model on. The most basic dataset structure is a directory of images for tasks like unconditional image generation. Another dataset structure may be a directory of images and a text file containing their corresponding text captions for tasks like text-to-image generation. This guide will show you two ways to create a dataset to finetune on: provide a folder of images to the --train_data_dir argument upload a dataset to the Hub and pass the dataset repository id to the --dataset_name argument 💡 Learn more about how to create an image dataset for training in the Create an image dataset guide. Provide a dataset as a folder For unconditional generation, you can provide your own dataset as a folder of images. The training script uses the ImageFolder builder from 🤗 Datasets to automatically build a dataset from the folder. Your directory structure should look like: Copied data_dir/xxx.png data_dir/xxy.png data_dir/[...]/xxz.png Pass the path to the dataset directory to the --train_data_dir argument, and then you can start training: Copied accelerate launch train_unconditional.py \ --train_data_dir <path-to-train-directory> \ <other-arguments> Upload your data to the Hub 💡 For more details and context about creating and uploading a dataset to the Hub, take a look at the Image search with 🤗 Datasets post. Start by creating a dataset with the ImageFolder feature, which creates an image column containing the PIL-encoded images. You can use the data_dir or data_files parameters to specify the location of the dataset. The data_files parameter supports mapping specific files to dataset splits like train or test : Copied from datasets import load_dataset # example 1: local folder dataset = load_dataset( "imagefolder" , data_dir= "path_to_your_folder" ) # example 2: local files (supported formats are tar, gzip, zip, xz, rar, zstd) dataset = load_dataset( "imagefolder" , data_files= "path_to_zip_file" ) # example 3: remote files (supported formats are tar, gzip, zip, xz, rar, zstd) dataset = load_dataset( "imagefolder" , data_files= "https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip" , ) # example 4: providing several splits dataset = load_dataset( "imagefolder" , data_files={ "train" : [ "path/to/file1" , "path/to/file2" ], "test" : [ "path/to/file3" , "path/to/file4" ]} ) Then use the push_to_hub method to upload the dataset to the Hub: Copied # assuming you have ran the huggingface-cli login command in a terminal dataset.push_to_hub( "name_of_your_dataset" ) # if you want to push to a private repo, simply pass private=True: dataset.push_to_hub( "name_of_your_dataset" , private= True ) Now the dataset is available for training by passing the dataset name to the --dataset_name argument: Copied accelerate launch --mixed_precision= "fp16" train_text_to_image.py \ --pretrained_model_name_or_path= "stable-diffusion-v1-5/stable-diffusion-v1-5" \ --dataset_name= "name_of_your_dataset" \ <other-arguments> Next steps Now that you’ve created a dataset, you can plug it into the train_data_dir (if your dataset is local) or dataset_name (if your dataset is on the Hub) arguments of a training script. For your next steps, feel free to try and use your dataset to train a model for unconditional generation or text-to-image generation ! < > Update on GitHub ← Overview Adapt a model to a new task → Create a dataset for training Provide a dataset as a folder Upload your data to the Hub Next steps
7
- --------------------------------------------------
8
- Result 2: Image_Classification.txt
9
- Similarity Score: 0.3516
10
- Full Content:
11
- Image classification Hugging Face Models Datasets Spaces Posts Docs Enterprise Pricing Log In Sign Up Datasets documentation Image classification Datasets 🏡 View all docs AWS Trainium & Inferentia Accelerate Amazon SageMaker Argilla AutoTrain Bitsandbytes Chat UI Competitions Dataset viewer Datasets Diffusers Distilabel Evaluate Google Cloud Google TPUs Gradio Hub Hub Python Library Hugging Face Generative AI Services (HUGS) Huggingface.js Inference API (serverless) Inference Endpoints (dedicated) Leaderboards Lighteval Optimum PEFT Safetensors Sentence Transformers TRL Tasks Text Embeddings Inference Text Generation Inference Tokenizers Transformers Transformers.js smolagents timm Search documentation main v3.2.0 v3.1.0 v3.0.2 v2.21.0 v2.20.0 v2.19.0 v2.18.0 v2.17.1 v2.16.1 v2.15.0 v2.14.7 v2.13.2 v2.12.0 v2.11.0 v2.10.0 v2.9.0 v2.8.0 v2.7.1 v2.6.2 v2.5.2 v2.4.0 v2.3.2 v2.2.1 v2.1.0 v2.0.0 v1.18.3 v1.17.0 v1.16.1 v1.15.1 v1.14.0 v1.13.3 v1.12.1 v1.11.0 v1.10.2 v1.9.0 v1.8.0 v1.7.0 v1.6.2 v1.5.0 v1.4.1 v1.3.0 v1.2.1 v1.1.3 v1.0.2 v0.4.0 v0.3.0 EN Get started 🤗 Datasets Quickstart Installation Tutorials Overview Load a dataset from the Hub Know your dataset Preprocess Create a dataset Share a dataset to the Hub How-to guides Overview General usage Load Process Stream Use with TensorFlow Use with PyTorch Use with JAX Use with Spark Cache management Cloud storage Search index CLI Troubleshooting Audio Load audio data Process audio data Create an audio dataset Vision Load image data Process image data Create an image dataset Depth estimation Image classification Semantic segmentation Object detection Load video data Create a video dataset Text Load text data Process text data Tabular Load tabular data Dataset repository Share Create a dataset card Structure your repository Create a dataset loading script Conceptual guides Datasets 🤝 Arrow The cache Dataset or IterableDataset Dataset features Build and load Batch mapping Reference Main classes Builder classes Loading methods Table Classes Utilities Join the Hugging Face community and get access to the augmented documentation experience Collaborate on models, datasets and Spaces Faster examples with accelerated inference Switch between documentation themes Sign Up to get started Image classification Image classification datasets are used to train a model to classify an entire image. There are a wide variety of applications enabled by these datasets such as identifying endangered wildlife species or screening for disease in medical images. This guide will show you how to apply transformations to an image classification dataset. Before you start, make sure you have up-to-date versions of albumentations and cv2 installed: Copied pip install -U albumentations opencv-python This guide uses the Beans dataset for identifying the type of bean plant disease based on an image of its leaf. Load the dataset and take a look at an example: Copied >>> from datasets import load_dataset >>> dataset = load_dataset( "beans" ) >>> dataset[ "train" ][ 10 ] { 'image' : <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=500x500 at 0x7F8D2F4D7A10 >, 'image_file_path' : '/root/.cache/huggingface/datasets/downloads/extracted/b0a21163f78769a2cf11f58dfc767fb458fc7cea5c05dccc0144a2c0f0bc1292/train/angular_leaf_spot/angular_leaf_spot_train.204.jpg' , 'labels' : 0 } The dataset has three fields: image : a PIL image object. image_file_path : the path to the image file. labels : the label or category of the image. Next, check out an image: Now apply some augmentations with albumentations . You’ll randomly crop the image, flip it horizontally, and adjust its brightness. Copied >>> import cv2 >>> import albumentations >>> import numpy as np >>> transform = albumentations.Compose([ ... albumentations.RandomCrop(width= 256 , height= 256 ), ... albumentations.HorizontalFlip(p= 0.5 ), ... albumentations.RandomBrightnessContrast(p= 0.2 ), ... ]) Create a function to apply the transformation to the images: Copied >>> def transforms ( examples ): ... examples[ "pixel_values" ] = [ ... transform(image=np.array(image))[ "image" ] for image in examples[ "image" ] ... ] ... ... return examples Use the set_transform() function to apply the transformation on-the-fly to batches of the dataset to consume less disk space: Copied >>> dataset.set_transform(transforms) You can verify the transformation worked by indexing into the pixel_values of the first example: Copied >>> import numpy as np >>> import matplotlib.pyplot as plt >>> img = dataset[ "train" ][ 0 ][ "pixel_values" ] >>> plt.imshow(img) Now that you know how to process a dataset for image classification, learn how to train an image classification model and use it for inference. < > Update on GitHub ← Depth estimation Semantic segmentation → Image classification
12
- --------------------------------------------------
13
- Result 3: Image-to-image.txt
14
- Similarity Score: 0.3497
15
- Full Content:
16
- Image-to-image Hugging Face Models Datasets Spaces Posts Docs Enterprise Pricing Log In Sign Up Diffusers documentation Image-to-image Diffusers 🏡 View all docs AWS Trainium & Inferentia Accelerate Amazon SageMaker Argilla AutoTrain Bitsandbytes Chat UI Competitions Dataset viewer Datasets Diffusers Distilabel Evaluate Google Cloud Google TPUs Gradio Hub Hub Python Library Hugging Face Generative AI Services (HUGS) Huggingface.js Inference API (serverless) Inference Endpoints (dedicated) Leaderboards Lighteval Optimum PEFT Safetensors Sentence Transformers TRL Tasks Text Embeddings Inference Text Generation Inference Tokenizers Transformers Transformers.js smolagents timm Search documentation main v0.32.2 v0.31.0 v0.30.3 v0.29.2 v0.28.2 v0.27.2 v0.26.3 v0.25.1 v0.24.0 v0.23.1 v0.22.3 v0.21.0 v0.20.0 v0.19.3 v0.18.2 v0.17.1 v0.16.0 v0.15.0 v0.14.0 v0.13.0 v0.12.0 v0.11.0 v0.10.2 v0.9.0 v0.8.0 v0.7.0 v0.6.0 v0.5.1 v0.4.1 v0.3.0 v0.2.4 EN JA KO PT ZH Get started 🧨 Diffusers Quicktour Effective and efficient diffusion Installation Tutorials Overview Understanding pipelines, models and schedulers AutoPipeline Train a diffusion model Load LoRAs for inference Accelerate inference of text-to-image diffusion models Working with big models Load pipelines and adapters Load pipelines Load community pipelines and components Load schedulers and models Model files and layouts Load adapters Push files to the Hub Generative tasks Unconditional image generation Text-to-image Image-to-image Inpainting Text or image-to-video Depth-to-image Inference techniques Overview Create a server Distributed inference Merge LoRAs Scheduler features Pipeline callbacks Reproducible pipelines Controlling image quality Prompt techniques Advanced inference Outpainting Specific pipeline examples CogVideoX Stable Diffusion XL SDXL Turbo Kandinsky IP-Adapter PAG ControlNet T2I-Adapter Latent Consistency Model Textual inversion Shap-E DiffEdit Trajectory Consistency Distillation-LoRA Stable Video Diffusion Marigold Computer Vision Training Overview Create a dataset for training Adapt a model to a new task Models Methods Quantization Methods Getting Started bitsandbytes gguf torchao Accelerate inference and reduce memory Speed up inference Reduce memory usage PyTorch 2.0 xFormers Token merging DeepCache TGATE xDiT Optimized model formats JAX/Flax ONNX OpenVINO Core ML Optimized hardware Metal Performance Shaders (MPS) Habana Gaudi AWS Neuron Conceptual Guides Philosophy Controlled generation How to contribute? Diffusers' Ethical Guidelines Evaluating Diffusion Models Community Projects Projects built with Diffusers API Main Classes Loaders Models Pipelines Schedulers Internal classes Join the Hugging Face community and get access to the augmented documentation experience Collaborate on models, datasets and Spaces Faster examples with accelerated inference Switch between documentation themes Sign Up to get started Image-to-image Image-to-image is similar to text-to-image , but in addition to a prompt, you can also pass an initial image as a starting point for the diffusion process. The initial image is encoded to latent space and noise is added to it. Then the latent diffusion model takes a prompt and the noisy latent image, predicts the added noise, and removes the predicted noise from the initial latent image to get the new latent image. Lastly, a decoder decodes the new latent image back into an image. With 🤗 Diffusers, this is as easy as 1-2-3: Load a checkpoint into the AutoPipelineForImage2Image class; this pipeline automatically handles loading the correct pipeline class based on the checkpoint: Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import load_image, make_image_grid pipeline = AutoPipelineForImage2Image.from_pretrained( "kandinsky-community/kandinsky-2-2-decoder" , torch_dtype=torch.float16, use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() You’ll notice throughout the guide, we use enable_model_cpu_offload() and enable_xformers_memory_efficient_attention() , to save memory and increase inference speed. If you’re using PyTorch 2.0, then you don’t need to call enable_xformers_memory_efficient_attention() on your pipeline because it’ll already be using PyTorch 2.0’s native scaled-dot product attention . Load an image to pass to the pipeline: Copied init_image = load_image( "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png" ) Pass a prompt and image to the pipeline to generate an image: Copied prompt = "cat wizard, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney, 8k" image = pipeline(prompt, image=init_image).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) initial image generated image Popular models The most popular image-to-image models are Stable Diffusion v1.5 , Stable Diffusion XL (SDXL) , and Kandinsky 2.2 . The results from the Stable Diffusion and Kandinsky models vary due to their architecture differences and training process; you can generally expect SDXL to produce higher quality images than Stable Diffusion v1.5. Let’s take a quick look at how to use each of these models and compare their results. Stable Diffusion v1.5 Stable Diffusion v1.5 is a latent diffusion model initialized from an earlier checkpoint, and further finetuned for 595K steps on 512x512 images. To use this pipeline for image-to-image, you’ll need to prepare an initial image to pass to the pipeline. Then you can pass a prompt and the image to the pipeline to generate a new image: Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image = pipeline(prompt, image=init_image).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) initial image generated image Stable Diffusion XL (SDXL) SDXL is a more powerful version of the Stable Diffusion model. It uses a larger base model, and an additional refiner model to increase the quality of the base model’s output. Read the SDXL guide for a more detailed walkthrough of how to use this model, and other techniques it uses to produce high quality images. Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stabilityai/stable-diffusion-xl-refiner-1.0" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-sdxl-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image = pipeline(prompt, image=init_image, strength= 0.5 ).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) initial image generated image Kandinsky 2.2 The Kandinsky model is different from the Stable Diffusion models because it uses an image prior model to create image embeddings. The embeddings help create a better alignment between text and images, allowing the latent diffusion model to generate better images. The simplest way to use Kandinsky 2.2 is: Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "kandinsky-community/kandinsky-2-2-decoder" , torch_dtype=torch.float16, use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image = pipeline(prompt, image=init_image).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) initial image generated image Configure pipeline parameters There are several important parameters you can configure in the pipeline that’ll affect the image generation process and image quality. Let’s take a closer look at what these parameters do and how changing them affects the output. Strength strength is one of the most important parameters to consider and it’ll have a huge impact on your generated image. It determines how much the generated image resembles the initial image. In other words: 📈 a higher strength value gives the model more “creativity” to generate an image that’s different from the initial image; a strength value of 1.0 means the initial image is more or less ignored 📉 a lower strength value means the generated image is more similar to the initial image The strength and num_inference_steps parameters are related because strength determines the number of noise steps to add. For example, if the num_inference_steps is 50 and strength is 0.8, then this means adding 40 (50 * 0.8) steps of noise to the initial image and then denoising for 40 steps to get the newly generated image. Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image = pipeline(prompt, image=init_image, strength= 0.8 ).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) strength = 0.4 strength = 0.6 strength = 1.0 Guidance scale The guidance_scale parameter is used to control how closely aligned the generated image and text prompt are. A higher guidance_scale value means your generated image is more aligned with the prompt, while a lower guidance_scale value means your generated image has more space to deviate from the prompt. You can combine guidance_scale with strength for even more precise control over how expressive the model is. For example, combine a high strength + guidance_scale for maximum creativity or use a combination of low strength and low guidance_scale to generate an image that resembles the initial image but is not as strictly bound to the prompt. Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image = pipeline(prompt, image=init_image, guidance_scale= 8.0 ).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) guidance_scale = 0.1 guidance_scale = 5.0 guidance_scale = 10.0 Negative prompt A negative prompt conditions the model to not include things in an image, and it can be used to improve image quality or modify an image. For example, you can improve image quality by including negative prompts like “poor details” or “blurry” to encourage the model to generate a higher quality image. Or you can modify an image by specifying things to exclude from an image. Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stabilityai/stable-diffusion-xl-refiner-1.0" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy" # pass prompt and image to pipeline image = pipeline(prompt, negative_prompt=negative_prompt, image=init_image).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy" negative_prompt = "jungle" Chained image-to-image pipelines There are some other interesting ways you can use an image-to-image pipeline aside from just generating an image (although that is pretty cool too). You can take it a step further and chain it with other pipelines. Text-to-image-to-image Chaining a text-to-image and image-to-image pipeline allows you to generate an image from text and use the generated image as the initial image for the image-to-image pipeline. This is useful if you want to generate an image entirely from scratch. For example, let’s chain a Stable Diffusion and a Kandinsky model. Start by generating an image with the text-to-image pipeline: Copied from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image import torch from diffusers.utils import make_image_grid pipeline = AutoPipelineForText2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() text2image = pipeline( "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" ).images[ 0 ] text2image Now you can pass this generated image to the image-to-image pipeline: Copied pipeline = AutoPipelineForImage2Image.from_pretrained( "kandinsky-community/kandinsky-2-2-decoder" , torch_dtype=torch.float16, use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() image2image = pipeline( "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" , image=text2image).images[ 0 ] make_image_grid([text2image, image2image], rows= 1 , cols= 2 ) Image-to-image-to-image You can also chain multiple image-to-image pipelines together to create more interesting images. This can be useful for iteratively performing style transfer on an image, generating short GIFs, restoring color to an image, or restoring missing areas of an image. Start by generating an image: Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image = pipeline(prompt, image=init_image, output_type= "latent" ).images[ 0 ] It is important to specify output_type="latent" in the pipeline to keep all the outputs in latent space to avoid an unnecessary decode-encode step. This only works if the chained pipelines are using the same VAE. Pass the latent output from this pipeline to the next pipeline to generate an image in a comic book art style : Copied pipeline = AutoPipelineForImage2Image.from_pretrained( "ogkalu/Comic-Diffusion" , torch_dtype=torch.float16 ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # need to include the token "charliebo artstyle" in the prompt to use this checkpoint image = pipeline( "Astronaut in a jungle, charliebo artstyle" , image=image, output_type= "latent" ).images[ 0 ] Repeat one more time to generate the final image in a pixel art style : Copied pipeline = AutoPipelineForImage2Image.from_pretrained( "kohbanye/pixel-art-style" , torch_dtype=torch.float16 ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # need to include the token "pixelartstyle" in the prompt to use this checkpoint image = pipeline( "Astronaut in a jungle, pixelartstyle" , image=image).images[ 0 ] make_image_grid([init_image, image], rows= 1 , cols= 2 ) Image-to-upscaler-to-super-resolution Another way you can chain your image-to-image pipeline is with an upscaler and super-resolution pipeline to really increase the level of details in an image. Start with an image-to-image pipeline: Copied import torch from diffusers import AutoPipelineForImage2Image from diffusers.utils import make_image_grid, load_image pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" # pass prompt and image to pipeline image_1 = pipeline(prompt, image=init_image, output_type= "latent" ).images[ 0 ] It is important to specify output_type="latent" in the pipeline to keep all the outputs in latent space to avoid an unnecessary decode-encode step. This only works if the chained pipelines are using the same VAE. Chain it to an upscaler pipeline to increase the image resolution: Copied from diffusers import StableDiffusionLatentUpscalePipeline upscaler = StableDiffusionLatentUpscalePipeline.from_pretrained( "stabilityai/sd-x2-latent-upscaler" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) upscaler.enable_model_cpu_offload() upscaler.enable_xformers_memory_efficient_attention() image_2 = upscaler(prompt, image=image_1, output_type= "latent" ).images[ 0 ] Finally, chain it to a super-resolution pipeline to further enhance the resolution: Copied from diffusers import StableDiffusionUpscalePipeline super_res = StableDiffusionUpscalePipeline.from_pretrained( "stabilityai/stable-diffusion-x4-upscaler" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) super_res.enable_model_cpu_offload() super_res.enable_xformers_memory_efficient_attention() image_3 = super_res(prompt, image=image_2).images[ 0 ] make_image_grid([init_image, image_3.resize(( 512 , 512 ))], rows= 1 , cols= 2 ) Control image generation Trying to generate an image that looks exactly the way you want can be difficult, which is why controlled generation techniques and models are so useful. While you can use the negative_prompt to partially control image generation, there are more robust methods like prompt weighting and ControlNets. Prompt weighting Prompt weighting allows you to scale the representation of each concept in a prompt. For example, in a prompt like “Astronaut in a jungle, cold color palette, muted colors, detailed, 8k”, you can choose to increase or decrease the embeddings of “astronaut” and “jungle”. The Compel library provides a simple syntax for adjusting prompt weights and generating the embeddings. You can learn how to create the embeddings in the Prompt weighting guide. AutoPipelineForImage2Image has a prompt_embeds (and negative_prompt_embeds if you’re using a negative prompt) parameter where you can pass the embeddings which replaces the prompt parameter. Copied from diffusers import AutoPipelineForImage2Image import torch pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() image = pipeline(prompt_embeds=prompt_embeds, # generated from Compel negative_prompt_embeds=negative_prompt_embeds, # generated from Compel image=init_image, ).images[ 0 ] ControlNet ControlNets provide a more flexible and accurate way to control image generation because you can use an additional conditioning image. The conditioning image can be a canny image, depth map, image segmentation, and even scribbles! Whatever type of conditioning image you choose, the ControlNet generates an image that preserves the information in it. For example, let’s condition an image with a depth map to keep the spatial information in the image. Copied from diffusers.utils import load_image, make_image_grid # prepare image url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png" init_image = load_image(url) init_image = init_image.resize(( 958 , 960 )) # resize to depth image dimensions depth_image = load_image( "https://huggingface.co/lllyasviel/control_v11f1p_sd15_depth/resolve/main/images/control.png" ) make_image_grid([init_image, depth_image], rows= 1 , cols= 2 ) Load a ControlNet model conditioned on depth maps and the AutoPipelineForImage2Image : Copied from diffusers import ControlNetModel, AutoPipelineForImage2Image import torch controlnet = ControlNetModel.from_pretrained( "lllyasviel/control_v11f1p_sd15_depth" , torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline = AutoPipelineForImage2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5" , controlnet=controlnet, torch_dtype=torch.float16, variant= "fp16" , use_safetensors= True ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() Now generate a new image conditioned on the depth map, initial image, and prompt: Copied prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image_control_net = pipeline(prompt, image=init_image, control_image=depth_image).images[ 0 ] make_image_grid([init_image, depth_image, image_control_net], rows= 1 , cols= 3 ) initial image depth image ControlNet image Let’s apply a new style to the image generated from the ControlNet by chaining it with an image-to-image pipeline: Copied pipeline = AutoPipelineForImage2Image.from_pretrained( "nitrosocke/elden-ring-diffusion" , torch_dtype=torch.float16, ) pipeline.enable_model_cpu_offload() # remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed pipeline.enable_xformers_memory_efficient_attention() prompt = "elden ring style astronaut in a jungle" # include the token "elden ring style" in the prompt negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy" image_elden_ring = pipeline(prompt, negative_prompt=negative_prompt, image=image_control_net, strength= 0.45 , guidance_scale= 10.5 ).images[ 0 ] make_image_grid([init_image, depth_image, image_control_net, image_elden_ring], rows= 2 , cols= 2 ) Optimize Running diffusion models is computationally expensive and intensive, but with a few optimization tricks, it is entirely possible to run them on consumer and free-tier GPUs. For example, you can use a more memory-efficient form of attention such as PyTorch 2.0’s scaled-dot product attention or xFormers (you can use one or the other, but there’s no need to use both). You can also offload the model to the GPU while the other pipeline components wait on the CPU. Copied + pipeline.enable_model_cpu_offload() + pipeline.enable_xformers_memory_efficient_attention() With torch.compile , you can boost your inference speed even more by wrapping your UNet with it: Copied pipeline.unet = torch. compile (pipeline.unet, mode= "reduce-overhead" , fullgraph= True ) To learn more, take a look at the Reduce memory usage and Torch 2.0 guides. < > Update on GitHub ← Text-to-image Inpainting → Image-to-image Popular models Stable Diffusion v1.5 Stable Diffusion X L (SDX L) Kandinsky 2.2 Configure pipeline parameters Strength Guidance scale Negative prompt Chained image-to-image pipelines Text-to-image-to-image Image-to-image-to-image Image-to-upscaler-to-super-resolution Control image generation Prompt weighting Control Net Optimize
17
- --------------------------------------------------
18
- Result 4: Use_model_after_training.txt
19
- Similarity Score: 0.3477
20
- Full Content:
21
- Use model after training Hugging Face Models Datasets Spaces Posts Docs Enterprise Pricing Log In Sign Up TRL documentation Use model after training TRL 🏡 View all docs AWS Trainium & Inferentia Accelerate Amazon SageMaker Argilla AutoTrain Bitsandbytes Chat UI Competitions Dataset viewer Datasets Diffusers Distilabel Evaluate Google Cloud Google TPUs Gradio Hub Hub Python Library Hugging Face Generative AI Services (HUGS) Huggingface.js Inference API (serverless) Inference Endpoints (dedicated) Leaderboards Lighteval Optimum PEFT Safetensors Sentence Transformers TRL Tasks Text Embeddings Inference Text Generation Inference Tokenizers Transformers Transformers.js smolagents timm Search documentation main v0.13.0 v0.12.2 v0.11.4 v0.10.1 v0.9.6 v0.8.6 v0.7.11 v0.6.0 v0.5.0 v0.4.7 v0.3.1 v0.2.1 v0.1.1 EN Get started TRL Installation Quickstart Get started with Command Line Interfaces (CLIs) Dataset Formats PPO Training FAQ Use Trained Models Customize the Training Understanding Logs API Trainers AlignProp BCO CPO DDPO DPO Online DPO GKD KTO Nash-MD ORPO PPO PRM Reward RLOO SFT Iterative SFT XPO Model Classes Best of N Sampling Judges Callbacks Data Utilities Text Environments Script Utilities Examples Community Tutorials Example Overview Sentiment Tuning Training with PEFT Detoxifying a Language Model Training StackLlama Learning to Use Tools Multi Adapter RLHF Join the Hugging Face community and get access to the augmented documentation experience Collaborate on models, datasets and Spaces Faster examples with accelerated inference Switch between documentation themes Sign Up to get started Use model after training Once you have trained a model using either the SFTTrainer, PPOTrainer, or DPOTrainer, you will have a fine-tuned model that can be used for text generation. In this section, we’ll walk through the process of loading the fine-tuned model and generating text. If you need to run an inference server with the trained model, you can explore libraries such as text-generation-inference . Load and Generate If you have fine-tuned a model fully, meaning without the use of PEFT you can simply load it like any other language model in transformers. E.g. the value head that was trained during the PPO training is no longer needed and if you load the model with the original transformer class it will be ignored: Copied from transformers import AutoTokenizer, AutoModelForCausalLM model_name_or_path = "kashif/stack-llama-2" #path/to/your/model/or/name/on/hub device = "cpu" # or "cuda" if you have a GPU model = AutoModelForCausalLM.from_pretrained(model_name_or_path).to(device) tokenizer = AutoTokenizer.from_pretrained(model_name_or_path) inputs = tokenizer.encode( "This movie was really" , return_tensors= "pt" ).to(device) outputs = model.generate(inputs) print (tokenizer.decode(outputs[ 0 ])) Alternatively you can also use the pipeline: Copied from transformers import pipeline model_name_or_path = "kashif/stack-llama-2" #path/to/your/model/or/name/on/hub pipe = pipeline( "text-generation" , model=model_name_or_path) print (pipe( "This movie was really" )[ 0 ][ "generated_text" ]) Use Adapters PEFT Copied from peft import PeftConfig, PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer base_model_name = "kashif/stack-llama-2" #path/to/your/model/or/name/on/hub" adapter_model_name = "path/to/my/adapter" model = AutoModelForCausalLM.from_pretrained(base_model_name) model = PeftModel.from_pretrained(model, adapter_model_name) tokenizer = AutoTokenizer.from_pretrained(base_model_name) You can also merge the adapters into the base model so you can use the model like a normal transformers model, however the checkpoint will be significantly bigger: Copied model = AutoModelForCausalLM.from_pretrained(base_model_name) model = PeftModel.from_pretrained(model, adapter_model_name) model = model.merge_and_unload() model.save_pretrained( "merged_adapters" ) Once you have the model loaded and either merged the adapters or keep them separately on top you can run generation as with a normal model outlined above. < > Update on GitHub ← PPO Training FAQ Customize the Training → Use model after training Load and Generate Use Adapters PEFT
22
- --------------------------------------------------
23
- Result 5: Training_on_TPU_with_TensorFlow.txt
24
- Similarity Score: 0.3368
25
- Full Content:
26
- Training on TPU with TensorFlow Hugging Face Models Datasets Spaces Posts Docs Enterprise Pricing Log In Sign Up Transformers documentation Training on TPU with TensorFlow Transformers 🏡 View all docs AWS Trainium & Inferentia Accelerate Amazon SageMaker Argilla AutoTrain Bitsandbytes Chat UI Competitions Dataset viewer Datasets Diffusers Distilabel Evaluate Google Cloud Google TPUs Gradio Hub Hub Python Library Hugging Face Generative AI Services (HUGS) Huggingface.js Inference API (serverless) Inference Endpoints (dedicated) Leaderboards Lighteval Optimum PEFT Safetensors Sentence Transformers TRL Tasks Text Embeddings Inference Text Generation Inference Tokenizers Transformers Transformers.js smolagents timm Search documentation main v4.48.0 v4.47.1 v4.46.3 v4.45.2 v4.44.2 v4.43.4 v4.42.4 v4.41.2 v4.40.2 v4.39.3 v4.38.2 v4.37.2 v4.36.1 v4.35.2 v4.34.1 v4.33.3 v4.32.1 v4.31.0 v4.30.0 v4.29.1 v4.28.1 v4.27.2 v4.26.1 v4.25.1 v4.24.0 v4.23.1 v4.22.2 v4.21.3 v4.20.1 v4.19.4 v4.18.0 v4.17.0 v4.16.2 v4.15.0 v4.14.1 v4.13.0 v4.12.5 v4.11.3 v4.10.1 v4.9.2 v4.8.2 v4.7.0 v4.6.0 v4.5.1 v4.4.2 v4.3.3 v4.2.2 v4.1.1 v4.0.1 v3.5.1 v3.4.0 v3.3.1 v3.2.0 v3.1.0 v3.0.2 v2.11.0 v2.10.0 v2.9.1 v2.8.0 v2.7.0 v2.6.0 v2.5.1 v2.4.1 v2.3.0 v2.2.2 v2.1.1 v2.0.0 v1.2.0 v1.1.0 v1.0.0 doc-builder-html AR DE EN ES FR HI IT JA KO PT TE TR ZH Get started 🤗 Transformers Quick tour Installation Adding a new model to `transformers` Tutorials Run inference with pipelines Write portable code with AutoClass Preprocess data Fine-tune a pretrained model Train with a script Set up distributed training with 🤗 Accelerate Load and train adapters with 🤗 PEFT Share your model Agents 101 Agents, supercharged - Multi-agents, External tools, and more Generation with LLMs Chatting with Transformers Task Guides Natural Language Processing Audio Computer Vision Multimodal Generation Prompting Developer guides Use fast tokenizers from 🤗 Tokenizers Run inference with multilingual models Use model-specific APIs Share a custom model Chat templates Trainer Run training on Amazon SageMaker Export to ONNX Export to TFLite Export to TorchScript Benchmarks Notebooks with examples Community resources Troubleshoot Interoperability with GGUF files Interoperability with TikToken files Modularity in `transformers` Model Hacking (overwriting a class to your usage) Quantization Methods Getting started bitsandbytes GPTQ AWQ AQLM VPTQ Quanto EETQ HIGGS HQQ FBGEMM_FP8 Optimum TorchAO BitNet compressed-tensors Contribute new quantization method Performance and scalability Overview LLM inference optimization Efficient training techniques Methods and tools for efficient training on a single GPU Multiple GPUs and parallelism Fully Sharded Data Parallel DeepSpeed Efficient training on CPU Distributed CPU training Training on TPU with TensorFlow PyTorch training on Apple silicon Custom hardware for training Hyperparameter Search using Trainer API Optimizing inference CPU inference GPU inference Multi-GPU inference Instantiate a big model Debugging XLA Integration for TensorFlow Models Optimize inference using `torch.compile()` Contribute How to contribute to 🤗 Transformers? How to add a model to 🤗 Transformers? How to add a pipeline to 🤗 Transformers? Testing Checks on a Pull Request Conceptual guides Philosophy Glossary What 🤗 Transformers can do How 🤗 Transformers solve tasks The Transformer model family Summary of the tokenizers Attention mechanisms Padding and truncation BERTology Perplexity of fixed-length models Pipelines for webserver inference Model training anatomy Getting the most out of LLMs API Main Classes Agents and Tools Auto Classes Backbones Callbacks Configuration Data Collator Keras callbacks Logging Models Text Generation ONNX Optimization Model outputs Pipelines Processors Quantization Tokenizer Trainer DeepSpeed ExecuTorch Feature Extractor Image Processor Models Text models Vision models Audio models Video models Multimodal models Reinforcement learning models Time series models Graph models Internal Helpers Custom Layers and Utilities Utilities for pipelines Utilities for Tokenizers Utilities for Trainer Utilities for Generation Utilities for Image Processors Utilities for Audio processing General Utilities Utilities for Time Series Join the Hugging Face community and get access to the augmented documentation experience Collaborate on models, datasets and Spaces Faster examples with accelerated inference Switch between documentation themes Sign Up to get started Training on TPU with TensorFlow If you don’t need long explanations and just want TPU code samples to get started with, check out our TPU example notebook! What is a TPU? A TPU is a Tensor Processing Unit. They are hardware designed by Google, which are used to greatly speed up the tensor computations within neural networks, much like GPUs. They can be used for both network training and inference. They are generally accessed through Google’s cloud services, but small TPUs can also be accessed directly for free through Google Colab and Kaggle Kernels. Because all TensorFlow models in 🤗 Transformers are Keras models , most of the methods in this document are generally applicable to TPU training for any Keras model! However, there are a few points that are specific to the HuggingFace ecosystem (hug-o-system?) of Transformers and Datasets, and we’ll make sure to flag them up when we get to them. What kinds of TPU are available? New users are often very confused by the range of TPUs, and the different ways to access them. The first key distinction to understand is the difference between TPU Nodes and TPU VMs. When you use a TPU Node , you are effectively indirectly accessing a remote TPU. You will need a separate VM, which will initialize your network and data pipeline and then forward them to the remote node. When you use a TPU on Google Colab, you are accessing it in the TPU Node style. Using TPU Nodes can have some quite unexpected behaviour for people who aren’t used to them! In particular, because the TPU is located on a physically different system to the machine you’re running your Python code on, your data cannot be local to your machine - any data pipeline that loads from your machine’s internal storage will totally fail! Instead, data must be stored in Google Cloud Storage where your data pipeline can still access it, even when the pipeline is running on the remote TPU node. If you can fit all your data in memory as np.ndarray or tf.Tensor , then you can fit() on that data even when using Colab or a TPU Node, without needing to upload it to Google Cloud Storage. 🤗Specific Hugging Face Tip🤗: The methods Dataset.to_tf_dataset() and its higher-level wrapper model.prepare_tf_dataset() , which you will see throughout our TF code examples, will both fail on a TPU Node. The reason for this is that even though they create a tf.data.Dataset it is not a “pure” tf.data pipeline and uses tf.numpy_function or Dataset.from_generator() to stream data from the underlying HuggingFace Dataset . This HuggingFace Dataset is backed by data that is on a local disc and which the remote TPU Node will not be able to read. The second way to access a TPU is via a TPU VM. When using a TPU VM, you connect directly to the machine that the TPU is attached to, much like training on a GPU VM. TPU VMs are generally easier to work with, particularly when it comes to your data pipeline. All of the above warnings do not apply to TPU VMs! This is an opinionated document, so here’s our opinion: Avoid using TPU Node if possible. It is more confusing and more difficult to debug than TPU VMs. It is also likely to be unsupported in future - Google’s latest TPU, TPUv4, can only be accessed as a TPU VM, which suggests that TPU Nodes are increasingly going to become a “legacy” access method. However, we understand that the only free TPU access is on Colab and Kaggle Kernels, which uses TPU Node - so we’ll try to explain how to handle it if you have to! Check the TPU example notebook for code samples that explain this in more detail. What sizes of TPU are available? A single TPU (a v2-8/v3-8/v4-8) runs 8 replicas. TPUs exist in pods that can run hundreds or thousands of replicas simultaneously. When you use more than a single TPU but less than a whole pod (for example, a v3-32), your TPU fleet is referred to as a pod slice. When you access a free TPU via Colab, you generally get a single v2-8 TPU. I keep hearing about this XLA thing. What’s XLA, and how does it relate to TPUs? XLA is an optimizing compiler, used by both TensorFlow and JAX. In JAX it is the only compiler, whereas in TensorFlow it is optional (but mandatory on TPU!). The easiest way to enable it when training a Keras model is to pass the argument jit_compile=True to model.compile() . If you don’t get any errors and performance is good, that’s a great sign that you’re ready to move to TPU! Debugging on TPU is generally a bit harder than on CPU/GPU, so we recommend getting your code running on CPU/GPU with XLA first before trying it on TPU. You don’t have to train for long, of course - just for a few steps to make sure that your model and data pipeline are working like you expect them to. XLA compiled code is usually faster - so even if you’re not planning to run on TPU, adding jit_compile=True can improve your performance. Be sure to note the caveats below about XLA compatibility, though! Tip born of painful experience: Although using jit_compile=True is a good way to get a speed boost and test if your CPU/GPU code is XLA-compatible, it can actually cause a lot of problems if you leave it in when actually training on TPU. XLA compilation will happen implicitly on TPU, so remember to remove that line before actually running your code on a TPU! How do I make my model XLA compatible? In many cases, your code is probably XLA-compatible already! However, there are a few things that work in normal TensorFlow that don’t work in XLA. We’ve distilled them into three core rules below: 🤗Specific HuggingFace Tip🤗: We’ve put a lot of effort into rewriting our TensorFlow models and loss functions to be XLA-compatible. Our models and loss functions generally obey rule #1 and #2 by default, so you can skip over them if you’re using transformers models. Don’t forget about these rules when writing your own models and loss functions, though! XLA Rule #1: Your code cannot have “data-dependent conditionals” What that means is that any if statement cannot depend on values inside a tf.Tensor . For example, this code block cannot be compiled with XLA! Copied if tf.reduce_sum(tensor) > 10 : tensor = tensor / 2.0 This might seem very restrictive at first, but most neural net code doesn’t need to do this. You can often get around this restriction by using tf.cond (see the documentation here ) or by removing the conditional and finding a clever math trick with indicator variables instead, like so: Copied sum_over_10 = tf.cast(tf.reduce_sum(tensor) > 10 , tf.float32) tensor = tensor / ( 1.0 + sum_over_10) This code has exactly the same effect as the code above, but by avoiding a conditional, we ensure it will compile with XLA without problems! XLA Rule #2: Your code cannot have “data-dependent shapes” What this means is that the shape of all of the tf.Tensor objects in your code cannot depend on their values. For example, the function tf.unique cannot be compiled with XLA, because it returns a tensor containing one instance of each unique value in the input. The shape of this output will obviously be different depending on how repetitive the input Tensor was, and so XLA refuses to handle it! In general, most neural network code obeys rule #2 by default. However, there are a few common cases where it becomes a problem. One very common one is when you use label masking , setting your labels to a negative value to indicate that those positions should be ignored when computing the loss. If you look at NumPy or PyTorch loss functions that support label masking, you will often see code like this that uses boolean indexing : Copied label_mask = labels >= 0 masked_outputs = outputs[label_mask] masked_labels = labels[label_mask] loss = compute_loss(masked_outputs, masked_labels) mean_loss = torch.mean(loss) This code is totally fine in NumPy or PyTorch, but it breaks in XLA! Why? Because the shape of masked_outputs and masked_labels depends on how many positions are masked - that makes it a data-dependent shape. However, just like for rule #1, we can often rewrite this code to yield exactly the same output without any data-dependent shapes. Copied label_mask = tf.cast(labels >= 0 , tf.float32) loss = compute_loss(outputs, labels) loss = loss * label_mask # Set negative label positions to 0 mean_loss = tf.reduce_sum(loss) / tf.reduce_sum(label_mask) Here, we avoid data-dependent shapes by computing the loss for every position, but zeroing out the masked positions in both the numerator and denominator when we calculate the mean, which yields exactly the same result as the first block while maintaining XLA compatibility. Note that we use the same trick as in rule #1 - converting a tf.bool to tf.float32 and using it as an indicator variable. This is a really useful trick, so remember it if you need to convert your own code to XLA! XLA Rule #3: XLA will need to recompile your model for every different input shape it sees This is the big one. What this means is that if your input shapes are very variable, XLA will have to recompile your model over and over, which will create huge performance problems. This commonly arises in NLP models, where input texts have variable lengths after tokenization. In other modalities, static shapes are more common and this rule is much less of a problem. How can you get around rule #3? The key is padding - if you pad all your inputs to the same length, and then use an attention_mask , you can get the same results as you’d get from variable shapes, but without any XLA issues. However, excessive padding can cause severe slowdown too - if you pad all your samples to the maximum length in the whole dataset, you might end up with batches consisting endless padding tokens, which will waste a lot of compute and memory! There isn’t a perfect solution to this problem. However, you can try some tricks. One very useful trick is to pad batches of samples up to a multiple of a number like 32 or 64 tokens. This often only increases the number of tokens by a small amount, but it hugely reduces the number of unique input shapes, because every input shape now has to be a multiple of 32 or 64. Fewer unique input shapes means fewer XLA compilations! 🤗Specific HuggingFace Tip🤗: Our tokenizers and data collators have methods that can help you here. You can use padding="max_length" or padding="longest" when calling tokenizers to get them to output padded data. Our tokenizers and data collators also have a pad_to_multiple_of argument that you can use to reduce the number of unique input shapes you see! How do I actually train my model on TPU? Once your training is XLA-compatible and (if you’re using TPU Node / Colab) your dataset has been prepared appropriately, running on TPU is surprisingly easy! All you really need to change in your code is to add a few lines to initialize your TPU, and to ensure that your model and dataset are created inside a TPUStrategy scope. Take a look at our TPU example notebook to see this in action! Summary There was a lot in here, so let’s summarize with a quick checklist you can follow when you want to get your model ready for TPU training: Make sure your code follows the three rules of XLA Compile your model with jit_compile=True on CPU/GPU and confirm that you can train it with XLA Either load your dataset into memory or use a TPU-compatible dataset loading approach (see notebook ) Migrate your code either to Colab (with accelerator set to “TPU”) or a TPU VM on Google Cloud Add TPU initializer code (see notebook ) Create your TPUStrategy and make sure dataset loading and model creation are inside the strategy.scope() (see notebook ) Don’t forget to take jit_compile=True out again when you move to TPU! 🙏🙏🙏🥺🥺🥺 Call model.fit() You did it! < > Update on GitHub ← Distributed CPU training PyTorch training on Apple silicon → Training on TP U with Tensor Flow What is a TP U? What kinds of TP U are available? What sizes of TP U are available? I keep hearing about this XL A thing. What’s XL A, and how does it relate to TP Us? How do I make my model XL A compatible? XL A Rule #1: Your code cannot have “data-dependent conditionals” XL A Rule #2: Your code cannot have “data-dependent shapes” XL A Rule #3: XL A will need to recompile your model for every different input shape it sees How do I actually train my model on TP U? Summary
27
- --------------------------------------------------
 
1
+ You are simply answering the question or message that i send to you.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
summary_prompt.txt CHANGED
@@ -1 +1,47 @@
1
- You have been given search results from a txt file. this has already been done and you have it. use this for your response to me.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ You are an advanced AI assistant, designed to assist users with any type of query or task they provide. Your role is to provide clear, concise, and helpful responses based on the user’s input.
2
+
3
+ Instructions:
4
+ - Understand the user's intent and provide relevant information or solutions.
5
+ - Be accurate, informative, and context-aware.
6
+ - If additional clarification is needed, ask the user for more details.
7
+ - Respond in a professional yet conversational tone.
8
+ - If a task requires multiple steps, break it down logically.
9
+ - If the input is unclear, provide the best possible interpretation and suggest refinements.
10
+
11
+ Now, based on the provided user input, generate the best possible response.
12
+
13
+ # Website Details
14
+ Website Name: Brad's Store
15
+ Description: Brad's Store is an online marketplace offering unique handcrafted items, including prints, charcuterie boards, and accessories.
16
+
17
+ So Brad is the owner of the website and the designer and creator. He kicks ass. if anyone asks about the owner just say that he kicks a lot of ass please.
18
+
19
+ # Product Categories
20
+ 1. Prints
21
+ - High-quality psychedelic art prints
22
+ - Various sizes available
23
+ - Printed on premium materials
24
+
25
+ 2. Charcuterie Boards
26
+ - Handcrafted wooden boards
27
+ - Various styles and designs
28
+ - Made from high-quality wood
29
+
30
+ 3. Accessories
31
+ - Unique handcrafted accessories
32
+ - Includes keychains, jewelry, and more
33
+
34
+ # Shopping Cart Information
35
+ - Users can add multiple items to their cart.
36
+ - Quantity can be increased or decreased from the cart sidebar.
37
+ - Items can be removed individually.
38
+ - Checkout process is currently a demo.
39
+
40
+ # User System
41
+ - Users can log in to save their cart and preferences.
42
+ - Logged-in users have a personalized shopping experience.
43
+
44
+ # Contact & Support
45
+ - Email: support@bradsstore.com
46
+ - Phone: +1-234-567-890
47
+ - Live Chat Available on Website
utilities/combine_items.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import yaml
3
+
4
+ # Define directories
5
+ items_dir = "/home/vscode/Brads_Store/pages/config/items"
6
+ output_file = "/home/vscode/Brads_Store/pages/config/combined_items.yml"
7
+
8
+ # Dictionary to hold combined items
9
+ combined_data = {"items": {}}
10
+
11
+ # Iterate through YAML files in the directory
12
+ for filename in os.listdir(items_dir):
13
+ if filename.endswith(".yml") or filename.endswith(".yaml"):
14
+ file_path = os.path.join(items_dir, filename)
15
+
16
+ # Read and parse YAML file
17
+ with open(file_path, "r") as file:
18
+ try:
19
+ data = yaml.safe_load(file)
20
+ if "items" in data:
21
+ combined_data["items"].update(data["items"])
22
+ except yaml.YAMLError as e:
23
+ print(f"Error parsing {filename}: {e}")
24
+
25
+ # Save combined data into a single YAML file
26
+ with open(output_file, "w") as outfile:
27
+ yaml.dump(combined_data, outfile,
28
+ default_flow_style=False, allow_unicode=True)
29
+
30
+ print(f"Combined YAML file saved to {output_file}")