Skip to content

Tushar1805/perplexity_clone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Perplexity Clone πŸ”

A Perplexity-style Q&A app built with Flutter (frontend) and FastAPI (backend).

This project was created to sharpen skills in Streams & WebSockets β€” the frontend streams answers from the backend WebSocket and renders them live as Markdown.


πŸ“‹ Table of contents


Project overview

This repository demonstrates a live Q&A streaming flow: a Flutter client connects to a FastAPI backend over WebSockets and displays streaming text chunks as Markdown. The app is optimized for local development across Android, iOS, Web and Desktop using simple networking patterns for connecting emulators and physical devices.

πŸ“‚ Project structure

perplexity_clone/
β”‚
β”œβ”€β”€ lib/                         # Flutter source code
β”‚   β”œβ”€β”€ main.dart
β”‚   β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ presentation/
β”‚   └── services/
β”‚
β”œβ”€β”€ assets/
β”‚   β”œβ”€β”€ images/
β”‚   └── ...
β”‚
β”œβ”€β”€ server/                      # Backend (FastAPI)
β”‚   β”œβ”€β”€ main.py                  # FastAPI app (contains http & ws endpoints)
β”‚   β”œβ”€β”€ requirements.txt         # pip dependencies
β”‚   β”œβ”€β”€ README.md                # backend-specific docs (optional)
β”‚   └── venv/                    # virtualenv (should be in .gitignore)
β”‚
β”œβ”€β”€ pubspec.yaml                 # Flutter metadata & deps
β”œβ”€β”€ README.md                    # This file
└── .gitignore

πŸ–₯ Backend (FastAPI) β€” setup & run

Requirements

  • Python 3.9+
  • pip
  • (recommended) virtualenv or python -m venv
  • adb if you plan to connect a physical Android device via USB

Create & activate virtualenv

cd server
python3 -m venv venv

Windows (PowerShell)

# If PowerShell prevents script execution, run once as admin or for current user
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# Activate venv
.\venv\Scripts\activate

macOS / Linux

source ./venv/bin/activate

⚠️ Make sure Python is installed and accessible from your PATH.

Install dependencies

pip install -r requirements.txt

Example server/requirements.txt

fastapi
uvicorn[standard]
websockets
python-dotenv  # optional, if you use .env

(You can pin versions for reproducible environments.)

Run the server

Recommended (explicit uvicorn command β€” binds to all interfaces so mobile devices can reach it):

uvicorn main:app --reload --host 0.0.0.0 --port 8000

If you prefer the FastAPI CLI and it's available:

fastapi dev main.py

API keys setup (Tavily & Google Gemini)

This project requires external API keys for Tavily (search) and Google Gemini (LLM) integrations.

1. Tavily API Key

  • Go to Tavily and sign up.
  • Create a new project and generate an API key.
  • Copy the key (e.g., tvly-dev-...).

2. Google Gemini API Key

  • Go to Google AI Studio or the Google Cloud Console.
  • Enable Generative Language API.
  • Create credentials β†’ API key.
  • Copy the key (starts with AIza...).

What to expect

  • HTTP API (example): http://127.0.0.1:8000/chat
  • WebSocket: ws://127.0.0.1:8000/ws/chat

Tip: use --host 0.0.0.0 when you want other devices on the LAN to access the server (e.g., http://192.168.x.y:8000).

πŸ“± Connecting mobile devices

A. Physical Android device (USB)

Use adb reverse to map device port β†’ PC port so the device can use localhost on your PC.

adb devices                       # ensure device is connected & authorized
adb reverse tcp:8000 tcp:8000

Then in your Flutter app you can point to:

http://127.0.0.1:8000
ws://127.0.0.1:8000/ws/chat

If using adb connect <DEVICE_IP> (device over Wi‑Fi):

adb -s <device-ip-or-id> reverse tcp:8000 tcp:8000

B. Android Emulator

  • Android Emulator (AVD): use 10.0.2.2:8000 to reach your machine's localhost.
  • Genymotion: use 10.0.3.2:8000.

C. If adb reverse fails (alternative)

Run the backend listening on 0.0.0.0:

uvicorn main:app --reload --host 0.0.0.0 --port 8000

Find your PC’s LAN IP (e.g. 192.168.1.42) and connect from the device to:

http://192.168.1.42:8000
ws://192.168.1.42:8000/ws/chat

Make sure firewall rules allow incoming connections on port 8000.


πŸš€ Frontend (Flutter) β€” setup & run

1. Install dependencies

flutter pub get

2. Generate localization (if your project uses it)

flutter gen-l10n

3. App icon setup (optional)

Add the following to pubspec.yaml:

flutter_launcher_icons:
  android: true
  ios: true
  image_path: "assets/images/app_icon.png"

Then run:

flutter pub run flutter_launcher_icons

4. Splash screen setup (optional)

Add to pubspec.yaml:

flutter_native_splash:
  color: "#51B848"
  image: assets/images/logo_large.png
  android: true
  ios: true
  fullscreen: true

Then run:

flutter pub run flutter_native_splash:create

5. Run the app

flutter run

Networking note

Use http://10.0.2.2:8000 on AVD emulator, or http://127.0.0.1:8000 if you used adb reverse with a physical device. If you used your PC LAN IP, point the app to http://<PC_IP>:8000 and ws://<PC_IP>:8000/ws/chat.


🧩 Environment / config example

If you want configurable endpoints, use a .env in server/ or a constants file in Flutter.

server/.env

HOST=0.0.0.0
PORT=8000

Flutter example

// lib/core/constants.dart
const backendHost = 'http://10.0.2.2:8000';
const websocketUrl = 'ws://10.0.2.2:8000/ws/chat';

πŸ›  Troubleshooting tips

adb reverse not working

  • Confirm adb devices shows your device and it is device (not unauthorized).
  • Reconnect USB, accept the RSA prompt on the device.
  • Use adb -s <id> reverse ... if multiple devices are attached.
  • Alternative: host on 0.0.0.0 and use PC LAN IP.

WebSocket connection refused

  • Ensure backend is running and listening on the port you expect.
  • If using 127.0.0.1 on backend, mobile device may not reach it β€” use adb reverse or 0.0.0.0 + PC IP.
  • Check firewall/antivirus blocking the port.

CORS / security

  • WebSocket from Flutter mobile clients generally does not require CORS.
  • For web builds, ensure your server adds appropriate CORS headers (e.g., using fastapi.middleware.cors.CORSMiddleware).

Large streamed messages / chunking

  • If streaming text in chunks, ensure the client correctly appends chunks and updates UI on the main thread (use setState or state management callbacks).
  • Consider a small backpressure or rate-limiting in the backend if your client cannot keep up.

Slow scroll-to-bottom / UI not updating

  • Ensure you call scroll after the frame is rendered: WidgetsBinding.instance.addPostFrameCallback.
  • Use ListView with controller.jumpTo or animateTo after new chunks arrive.

Tokenization / encoding issues

  • Make sure you agree on encoding (usually UTF-8) and avoid sending binary chunks as text unless both sides expect it.

✨ Features

  • Streaming answers from FastAPI WebSocket to Flutter via a Stream.
  • Live Markdown rendering for richly formatted answers.
  • Skeleton loaders while waiting for content.
  • Clear separation between backend and frontend for local development.
  • Designed to work on Web, Android, iOS and Desktop.

πŸŽ₯ Demo

perplexiy_clone_demo.mp4

🀝 Contributing

  1. Fork the repo.
  2. Create a feature branch: git checkout -b feat/your-feature.
  3. Commit and push: git commit -am "Add feature" && git push origin feat/your-feature.
  4. Open a Pull Request with a clear description and testing steps.

Open issues for bugs or feature requests and keep backend/frontend changes split with documented env variables.


πŸ“¬ Contact

If you want help setting this up, want features added, or want to collaborate:

Happy hacking β€” stream safely and render beautifully!

About

A Perplexity-style Q&A app built with Flutter (frontend) and FastAPI (backend).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published