Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ all-services-up:
cd services/frontend && uv run streamlit run main.py --server.address 0.0.0.0 --server.port 3000 & \
cd services/retriever && uv run uvicorn retriever.api:app --host 0.0.0.0 --port 8000 --reload

# --------------------TESTS --------------------------------------------------------------------------------------------------
test-parser:
pytest tests/test_parser.py -v -s --log-cli-level=INFO --capture=no --tb=short
# --------------------SERVICE STARTERS INSIDE DEVCONTAINER --------------------------------------------------------------------------------------------------
start-frontend:
cd services/frontend && uv sync && uv run streamlit run main.py --server.address 0.0.0.0 --server.port 3000

start-retriever:
cd services/retriever && uv sync && uv run uvicorn src.api:app --host 0.0.0.0 --port 8000 --reload

start-pusher:
cd services/pusher && uv sync && uv run python main.py

start-scraper:
cd services/scraper && uv sync && cd event_scraper && uv run python main.py

start-parser:
cd services/parser && uv sync && uv run python parser.py
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" />
<img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/357725b4-4da2-4463-b9a5-896a29fc4b79" />
# Laiive

#### what is 🫦Laiive
Expand All @@ -16,11 +16,11 @@ laiive links the broken connection between events and public[^*]

#### why 🫦laiive makes sense?

laiive was born to connect small events with people close to them, laiive does not focus on big musical events as many platforms are, laiive works on the human and community scale where small music events live.
laiive was born to connect small events with people close to them, laiive does not focus on big musical events as many platforms are, laiive works on the human and community scale where small music events live.

#### why is 🫦laiive good?

laiive was born as an AI cultural agenda, with the AI hype and AI competition without the AI Safety layer laiive has become a subversive way of using AI, it tries to steal attention from the main digital platforms and bring it back to real world social meetings. laiive positions itself as an ethical AI app helping to develop a balanced digital-physical culture before the intermediate layer in our digital comunication becomes too powerful.
laiive was born as an AI cultural agenda, with the AI hype and AI competition without the AI Safety layer laiive has become a subversive way of using AI, it tries to steal attention from the main digital platforms and bring it back to real world social meetings. laiive positions itself as an ethical AI app helping to develop a balanced digital-physical culture before the intermediate layer in our digital comunication becomes too powerful.

#### why is 🫦laiive profitable?

Expand All @@ -30,8 +30,7 @@ laiive is a catalyzer of a world wide business that is actually unatended. laiiv


## Services
<img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" />

<img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" /><img width="90" height="90" alt="laiive1" src="https://github.com/user-attachments/assets/f8dc0267-f630-4a87-b3f8-fe0277137ba5" />
### UI
a ZERO CLIC UI is the public view of laiive, easy to publish an event, easy to find an event.

Expand Down
10 changes: 0 additions & 10 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,6 @@ services:
target: /app
ignore:
- .venv/
pgadmin:
# TODO migrate to DBeaver
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: admin@admin.com # pragma: allowlist secret
PGADMIN_DEFAULT_PASSWORD: admin # pragma: allowlist secret
ports:
- "5050:80"
depends_on:
- db

volumes:
frontend-venv:
Expand Down
213 changes: 174 additions & 39 deletions services/frontend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,142 @@
from datetime import date
from config import settings

# Enhanced dark theme CSS
st.markdown(
"""
<style>
/* Root background - black */
.stApp {
background-color: #2b2b2b;
}

/* Main container background */
.main .block-container {
background-color: #2b2b2b;
padding-top: 2rem;
}

/* Title - Fuchsia Pink */
h1 {
color: #FF2AA0 !important;
font-weight: bold;
}

/* Chat container - dark grey with border */
div[data-testid="stContainer"] {
background-color: #2b2b2b;
border-radius: 10px;
padding: 20px;
border: 1px solid #404040;
}

/* Sidebar - mid grey with border */
[data-testid="stSidebar"] {
background-color: #2b2b2b !important;
border-right: 2px solid #FF2AA0 !important;
}

[data-testid="stSidebar"] > div:first-child {
background-color: #2b2b2b;
}

/* Sidebar labels and text - Fuchsia Pink */
[data-testid="stSidebar"] label,
[data-testid="stSidebar"] .stSelectbox label,
[data-testid="stSidebar"] .stRadio label,
[data-testid="stSidebar"] .stDateInput label,
[data-testid="stSidebar"] .stRadio label p,
[data-testid="stSidebar"] .stRadio label span,
[data-testid="stSidebar"] .stRadio > label,
[data-testid="stSidebar"] p,
[data-testid="stSidebar"] span {
color: #FF2AA0 !important;
}

/* Input fields styling (main area only) */
.stTextInput input {
background-color: #1e1e1e !important;
color: #ffffff !important;
border: 1px solid #FF2AA0 !important;
}

.stTextInput input:focus {
border-color: #FF2AA0 !important;
}

/* Button styling */
button[kind="primary"] {
background-color: #404040 !important;
color: #ffffff !important;
border: 1px solid #FF2AA0 !important;
}

button[kind="primary"]:hover {
background-color: #555555 !important;
border-color: #FF2AA0 !important;
}

/* Text color for readability (main area only) */
.stMarkdown,
.stMarkdown p,
.stMarkdown strong {
color: #e0e0e0 !important;
}

/* Chat message styling */
.stMarkdown strong {
color: #FF2AA0 !important;
}

/* User message bubble - right aligned with dark grey background */
.user-message {
background-color: #404040;
padding: 10px 15px;
border-radius: 10px;
margin: 10px 0;
margin-left: 40%;
text-align: right;
color: #ffffff;
}

/* Bot message styling */
.bot-message {
margin: 10px 0;
margin-left: 0%;
text-align: left;
}

/* Scrollbar styling */
::-webkit-scrollbar {
width: 8px;
}

::-webkit-scrollbar-track {
background: #1e1e1e;
}

::-webkit-scrollbar-thumb {
background: #555555;
border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
background: #666666;
}
</style>
""",
unsafe_allow_html=True,
)

API_URL = f"{settings.api_url}{settings.api_path}"

st.title("🫦laiive")

# Sidebar for filters
with st.sidebar:
st.header("SQL Filters")

# Place filter
places = ["All", "Bergamo", "Barcelona", "Boston", "Milano"]
selected_place = st.selectbox("PLACE FILTER:", places)
selected_place = st.selectbox("CITY:", places)

# Date filter
date_option = st.radio("DATE FILTER:", ["All Dates", "Specific Date", "Date Range"])
date_option = st.radio("DATE:", ["All Dates", "Specific Date", "Date Range"])

if date_option == "Specific Date":
selected_date = st.date_input("Select Date:", value=date(2025, 8, 1))
Expand All @@ -33,15 +155,6 @@
selected_date = None
date_range = None

# Display current filters
st.subheader("Current Filters")
st.write(f"**Place:** {selected_place}")
if date_option == "Specific Date":
st.write(f"**Date:** {selected_date}")
elif date_option == "Date Range" and date_range is not None:
st.write(f"**Date Range:** {date_range[0]} to {date_range[1]}")
else:
st.write("**Date:** All Dates")

if "messages" not in st.session_state:
st.session_state.messages = []
Expand All @@ -54,20 +167,24 @@ def get_laiive_response(
date_range=None,
):
try:
# Prepare the request payload with filters
dates_list = None
if date_filter:
dates_list = [date_filter.isoformat()]
elif date_range:
from datetime import timedelta

current_date = date_range[0]
end_date = date_range[1]
dates_list = []
while current_date <= end_date:
dates_list.append(current_date.isoformat())
current_date += timedelta(days=1)

payload = {
"message": user_message,
"filters": {
"place": place_filter if place_filter != "All" else None,
"date": date_filter.isoformat() if date_filter else None,
"date_range": (
{
"start": date_range[0].isoformat(),
"end": date_range[1].isoformat(),
}
if date_range is not None
else None
),
"dates": dates_list,
},
}

Expand All @@ -82,12 +199,37 @@ def get_laiive_response(
return f"Connection error: {e}"


# Main chat interface
st.header("Chat search engine")
# Create a scrollable container for chat messages
chat_container = st.container(height=400) # Adjust height as needed

user_input = st.text_input("You:", key="user_input")
with chat_container:
# Display chat history
for sender, msg in st.session_state.messages:
if sender == "user":
st.markdown(
f'<div class="user-message"><strong>You:</strong> {msg}</div>',
unsafe_allow_html=True,
)
else:
st.markdown(
f'<div class="bot-message"><strong>laiive:</strong> {msg}</div>',
unsafe_allow_html=True,
)

if st.button("Send") and user_input:
# Fixed input area at the bottom
with st.form(key="chat_form", clear_on_submit=True):
col1, col2 = st.columns([5, 1])
with col1:
user_input = st.text_input(
"You:",
key="user_input",
label_visibility="collapsed",
placeholder="Type your message...",
)
with col2:
send_button = st.form_submit_button("Send", use_container_width=True)

if send_button and user_input:
st.session_state.messages.append(("user", user_input))

# Pass filters to the API
Expand All @@ -97,12 +239,5 @@ def get_laiive_response(
date_filter=selected_date,
date_range=date_range,
)

st.session_state.messages.append(("bot", bot_reply))

# Display chat history
for sender, msg in st.session_state.messages:
if sender == "user":
st.markdown(f"**You:** {msg}")
else:
st.markdown(f"**laiive:** {msg}")
st.session_state.messages.append(("laiive", bot_reply))
st.rerun() # Refresh to show new messages
1 change: 1 addition & 0 deletions services/frontend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"loguru>=0.7.3",
"pydantic>=2.11.7",
"pydantic-settings>=2.10.1",
"streamlit>=1.47.0",
Expand Down
Loading