|
import streamlit as st |
|
import requests |
|
import os |
|
os.system("pip install langchain-groq==0.1.3") |
|
from langchain_groq import ChatGroq |
|
from langchain_core.messages import HumanMessage, SystemMessage |
|
from langchain_core.prompts import ChatPromptTemplate |
|
os.system("pip install python-dotenv") |
|
from dotenv import load_dotenv |
|
|
|
load_dotenv() |
|
GROQ_API_KEY = os.getenv("GROQ_API_KEY") |
|
|
|
|
|
if not GROQ_API_KEY: |
|
raise ValueError("GROQ_API_KEY environment variable is not set") |
|
|
|
|
|
def search_travel_info(destination): |
|
url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{destination}" |
|
response = requests.get(url) |
|
if response.status_code == 200: |
|
data = response.json() |
|
return data.get("extract", "No information found.") |
|
return "No results found." |
|
|
|
|
|
def generate_itinerary(start_location, budget, duration, destination, purpose, preferences): |
|
search_results = search_travel_info(destination) |
|
|
|
|
|
prompt_template = ChatPromptTemplate.from_messages([ |
|
SystemMessage(content="You are an expert travel guide. Provide a detailed travel itinerary."), |
|
HumanMessage(content=f""" |
|
Create a {duration}-day travel itinerary for a traveler going from {start_location} to {destination}. |
|
|
|
### π·οΈ Traveler Information: |
|
- Budget: {budget} |
|
- Purpose of Travel: {purpose} |
|
- Preferences: {preferences} |
|
|
|
### π Day-wise Itinerary: |
|
- π Activities (morning, afternoon, evening) |
|
- π Attractions (landmarks & hidden gems) |
|
- π½οΈ Food recommendations |
|
- π¨ Accommodation options |
|
- π Transportation details |
|
|
|
### π Additional Travel Info: |
|
{search_results} |
|
""") |
|
]) |
|
|
|
|
|
llm = ChatGroq(temperature=0,model_name="llama-3.3-70b-versatile", api_key=GROQ_API_KEY) |
|
|
|
|
|
response = llm.invoke(prompt_template.format()) |
|
|
|
return response.content if response else "Error: Unable to generate itinerary." |
|
|
|
|
|
st.set_page_config(page_title="AI Travel Planner", page_icon="βοΈ") |
|
|
|
|
|
st.markdown( |
|
""" |
|
<style> |
|
.stApp { |
|
# background-image: url("https://images.unsplash.com/photo-1436491865332-7a61a109cc05"); |
|
# background-image: url("https://images.unsplash.com/photo-1506748686214-e9df14d4d9d0"); |
|
background-image: url("https://images.unsplash.com/photo-1483728642387-6c3bdd6c93e5"); |
|
# background-image: url("https://images.unsplash.com/photo-1518563259479-d003c05a6507?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"); |
|
background-size: cover; |
|
background-position: center; |
|
background-attachment: fixed; |
|
filter: brightness(90%); |
|
} |
|
.stApp::before { |
|
content: ""; |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
right: 0; |
|
bottom: 0; |
|
background: rgba(0, 0, 0, 0.4); /* 40% opaque black */ |
|
z-index: -1; |
|
} |
|
.form-title { |
|
color: white !important; |
|
font-size: 2rem; |
|
font-weight: bold; |
|
text-align: center; |
|
} |
|
.form-subtitle { |
|
color: white !important; |
|
font-size: 1.2rem; |
|
text-align: center; |
|
margin-bottom: 1.5rem; |
|
} |
|
/* Frosted Glass Box */ |
|
.frosted-glass-box { |
|
background: rgba(255, 255, 255, 0.2); |
|
backdrop-filter: blur(10px); |
|
-webkit-backdrop-filter: blur(10px); |
|
border-radius: 15px; |
|
padding: 2rem; |
|
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2); |
|
width: 80%; |
|
margin: auto; |
|
} |
|
/* Input Styling */ |
|
.stTextInput input, |
|
.stSelectbox select, |
|
.stNumberInput input, |
|
.stTextArea textarea { |
|
color: #000000 !important; |
|
background-color: rgba(255, 255, 255, 0.7) !important; |
|
border-radius: 8px !important; |
|
border: 1px solid rgba(0, 0, 0, 0.1) !important; |
|
padding: 10px; |
|
font-size: 1rem; |
|
} |
|
/* Button Styling */ |
|
.stButton button { |
|
background-color: black !important; |
|
color: white !important; |
|
border-radius: 8px !important; |
|
padding: 10px 20px !important; |
|
font-size: 1rem; |
|
font-weight: bold !important; |
|
width: 100% !important; |
|
margin-top: 1rem !important; |
|
border: none !important; |
|
} |
|
.stButton button:hover { |
|
background-color: white !important; |
|
color: black !important; |
|
border: 1.5px solid black !important; |
|
} |
|
/* Itinerary Box */ |
|
.itinerary-box { |
|
background: rgba(255, 255, 255, 0.7); |
|
border-radius: 15px; |
|
padding: 1.5rem; |
|
margin-top: 1.5rem; |
|
width: 80%; |
|
margin: auto; |
|
} |
|
</style> |
|
""", |
|
unsafe_allow_html=True |
|
) |
|
|
|
|
|
st.markdown('<h1 class="form-title">AI-Powered Travel Planner βοΈ</h1>', unsafe_allow_html=True) |
|
st.markdown('<p class="form-subtitle">Plan your next trip with AI!</p>', unsafe_allow_html=True) |
|
|
|
|
|
col1, col2 = st.columns(2) |
|
with col1: |
|
start_location = st.text_input("π Starting Location") |
|
with col2: |
|
destination = st.text_input("π Destination") |
|
|
|
col3, col4 = st.columns(2) |
|
with col3: |
|
budget = st.selectbox("π° Select Budget", ["Low", "Moderate", "Luxury"]) |
|
with col4: |
|
duration = st.number_input("π
Trip Duration (days)", min_value=1, max_value=30, value=3) |
|
|
|
|
|
purpose = st.text_area("π Purpose of Trip") |
|
preferences = st.text_area("π― Your Preferences (e.g., adventure, food, history)") |
|
|
|
if st.button("Generate Itinerary"): |
|
if start_location and destination and purpose and preferences: |
|
itinerary = generate_itinerary(start_location, budget, duration, destination, purpose, preferences) |
|
st.subheader("Your AI-Generated Itinerary:") |
|
st.write(itinerary) |
|
else: |
|
|
|
st.warning("Please fill in all fields.") |