Production-style portfolio project: an AI real estate chatbot for the fictional brokerage Radar Estate.
RadarBot answers natural-language questions by retrieving grounded facts from a property database. It does not invent listings, prices, or availability.
- FastAPI backend with SQLAlchemy + Pydantic
- SQLite by default (PostgreSQL-ready)
- Hybrid search: structured filters + Sentence Transformers + FAISS
- Conversational memory (follow-ups like “Which one is the cheapest?”)
- Ollama-first LLM integration (OpenAI-compatible fallback)
- Admin dashboard (add / edit / delete / upload images)
- Favorites, compare, mortgage calculator, schedule viewing, recommendations
- Modern responsive UI with dark mode, chat bubbles, typing indicator, voice I/O hooks
- Docker + Pytest
radarbot/
├── backend/ # FastAPI app, config, dependencies
├── chatbot/ # Intent parsing, memory, LLM, safety
├── database/ # Session, schema.sql, seed, sample data
├── embeddings/ # Encoder + FAISS index
├── frontend/ # HTML/CSS/JS UI
├── models/ # SQLAlchemy ORM
├── routers/ # API routes
├── schemas/ # Pydantic contracts
├── services/ # Business logic
├── scripts/ # init_db, rebuild_index
├── tests/ # Pytest suite
├── Dockerfile
├── docker-compose.yml
└── requirements.txt
- Python 3.11+ (recommended;
python3.11 -m venv .venv) - Optional: Ollama with a chat model (
ollama pull llama3.2) - Optional heavy deps for semantic search:
faiss-cpu,sentence-transformers(installed viarequirements.txt)
cd Radarbot
python3.11 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -U pip
pip install -r requirements.txt
cp .env.example .envTip: If FAISS / Sentence Transformers install slowly, you can still run the app — structured search and deterministic chat replies work without them.
python scripts/init_db.pyThis creates tables, seeds sample listings/agents, creates the admin user, and builds the FAISS index.
uvicorn backend.main:app --reload --host 0.0.0.0 --port 3000Open:
- Home: http://127.0.0.1:3000/
- Chat: http://127.0.0.1:3000/chat
- Admin: http://127.0.0.1:3000/admin
- API docs: http://127.0.0.1:3000/docs
- Email:
admin@radarestate.com - Password:
Admin123!
Local (Ollama):
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3.2:latestCloud / Render (Groq — recommended):
LLM_PROVIDER=groq
GROQ_API_KEY=gsk_...
GROQ_MODEL=llama-3.3-70b-versatileGet a free key at console.groq.com/keys.
OpenAI:
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o-miniIf the LLM is offline, RadarBot still answers using deterministic, database-grounded formatters.
Repo: github.com/Oloyededaniel/radarbot
- Create a free Groq API key: console.groq.com/keys
- Open Render Dashboard → New → Blueprint
- Connect GitHub and select
Oloyededaniel/radarbot - Render reads
render.yamland creates theradarbotweb service - Set these env vars when prompted:
GROQ_API_KEY= your Groq keyADMIN_PASSWORD= a password you choose (e.g.Admin123!)
- Deploy
After deploy:
- App:
https://radarbot.onrender.com(or the URL Render shows) - Chat:
/chat - Admin:
/admin(emailadmin@radarestate.com)
Notes:
- Free Render services sleep after inactivity — first request may take ~30–60s
- SQLite is used for the demo; data resets if the instance is fully replaced
- Cloud deploys use
requirements-render.txt(no Torch/FAISS) for faster builds; chat uses Groq
| Method | Path | Description |
|---|---|---|
| GET | /properties |
List properties |
| GET | /property/{id} |
Property detail |
| GET | /search |
Filtered / hybrid search |
| POST | /chat |
Chat with RadarBot |
| POST | /login |
JWT login |
| POST | /register |
Create customer account |
| POST | /admin/add |
Add listing (admin) |
| PUT | /admin/update?property_id= |
Update listing (admin) |
| DELETE | /admin/delete?property_id= |
Delete listing (admin) |
| POST | /admin/upload |
Upload image (admin) |
| POST | /compare |
Compare listings |
| POST | /mortgage |
Mortgage estimate |
| POST | /viewing |
Schedule viewing |
| POST | /email-agent |
Queue agent email |
| GET/POST/DELETE | /favorites |
Favorites |
| GET | /recommendations/{id} |
Similar homes |
- What houses do you have in Vancouver?
- Show me all apartments under $700,000.
- Which properties have 4 bedrooms?
- Do you have homes with swimming pools?
- What is Listing 1045?
- Compare Listing 101 and Listing 215.
- I need a family home.
- I'm a student.
- Which one is the cheapest? (follow-up)
docker compose up --buildThe API serves on port 3000. Ollama on the host is reachable via host.docker.internal.
PostgreSQL optional profile:
docker compose --profile postgres up --buildThen set:
DATABASE_URL=postgresql+psycopg2://radarbot:radarbot@db:5432/radarbotpytest -q- Retrieve from the database first.
- Format or generate answers only from retrieved rows.
- If missing, reply:
I couldn't find that information in the Radar Estate listings.
- Prefer Groq on Render (
LLM_PROVIDER=groq). - Set a strong
SECRET_KEY(Render can auto-generate). - Use PostgreSQL for durable production data if needed.
- Keep admin credentials and API keys in Render env vars only — never commit
.env. - Optional local semantic search:
pip install -r requirements.txt(includes FAISS + Sentence Transformers).
MIT — portfolio / educational use.