Skip to content

Commit 4c5fe03

Browse files
authored
Update citypulse-ai-search.mdx
1 parent 69c7ae1 commit 4c5fe03

File tree

1 file changed

+31
-240
lines changed

1 file changed

+31
-240
lines changed

docs/showcase/citypulse-ai-search.mdx

Lines changed: 31 additions & 240 deletions
Original file line numberDiff line numberDiff line change
@@ -1,272 +1,63 @@
11
---
22
title: CityPulse - AI-Powered Geospatial Discovery Search
33
description: Real-time local discovery search using Perplexity AI for personalized location insights and recommendations
4-
sidebar_position: 1
5-
keywords: [perplexity, geospatial, location, real-time, maps, local-discovery, sonar, fasthtml]
4+
sidebar_position: 2
5+
keywords: [perplexity, geospatial, location, real-time, maps, local-discovery, sonar]
66
---
77

88
# CityPulse - AI-Powered Geospatial Discovery
99

1010
![CityPulse Main Interface](https://raw.githubusercontent.com/anevsky/CityPulse/main/assets/CityPulse-GeoSearch-App-1.jpg)
1111

12-
CityPulse is an intelligent location-based discovery app that helps users explore what's happening around them right now. Built with Perplexity AI's Sonar models, it provides personalized, real-time insights about local events, restaurants, alerts, and activities with geographic context and citation tracking.
12+
CityPulse is an intelligent location-based discovery search that helps users explore what's happening around them right now. It demonstrates how to create personalized, real-time local insights using Perplexity's Sonar models.
1313

14-
## Demo Video
14+
[![Demo Video](https://cdn.loom.com/sessions/thumbnails/6507fa27571442e680edf787b0f0690d-2fa2c36169822631-full-play.gif)](https://youtu.be/Y0UIhh3diJg)
1515

16-
[![CityPulse Demo Video](https://cdn.loom.com/sessions/thumbnails/6507fa27571442e680edf787b0f0690d-2fa2c36169822631-full-play.gif)](https://youtu.be/Y0UIhh3diJg)
16+
## What CityPulse Does
1717

18-
## Features
18+
- **Real-time local discovery** - Find current events, restaurants, and local alerts near any location
19+
- **AI-powered search suggestions** - Get intelligent search recommendations as you type
20+
- **Personalized insights** - Receive AI-generated advice on what to try, best times to visit, and pro tips
21+
- **Interactive mapping** - Explore results on an interactive map with custom markers and detailed popups
1922

20-
- **Real-time location discovery** using Perplexity's Sonar models for current information
21-
- **Interactive map interface** with custom markers and auto-zoom functionality
22-
- **AI-powered search suggestions** with natural language query processing
23-
- **Structured data extraction** with JSON schema validation and citation tracking
24-
- **Personalized insights** using Sonar Reasoning for location recommendations
25-
- **Geographic context awareness** for coordinate-based search queries
23+
![Search Interface](https://raw.githubusercontent.com/anevsky/CityPulse/main/assets/CityPulse-GeoSearch-App-2.jpg)
2624

27-
## Prerequisites
25+
## How It Uses Perplexity Sonar
2826

29-
- Python 3.11+
30-
- Perplexity API key
31-
- Google Maps API key
32-
- Basic knowledge of FastHTML framework
27+
CityPulse leverages two key Perplexity models:
3328

34-
## Installation
35-
36-
1. **Clone and setup environment**
37-
```bash
38-
git clone <repository-url>
39-
cd citypulse
40-
python3 -m venv venv
41-
source venv/bin/activate
42-
pip install -r requirements.txt
43-
```
44-
45-
2. **Configure API keys**
46-
```env
47-
# .env file
48-
PERPLEXITY_API_KEY=your_perplexity_api_key_here
49-
GOOGLE_MAPS_API_KEY=your_google_maps_api_key_here
50-
```
51-
52-
3. **Run the application**
53-
```bash
54-
python3 main.py
55-
```
56-
57-
## Usage
58-
59-
### Basic Local Discovery
60-
```python
61-
# Get nearby events, restaurants, and alerts
62-
api.geo_structured_output_with_citations(
63-
prompt=f"Find current events, restaurants, and local alerts near coordinates {lat}, {lng}",
64-
schema=LOCAL_INFO_SCHEMA
65-
)
66-
```
67-
68-
![Search Interface](https://raw.githubusercontent.com/anevsky/CityPulse/main/assets/CityPulse-GeoSearch-App-4.jpg)
69-
70-
### AI-Powered Search Suggestions
29+
**Sonar for Real-Time Data**
7130
```python
72-
# Generate contextual search suggestions
73-
api.get_search_suggestions(
74-
query="coffee",
75-
location="San Francisco, CA"
31+
# Get current local information with geographic context
32+
response = client.chat.completions.create(
33+
model="sonar",
34+
messages=[{
35+
"role": "user",
36+
"content": f"Find current events, restaurants, and alerts near {lat}, {lng}"
37+
}],
38+
response_format={"type": "json_schema", "json_schema": {"schema": LOCAL_INFO_SCHEMA}}
7639
)
7740
```
7841

79-
![Location Details Modal](https://raw.githubusercontent.com/anevsky/CityPulse/main/assets/CityPulse-GeoSearch-App-2.jpg)
80-
81-
### Personalized Location Insights
42+
**Sonar Reasoning for Personalized Insights**
8243
```python
83-
# Get AI reasoning for specific locations
84-
api.get_location_insights(
85-
location_name="Blue Bottle Coffee",
86-
location_type="restaurant",
87-
description="Specialty coffee roaster",
88-
address="315 Linden St, Oakland, CA"
44+
# Generate AI-powered location recommendations
45+
response = client.chat.completions.create(
46+
model="sonar-reasoning",
47+
messages=[{
48+
"role": "user",
49+
"content": f"Provide personalized insights for {location_name}: what to try, best times to visit, pro tips"
50+
}]
8951
)
9052
```
9153

92-
![AI-Powered Insights](https://raw.githubusercontent.com/anevsky/CityPulse/main/assets/CityPulse-GeoSearch-App-3.jpg)
93-
94-
## Code Explanation
95-
96-
### Perplexity API Integration
97-
```python
98-
class PerplexityAPI:
99-
def __init__(self, api_key: Optional[str] = None):
100-
"""Initialize the Perplexity API client."""
101-
self.api_key = api_key or os.environ.get("PERPLEXITY_API_KEY")
102-
if not self.api_key:
103-
raise ValueError("API key is required. Set PERPLEXITY_API_KEY environment variable or pass it directly.")
104-
self.base_url = "https://api.perplexity.ai/chat/completions"
105-
self.headers = {"Authorization": f"Bearer {self.api_key}"}
106-
107-
def geo_structured_output_with_citations(self,
108-
prompt: str,
109-
schema: Dict[str, Any],
110-
model: str = "sonar") -> Dict:
111-
"""Get a structured JSON response with detailed citations."""
112-
payload = {
113-
"model": model,
114-
"messages": [
115-
{"role": "system", "content":
116-
"""
117-
You are an expert on current events and a real-time local discovery app for city exploration.
118-
119-
We're building an app that helps people discover what's happening right around them, whether they're tourists or locals. The key features would be:
54+
The app uses structured JSON schemas to ensure consistent data formatting and includes citation tracking for source verification.
12055

121-
1. Live local events (concerts, meetups, pop-ups happening now)
122-
2. Contextual business info (what's open, busy, or recommended nearby)
123-
3. Real-time alerts (weather, traffic, safety updates)
124-
4. Smart recommendations based on location and time
125-
126-
Find current information near coordinates:
127-
128-
1. EVENTS: Live events happening today/this week (concerts, festivals, sports, etc.)
129-
2. RESTAURANTS: Popular local restaurants and cafes currently open
130-
3. ALERTS: Any weather, traffic, or safety alerts for the area
131-
132-
For each item:
133-
- Generate a unique ID (like "event_001", "restaurant_001", "alert_001")
134-
- Include specific addresses and approximate coordinates if possible
135-
- Include official website URLs when available
136-
- Provide citation information ONLY if it's from a different source than the official website
137-
- For every category, try to include at least 5 items
138-
139-
Return as JSON with events, restaurants, and alerts arrays.
140-
141-
IMPORTANT: For each item, include:
142-
- id: unique identifier
143-
- website: official website URL if available (leave empty if not available)
144-
- citation: object with url, title, and description ONLY if different from official website (leave empty if not available or same as website)
145-
"""
146-
},
147-
{"role": "user", "content": prompt}
148-
],
149-
"response_format": {
150-
"type": "json_schema",
151-
"json_schema": {"schema": schema}
152-
},
153-
"return_citations": True,
154-
"return_images": False
155-
}
156-
157-
response = requests.post(self.base_url, headers=self.headers, json=payload).json()
158-
159-
# Return both content and citations
160-
result = {
161-
"content": response["choices"][0]["message"]["content"],
162-
"citations": response.get("citations", [])
163-
}
164-
165-
return result
166-
```
167-
168-
### JSON Schema for Structured Output
169-
```python
170-
LOCAL_INFO_SCHEMA = {
171-
"type": "object",
172-
"properties": {
173-
"events": {
174-
"type": "array",
175-
"items": {
176-
"type": "object",
177-
"properties": {
178-
"id": {"type": "string"},
179-
"name": {"type": "string"},
180-
"type": {"type": "string"},
181-
"address": {"type": "string"},
182-
"date": {"type": "string"},
183-
"time": {"type": "string"},
184-
"description": {"type": "string"},
185-
"latitude": {"type": "number"},
186-
"longitude": {"type": "number"},
187-
"website": {"type": "string"},
188-
"citation": {
189-
"type": "object",
190-
"properties": {
191-
"url": {"type": "string"},
192-
"title": {"type": "string"},
193-
"description": {"type": "string"}
194-
}
195-
}
196-
},
197-
"required": ["id", "name", "type", "description"]
198-
}
199-
},
200-
"restaurants": {
201-
"type": "array",
202-
"items": {
203-
"type": "object",
204-
"properties": {
205-
"id": {"type": "string"},
206-
"name": {"type": "string"},
207-
"address": {"type": "string"},
208-
"cuisine": {"type": "string"},
209-
"description": {"type": "string"},
210-
"date": {"type": "string"},
211-
"time": {"type": "string"},
212-
"latitude": {"type": "number"},
213-
"longitude": {"type": "number"},
214-
"website": {"type": "string"},
215-
"citation": {
216-
"type": "object",
217-
"properties": {
218-
"url": {"type": "string"},
219-
"title": {"type": "string"},
220-
"description": {"type": "string"}
221-
}
222-
}
223-
},
224-
"required": ["id", "name", "description"]
225-
}
226-
},
227-
"alerts": {
228-
"type": "array",
229-
"items": {
230-
"type": "object",
231-
"properties": {
232-
"id": {"type": "string"},
233-
"title": {"type": "string"},
234-
"description": {"type": "string"},
235-
"severity": {"type": "string"},
236-
"date": {"type": "string"},
237-
"time": {"type": "string"},
238-
"latitude": {"type": "number"},
239-
"longitude": {"type": "number"},
240-
"website": {"type": "string"},
241-
"citation": {
242-
"type": "object",
243-
"properties": {
244-
"url": {"type": "string"},
245-
"title": {"type": "string"},
246-
"description": {"type": "string"}
247-
}
248-
}
249-
},
250-
"required": ["id", "title", "description"]
251-
}
252-
}
253-
},
254-
"required": ["events", "restaurants", "alerts"]
255-
}
256-
```
56+
![AI Insights](https://raw.githubusercontent.com/anevsky/CityPulse/main/assets/CityPulse-GeoSearch-App-3.jpg)
25757

25858
## Links
25959

26060
- [GitHub Repository](https://github.com/anevsky/CityPulse)
26161
- [Live Demo](https://citypulse-ppx.uc.r.appspot.com/)
26262
- [Video Demo](https://youtu.be/Y0UIhh3diJg)
263-
- [Perplexity API Documentation](https://docs.perplexity.ai)
26463
- **[Built with ❤️ by Alex Nevsky](https://alexnevsky.com)**
265-
266-
## Limitations
267-
268-
- **API Rate Limits**: Perplexity API has usage limits depending on your plan
269-
- **Real-time Data Accuracy**: Information freshness depends on available sources
270-
- **Geographic Coverage**: Results quality varies by location and data availability
271-
- **Citation Reliability**: Always verify critical information from provided sources
272-
- **Mobile Performance**: Large datasets may impact performance on slower devices

0 commit comments

Comments
 (0)