from typing import List import html import streamlit as st import asyncio from pydantic_models import Product from pydantic_ai_agents import Chatbot CARD_CSS = """ """ # class ProductReview(BaseModel): # ratings: Annotated[float, Field(le=5.0, ge=0.0)] = 0.0 # num_ratings: int = -1 # num_reviews : int = -1 # # class Product(BaseModel): # id: Optional[str] = None # pro_class : Annotated[Optional[ProductClass] ,Field(description="The category/type of the product")] = None # price: int # name: str # url: str # image: Optional[str] # review: Optional[ProductReview] # details: List[str] # delivery_date: datetime.date | str | None = None def render_products(products: List[Product], cols: int = 3): rows = [products[i : i + cols] for i in range(0, len(products), cols)] for row in rows: columns = st.columns(len(row), gap="large") for col, product in zip(columns, row): with col: # Card HTML name_escaped = html.escape(product.name) url = product.url image = product.image if product.image else None price = product.price rating = product.review.ratings if product.review else None num_ratings = product.review.num_ratings if product.review else None # If price is numeric, format it with comma separators if isinstance(price, (int, float)): price_str = "₹{:,.0f}".format(price) else: price_str = str(price) if price else "" # Build HTML for the card (image + title link) if image: card_html = f"""
{name_escaped}
{name_escaped}
{price_str}
{"⭐ " + str(rating) if rating else ""}{" (" + str(num_ratings) + ")" if num_ratings else ""}
""" else: card_html = f"""
default-image
{name_escaped}
{price_str}
{"⭐ " + str(rating) if rating else ""}{" (" + str(num_ratings) + ")" if num_ratings else ""}
""" st.markdown(card_html, unsafe_allow_html=True) async def st_main(): # Page config st.set_page_config(page_title="Shopping assistant", page_icon="💬") st.title("💬 Shopping Assistant") st.write("What would you like to buy today?") st.markdown(CARD_CSS, unsafe_allow_html=True) chatbot = Chatbot() # Initialize chat history if "messages" not in st.session_state: st.session_state.messages = [] # Display chat history for msg in st.session_state.messages: with st.chat_message(msg["role"]): st.markdown(msg["content"]) # Chat input box if user_input := st.chat_input("Type your message..."): # Add user message to history st.session_state.messages.append({"role": "user", "content": user_input}) with st.chat_message("user"): st.markdown(user_input) # Get bot response resp = await chatbot.chat(user_input) op = f""" Recommended product: \n{resp.output.recommended.model_dump_json()} \n{resp.output.message}\n Agent Flow : {resp.output.flow} """ st.session_state.messages.append({"role": "assistant", "content": op}) with st.chat_message("assistant"): st.markdown(op) render_products(resp.products) if __name__ == "__main__": asyncio.run(main())