- Project Overview
- Why This Project
- Features
- System Architecture
- Technology Stack
- Data Flow
- Database Schema
- AI/ML Components
- Security & Authentication
- Deployment
- Future Enhancements
The Travel Recommendation System is an intelligent, graph-based travel planning application that leverages Knowledge Graphs, Large Language Models (LLMs), and Graph RAG (Retrieval-Augmented Generation) to provide personalized travel recommendations and itinerary planning for Massachusetts destinations.
- Intelligent Discovery: Help users discover attractions, restaurants, parks, and cultural sites across Massachusetts
- Personalized Recommendations: Provide AI-powered suggestions based on user preferences and travel history
- Interactive Planning: Enable users to create, save, and manage day trip itineraries
- Knowledge Graph Exploration: Allow users to explore relationships between cities, attractions, and points of interest
- Natural Language Interaction: Support conversational queries through AI-powered chat interfaces
Traditional travel planning tools suffer from several limitations:
- Information Overload: Too many options without personalization
- Disconnected Data: Attractions, restaurants, and activities are siloed
- Static Recommendations: No learning from user behavior
- Poor Spatial Understanding: Difficulty finding nearby attractions
- Complex Planning: Manual itinerary creation is time-consuming
We address these challenges by:
- Knowledge Graph Integration: Connecting 352 cities with 19,883 attractions through 13,519+ relationships
- AI-Powered Insights: Using LLMs (Snowflake Cortex) for natural language understanding and generation
- Graph RAG: Combining graph database queries with LLM reasoning for contextual recommendations
- Spatial Intelligence: Leveraging geospatial data for proximity-based suggestions
- User Personalization: Learning from saved trips and preferences
- Enhanced User Experience: Intuitive, conversational interface
- Data-Driven Decisions: Insights from graph analytics
- Scalability: Graph database architecture supports millions of nodes
- Extensibility: Easy to add new cities, attractions, and features
Purpose: Central hub for user activity and quick access
Features:
- User statistics (trips planned, cities explored)
- Recent activity with saved trips
- Quick navigation to all features
- Personalized greeting
Technology: Streamlit UI, Snowflake data retrieval
Purpose: Conversational AI for travel queries
Features:
- Natural language question answering
- Graph RAG-powered responses
- Context-aware recommendations
- Suggested queries for exploration
Technology:
- LangChain for LLM orchestration
- Snowflake Cortex (Mistral-Large2 model)
- Neo4j for graph queries
- Custom prompt engineering
Example Queries:
"What are the best restaurants in Boston?"
"Find family-friendly museums in Cambridge"
"Suggest a day trip itinerary for Salem"
Purpose: Visual exploration of the travel knowledge graph
Features:
- Interactive graph visualization
- 352 cities, 19,883 attractions
- Relationship exploration (LOCATED_IN, SERVES_CUISINE, etc.)
- Quick query templates
- Cypher query execution
Technology:
- Neo4j graph database
- Plotly for visualizations
- Custom graph rendering
Graph Statistics:
- Nodes: 57,877 entities
- Relationships: 55,131+ connections
- Node Types: City, Restaurant, Museum, Park, Beach, Historic, Theatre, etc.
Purpose: Natural language to Cypher query generation
Features:
- Dynamic Cypher Generation: Converts natural language to Neo4j Cypher queries
- Schema-Aware: Uses actual database schema for accurate queries
- Spatial Proximity: Handles "near" queries with point.distance()
- Query History: Saves and reloads previous queries
- Visual Results: Graph visualization of query results
Technology:
- LLM-powered query generation
- Dynamic city fetching (352 cities)
- Template-based optimization
- Query caching for performance
Example:
User: "cafes near parks in cambridge"
Generated Cypher:
MATCH (p:Park)-[:LOCATED_IN]->(c:City) WHERE c.name = "Cambridge"
WITH p
MATCH (cf:Cafe)-[rel:LOCATED_IN]->(cc:City)
WHERE point.distance(
point({latitude: p.latitude, longitude: p.longitude}),
point({latitude: cf.latitude, longitude: cf.longitude})
) < 500
RETURN cf, rel, cc LIMIT 20
Purpose: Data analytics and visualization
Features:
- Geographic heatmaps
- Top destinations analysis
- Category distribution (pie charts)
- Top attractions by type
- Hidden gems discovery
- Smart Recommendations (collapsible):
- Graph-based recommendations
- AI-powered semantic suggestions
- Collaborative filtering
Technology:
- Plotly for interactive charts
- Pandas for data processing
- Snowflake for user trip data
- Neo4j for attraction data
Purpose: Interactive itinerary creation
Features:
- City selection with attraction filtering
- Drag-and-drop itinerary builder
- Interactive map with route visualization
- Save trips to database
- Estimated travel times
- Attraction details (hours, website, accessibility)
Technology:
- Streamlit drag-and-drop components
- Plotly Scattermap for mapping
- Snowflake for trip persistence
- Geospatial calculations
graph TB
subgraph "Frontend Layer"
UI[Streamlit Web App]
Pages[6 Interactive Pages]
end
subgraph "Application Layer"
Auth[Authentication Service]
LLM[LLM Utils]
GraphRAG[Graph RAG Engine]
Cypher[Cypher Generator]
end
subgraph "Data Layer"
Neo4j[(Neo4j Graph DB)]
Snowflake[(Snowflake Data Warehouse)]
end
subgraph "AI Services"
Cortex[Snowflake Cortex LLM]
LangChain[LangChain Framework]
end
UI --> Pages
Pages --> Auth
Pages --> LLM
Pages --> GraphRAG
Pages --> Cypher
Auth --> Snowflake
LLM --> Cortex
LLM --> LangChain
GraphRAG --> Neo4j
GraphRAG --> Cortex
Cypher --> Neo4j
Pages --> Neo4j
Pages --> Snowflake
graph LR
subgraph "User Interface"
D[Dashboard]
TA[Travel Assistant]
KG[KG Assistant]
AC[AI Cypher Chat]
TI[Travel Insights]
DT[Day Trip Planner]
end
subgraph "Core Services"
AUTH[auth_utils.py]
LLM[llm_utils.py]
GRAPH[graph_rag.py]
CONN[connections.py]
end
subgraph "Data Sources"
N[(Neo4j)]
S[(Snowflake)]
end
D --> AUTH
TA --> GRAPH
KG --> N
AC --> LLM
TI --> S
DT --> S
AUTH --> S
GRAPH --> N
GRAPH --> LLM
LLM --> S
CONN --> N
CONN --> S
graph TB
subgraph "Frontend Layer"
ST[Streamlit 1.40.2<br/>Web Framework]
PL[Plotly 5.24.1<br/>Visualizations]
CSS[Custom CSS<br/>Styling]
end
subgraph "Application Layer"
PY[Python 3.14<br/>Core Language]
LC[LangChain 0.3.13<br/>LLM Framework]
PD[Pandas 2.2.3<br/>Data Processing]
end
subgraph "AI/ML Stack"
CORTEX[Snowflake Cortex<br/>Mistral-Large2]
GRAG[Graph RAG<br/>Custom Engine]
CYP[Cypher Generator<br/>NL to Query]
end
subgraph "Data Layer"
NEO[(Neo4j 5.x<br/>57,877 nodes<br/>55,131+ rels)]
SF[(Snowflake<br/>User Data<br/>Trip Storage)]
end
subgraph "Security Layer"
AUTH[bcrypt<br/>Password Hash]
RSA[RSA Keys<br/>Snowflake Auth]
SESS[Session<br/>Management]
end
ST --> PY
PL --> ST
CSS --> ST
PY --> LC
PY --> PD
LC --> CORTEX
LC --> GRAG
GRAG --> NEO
GRAG --> CORTEX
CYP --> NEO
CYP --> CORTEX
PY --> AUTH
PY --> RSA
PY --> SESS
AUTH --> SF
RSA --> SF
style ST fill:#667eea,color:#fff
style NEO fill:#00d4aa,color:#fff
style SF fill:#29b5e8,color:#fff
style CORTEX fill:#ff6b6b,color:#fff
style GRAG fill:#feca57,color:#000
| Technology | Version | Purpose |
|---|---|---|
| Python | 3.14 | Core programming language |
| LangChain | 0.3.13 | LLM orchestration framework |
| Pandas | 2.2.3 | Data manipulation & analysis |
| NumPy | Latest | Numerical computations |
| Technology | Version | Purpose | Scale |
|---|---|---|---|
| Neo4j | 5.x | Graph database | 57,877 nodes, 55,131+ rels |
| neo4j-driver | 5.27.0 | Python driver | - |
| Snowflake | Latest | Data warehouse | User & trip data |
| snowflake-connector | 3.12.3 | Python connector | - |
| Technology | Version | Purpose |
|---|---|---|
| Snowflake Cortex | Latest | LLM hosting (Mistral-Large2) |
| LangChain Core | 0.3.28 | LLM abstractions |
| LangChain Community | 0.3.13 | Community integrations |
| Custom Graph RAG | 1.0 | Graph + LLM integration |
| Technology | Version | Purpose |
|---|---|---|
| bcrypt | 4.2.1 | Password hashing |
| cryptography | 44.0.0 | RSA key generation |
| Streamlit Secrets | - | Credential management |
| Tool | Purpose |
|---|---|
| Git | Version control |
| pip | Package management |
| venv | Virtual environment |
| Streamlit CLI | Development server |
# Core Framework
streamlit==1.40.2
# Database Drivers
neo4j==5.27.0
snowflake-connector-python==3.12.3
# AI/ML
langchain==0.3.13
langchain-core==0.3.28
langchain-community==0.3.13
# Data Processing
pandas==2.2.3
numpy==1.26.4
# Visualization
plotly==5.24.1
# Security
cryptography==44.0.0
bcrypt==4.2.1
# Utilities
python-dotenv==1.0.0
requests==2.31.0sequenceDiagram
participant User
participant Streamlit
participant AuthUtils
participant Snowflake
User->>Streamlit: Enter credentials
Streamlit->>AuthUtils: authenticate_user()
AuthUtils->>Snowflake: Query USERS table
Snowflake-->>AuthUtils: User record
AuthUtils->>AuthUtils: Verify password hash
AuthUtils-->>Streamlit: Authentication result
Streamlit-->>User: Login success/failure
sequenceDiagram
participant User
participant TravelAssistant
participant GraphRAG
participant Neo4j
participant LLM
User->>TravelAssistant: Ask question
TravelAssistant->>GraphRAG: query_graph_rag()
GraphRAG->>Neo4j: Execute Cypher query
Neo4j-->>GraphRAG: Graph data
GraphRAG->>GraphRAG: Format context
GraphRAG->>LLM: Generate response with context
LLM-->>GraphRAG: AI-generated answer
GraphRAG-->>TravelAssistant: Final response
TravelAssistant-->>User: Display answer
sequenceDiagram
participant User
participant CypherChat
participant LLMUtils
participant Neo4j
participant Cortex
User->>CypherChat: Natural language query
CypherChat->>LLMUtils: generate_cypher_query()
LLMUtils->>Neo4j: Fetch available cities
Neo4j-->>LLMUtils: City list (352 cities)
LLMUtils->>LLMUtils: Check template match
alt Template Match
LLMUtils-->>CypherChat: Template query
else Complex Query
LLMUtils->>Cortex: Generate with schema context
Cortex-->>LLMUtils: Cypher query
LLMUtils-->>CypherChat: Generated query
end
CypherChat->>Neo4j: Execute Cypher
Neo4j-->>CypherChat: Query results
CypherChat-->>User: Display results
sequenceDiagram
participant User
participant DayTripPlanner
participant Neo4j
participant Snowflake
User->>DayTripPlanner: Select city
DayTripPlanner->>Neo4j: Fetch attractions
Neo4j-->>DayTripPlanner: Attraction list
DayTripPlanner-->>User: Display attractions
User->>DayTripPlanner: Build itinerary
User->>DayTripPlanner: Save trip
DayTripPlanner->>Snowflake: INSERT INTO USER_TRIPS
Snowflake-->>DayTripPlanner: Confirmation
DayTripPlanner-->>User: Trip saved
graph LR
subgraph "Neo4j Graph Database"
N1[352 Cities]
N2[19,883 Attractions]
N3[13,519 LOCATED_IN<br/>Relationships]
N4[Graph Queries<br/>Cypher]
end
subgraph "Snowflake Data Warehouse"
S1[USERS Table<br/>Authentication]
S2[USER_TRIPS Table<br/>Trip Storage]
S3[Cortex LLM<br/>AI Services]
end
subgraph "Application"
APP[Travel Recommend<br/>System]
end
N1 --> N3
N2 --> N3
N4 --> N1
N4 --> N2
APP --> N4
APP --> S1
APP --> S2
APP --> S3
S1 -.User Auth.-> APP
S2 -.Trip Data.-> APP
S3 -.AI Responses.-> APP
style N1 fill:#00d4aa,color:#fff
style N2 fill:#00d4aa,color:#fff
style S1 fill:#29b5e8,color:#fff
style S2 fill:#29b5e8,color:#fff
style S3 fill:#ff6b6b,color:#fff
style APP fill:#667eea,color:#fff
graph TB
subgraph "Geographic Hierarchy"
Country[Country<br/>🌍 1 node<br/>name: Us]
State[State<br/>🗺️ 5 nodes<br/>name: MA, CT, RI, NH, VT]
City[City<br/>🏙️ 352 nodes<br/>name, lat, lon]
end
subgraph "Tourism Nodes"
Park[Park<br/>🌳 3,802 nodes]
Beach[Beach<br/>🏖️ 2,053 nodes]
Museum[Museum<br/>🏛️ 444 nodes]
Theatre[Theatre<br/>🎭 220 nodes]
Historic[Historic<br/>🏰 136 nodes]
end
subgraph "Business Nodes"
Restaurant[Restaurant<br/>🍽️ 4,813 nodes]
FastFood[FastFood<br/>🍔 2,395 nodes]
Cafe[Cafe<br/>☕ 1,202 nodes]
Bar[Bar<br/>🍺 415 nodes]
Pub[Pub<br/>🍻 71 nodes]
end
subgraph "Properties"
Props[Common Properties:<br/>• id<br/>• name<br/>• latitude<br/>• longitude<br/>• website<br/>• phone<br/>• openingHours<br/>• wheelchair]
end
State -->|IN_COUNTRY<br/>4 rels| Country
City -->|IN_STATE<br/>348 rels| State
Park -->|LOCATED_IN| City
Beach -->|LOCATED_IN| City
Museum -->|LOCATED_IN| City
Theatre -->|LOCATED_IN| City
Historic -->|LOCATED_IN| City
Restaurant -->|LOCATED_IN| City
FastFood -->|LOCATED_IN| City
Cafe -->|LOCATED_IN| City
Bar -->|LOCATED_IN| City
Pub -->|LOCATED_IN| City
Restaurant -.properties.-> Props
Museum -.properties.-> Props
Park -.properties.-> Props
style Country fill:#ff6b6b,color:#fff
style State fill:#feca57,color:#000
style City fill:#48dbfb,color:#fff
style Restaurant fill:#ff9ff3,color:#000
style Park fill:#54a0ff,color:#fff
style Museum fill:#00d2d3,color:#fff
Total Nodes: 57,877 Total Relationships: 55,131+
Top Node Labels:
| Label | Count | Description |
|---|---|---|
Entity |
57,877 | Base label for all nodes |
Attraction |
19,883 | All points of interest |
City |
352 | Cities in Massachusetts |
Restaurant |
4,813 | Dining establishments |
Park |
3,802 | Parks and green spaces |
FastFood |
2,395 | Fast food restaurants |
Beach |
2,053 | Beaches and waterfronts |
Cafe |
1,202 | Coffee shops and cafes |
Museum |
444 | Museums and galleries |
Bar |
415 | Bars and pubs |
Theatre |
220 | Theaters and performance venues |
Historic |
136 | Historic sites |
graph LR
POI[POI/Attraction]
City[City]
State[State]
Country[Country]
Cuisine[Cuisine Type]
Hours[Opening Hours]
Website[Website URL]
POI -->|LOCATED_IN<br/>13,519 rels| City
City -->|IN_STATE<br/>348 rels| State
State -->|IN_COUNTRY<br/>4 rels| Country
POI -->|SERVES_CUISINE<br/>699 rels| Cuisine
POI -->|OPENING_HOURS<br/>2,993 rels| Hours
POI -->|HAS_WEBSITE<br/>4,125 rels| Website
style POI fill:#54a0ff,color:#fff
style City fill:#48dbfb,color:#fff
style State fill:#feca57,color:#000
Top Relationships:
City Node:
{
"id": "city_4:7f741ed8-79a8-48ae-98d9-00838f6db129:23410",
"name": "Boston",
"latitude": 42.3601,
"longitude": -71.0589,
"country": "Us",
"state": "MA",
"attractionCount": 5234,
"color": "#68BDF6",
"createdAt": "2025-12-03T19:42:00.671Z",
"updatedAt": "2025-12-04T04:06:00.808Z"
}Restaurant Node:
{
"id": "rest_66010cc608e8",
"name": "Dino's North End",
"latitude": 42.3645,
"longitude": -71.0535,
"city": "Boston",
"state": "MA",
"country": "Us",
"type": "ItalianSubShop",
"category": "italian_north_end",
"cuisine": "italian",
"price_range_usd": "10-20",
"description": "Generous Italian subs and pasta at fair prices",
"openingHours": "11AM-9PM",
"neighborhood": "North End",
"wheelchair": "yes",
"outdoorSeating": "no",
"website": "https://example.com",
"phone": "+1-617-555-0123"
}Museum Node:
{
"id": "museum_247474896",
"name": "Museum of Fine Arts",
"tourism": "museum",
"latitude": 42.3394,
"longitude": -71.0948,
"city": "Boston",
"state": "MA",
"fee": "yes",
"wheelchair": "yes",
"openingHours": "10:00-17:00",
"website": "https://www.mfa.org",
"wikidataLink": "https://www.wikidata.org/wiki/Q49133",
"building": "yes",
"addrStreet": "Avenue of the Arts",
"addrHousenumber": "465",
"addrCity": "Boston",
"addrPostcode": "02115"
}erDiagram
USERS ||--o{ USER_TRIPS : creates
USERS {
varchar user_id PK "UUID"
varchar username UK "Unique username"
varchar email UK "Unique email"
varchar password_hash "bcrypt hash"
varchar full_name "User's full name"
timestamp created_at "Account creation"
timestamp last_login "Last login time"
}
USER_TRIPS {
varchar trip_id PK "UUID"
varchar user_id FK "References USERS"
varchar city "Trip destination"
date trip_date "Planned date"
variant itinerary "JSON array of attractions"
timestamp created_at "Trip creation time"
}
USERS Table:
CREATE TABLE USERS (
user_id VARCHAR(255) PRIMARY KEY,
username VARCHAR(100) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
last_login TIMESTAMP,
-- Constraints
CONSTRAINT email_format CHECK (email LIKE '%@%.%'),
CONSTRAINT username_length CHECK (LENGTH(username) >= 3)
);
-- Indexes
CREATE INDEX idx_users_email ON USERS(email);
CREATE INDEX idx_users_username ON USERS(username);Sample User Record:
{
"user_id": "user_550e8400-e29b-41d4-a716-446655440000",
"username": "hotragn",
"email": "hotragn@example.com",
"password_hash": "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYIeWZQe",
"full_name": "Hotragn Developer",
"created_at": "2024-11-01 10:30:00",
"last_login": "2024-12-11 15:45:00"
}USER_TRIPS Table:
CREATE TABLE USER_TRIPS (
trip_id VARCHAR(255) PRIMARY KEY,
user_id VARCHAR(255) NOT NULL,
city VARCHAR(100) NOT NULL,
trip_date DATE,
itinerary VARIANT, -- JSON array
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
-- Foreign Key
CONSTRAINT fk_user
FOREIGN KEY (user_id)
REFERENCES USERS(user_id)
ON DELETE CASCADE
);
-- Indexes
CREATE INDEX idx_trips_user ON USER_TRIPS(user_id);
CREATE INDEX idx_trips_city ON USER_TRIPS(city);
CREATE INDEX idx_trips_date ON USER_TRIPS(trip_date);Sample Trip Record:
{
"trip_id": "trip_660e8400-e29b-41d4-a716-446655440001",
"user_id": "user_550e8400-e29b-41d4-a716-446655440000",
"city": "Boston",
"trip_date": "2024-12-25",
"itinerary": [
{
"name": "Museum of Fine Arts",
"type": "Museum",
"address": "465 Huntington Ave",
"time": "10:00 AM",
"duration": "2 hours",
"latitude": 42.3394,
"longitude": -71.0948
},
{
"name": "Fenway Park",
"type": "Stadium",
"address": "4 Jersey St",
"time": "2:00 PM",
"duration": "3 hours",
"latitude": 42.3467,
"longitude": -71.0972
}
],
"created_at": "2024-12-11 16:00:00"
}-- LLM Query Example
SELECT SNOWFLAKE.CORTEX.COMPLETE(
'mistral-large2',
'What are the best restaurants in Boston?'
) as ai_response;
-- Sentiment Analysis
SELECT
trip_id,
city,
SNOWFLAKE.CORTEX.SENTIMENT(
ARRAY_TO_STRING(itinerary:*.name, ', ')
) as trip_sentiment
FROM USER_TRIPS;sequenceDiagram
participant User
participant App
participant Neo4j
participant Snowflake
participant LLM
User->>App: Login
App->>Snowflake: Authenticate user
Snowflake-->>App: User session
User->>App: Search attractions
App->>Neo4j: Cypher query
Neo4j-->>App: Graph results
App-->>User: Display attractions
User->>App: Ask AI question
App->>Neo4j: Fetch context
Neo4j-->>App: Graph data
App->>LLM: Generate response
LLM-->>App: AI answer
App-->>User: Display answer
User->>App: Save trip
App->>Snowflake: INSERT trip
Snowflake-->>App: Confirmation
App-->>User: Trip saved
Neo4j Statistics:
- Nodes: 57,877 total
- Cities: 352
- Attractions: 19,883
- Other entities: 37,642
- Relationships: 55,131+
- Properties: ~500,000+ property values
- Average Query Time: 50-200ms
- Index Coverage: 95%
Snowflake Statistics:
- Users: Growing (multi-user system)
- Trips: Unlimited storage
- Query Performance: <100ms for user queries
- Storage: Scalable (cloud-based)
- Cortex LLM: On-demand processing
Neo4j Optimizations:
-- Create indexes for fast lookups
CREATE INDEX city_name FOR (c:City) ON (c.name);
CREATE INDEX poi_name FOR (p:Attraction) ON (p.name);
CREATE INDEX poi_city FOR (p:Attraction) ON (p.city);
-- Create constraints
CREATE CONSTRAINT city_id FOR (c:City) REQUIRE c.id IS UNIQUE;
CREATE CONSTRAINT poi_id FOR (p:Attraction) REQUIRE p.id IS UNIQUE;Snowflake Optimizations:
-- Clustering for better performance
ALTER TABLE USER_TRIPS CLUSTER BY (user_id, trip_date);
-- Materialized views for analytics
CREATE MATERIALIZED VIEW user_trip_stats AS
SELECT
user_id,
COUNT(*) as total_trips,
COUNT(DISTINCT city) as cities_visited,
MAX(created_at) as last_trip_date
FROM USER_TRIPS
GROUP BY user_id;Model: Snowflake Cortex - Mistral-Large2
Capabilities:
- Natural language understanding
- Cypher query generation
- Conversational responses
- Context-aware recommendations
Integration:
class SnowflakeCortexLLM(LLM):
model: str = "mistral-large2"
def _call(self, prompt: str) -> str:
cursor.execute(
"SELECT SNOWFLAKE.CORTEX.COMPLETE(?, ?)",
(self.model, prompt)
)
return cursor.fetchone()[0]Purpose: Combine graph database queries with LLM reasoning
Process:
- Query Understanding: Parse user intent
- Graph Retrieval: Execute Cypher queries to fetch relevant data
- Context Formation: Format graph data as context
- LLM Generation: Generate natural language response
- Response Delivery: Present to user
Example:
def query_graph_rag(user_query, neo4j_driver, llm):
# Step 1: Generate Cypher query
cypher = generate_cypher_query(user_query)
# Step 2: Execute on Neo4j
results = execute_cypher(cypher, neo4j_driver)
# Step 3: Format context
context = format_graph_results(results)
# Step 4: Generate response
prompt = f"Context: {context}\nQuestion: {user_query}\nAnswer:"
response = llm(prompt)
return responseFeatures:
- Dynamic City Fetching: Queries Neo4j for all 352 cities
- Schema-Aware Prompts: Uses actual database schema
- Template Optimization: Fast path for common queries
- Spatial Query Support: Handles proximity with
point.distance()
Prompt Engineering:
prompt = f"""You are a Neo4j Cypher expert.
DATABASE SCHEMA:
- Node Labels: City (352), Restaurant (4,813), Museum (444)...
- Relationships: LOCATED_IN (13,519), IN_STATE (348)...
- Available Cities: {', '.join(cities[:20])}
RULES:
1. ALWAYS use WHERE clause for city filters
2. For "X near Y" queries: Match Y first, then X with point.distance()
3. ALWAYS return: node, relationship, city
USER QUESTION: {natural_language_query}
Generate Cypher query:
"""Three Approaches:
- Graph-Based: Similar attractions in visited cities
- AI-Powered: Semantic similarity using LLM embeddings
- Collaborative Filtering: Popular among similar users
Technology: Neo4j graph algorithms, Snowflake analytics
Features:
- User registration with email validation
- Password hashing with bcrypt
- Session management
- Secure credential storage
Implementation:
def authenticate_user(username, password):
# Fetch user from Snowflake
user = fetch_user(username)
# Verify password hash
if bcrypt.checkpw(password.encode(), user['password_hash'].encode()):
return user
return NoneSetup:
- Generate RSA key pair
- Store public key in Snowflake
- Use private key for authentication
- Secure key storage in
.streamlit/secrets.toml
Benefits:
- No password exposure
- Encrypted connections
- Key rotation support
# 1. Clone repository
git clone <repository-url>
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Configure secrets
# Edit .streamlit/secrets.toml with credentials
# 5. Run application
streamlit run app.pyRecommended Platform: Streamlit Cloud, AWS, or Azure
Steps:
- Configure environment variables
- Set up Neo4j database connection
- Configure Snowflake connection
- Deploy Streamlit app
- Set up SSL/TLS
- Configure domain
- Multi-State Support: Expand beyond Massachusetts
- Mobile App: React Native or Flutter
- Real-Time Updates: Live attraction data
- Social Features: Share trips, follow users
- Advanced Analytics: ML-powered insights
- Voice Interface: Voice-activated queries
- Offline Mode: Cached data for offline access
- Integration: Google Maps, Yelp, TripAdvisor APIs
- Performance: Query optimization, caching layer
- Scalability: Microservices architecture
- Testing: Unit tests, integration tests
- CI/CD: Automated deployment pipeline
- Monitoring: Application performance monitoring
- Documentation: API documentation, user guides
Project Team:
- Hotragn (Lead Developer)
- Tirdesh (Backend Engineer)
- Amantha (Frontend Developer)
Repository: Hotragn
This project is licensed under the MIT License - see below for details.
MIT License
Copyright (c) 2025 Hotragn, Tirdesh, Amantha
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Last Updated: December 2025 Version: 2.0.0
