Spaces:
Sleeping
Sleeping
| title: Simple Chatbot | |
| emoji: π€ | |
| colorFrom: indigo | |
| colorTo: purple | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| # π€ Simple Chatbot | |
| A sleek, real-time AI chatbot built with **FastAPI** and vanilla **HTML/CSS/JS**, powered by [OpenRouter](https://openrouter.ai/) for free access to various AI models. | |
|  | |
|  | |
|  | |
| --- | |
| ## β¨ Features | |
| | Feature | Description | | |
| |---------|-------------| | |
| | π **Streaming Responses** | AI replies appear in real-time, token by token β no waiting for the full response | | |
| | π¬ **Conversation Memory** | Full chat history is maintained within a session so the AI remembers context | | |
| | π¨ **Premium Dark UI** | Glassmorphism design with ambient gradient blobs and smooth animations | | |
| | β‘ **Quick Suggestions** | Clickable prompt starters on the welcome screen to get started fast | | |
| | π **Markdown Rendering** | Supports bold, italic, inline code, and code blocks in responses | | |
| | π± **Responsive Design** | Works beautifully on desktop and mobile screens | | |
| | π **New Chat** | One-click reset to clear history and start fresh | | |
| --- | |
| ## π Project Structure | |
| ``` | |
| Simple Chatbot/ | |
| βββ main.py # FastAPI backend β API routes & OpenRouter integration | |
| βββ static/ | |
| β βββ index.html # Frontend HTML β chat UI layout | |
| β βββ style.css # Styling β dark theme, glassmorphism, animations | |
| β βββ script.js # Frontend logic β streaming, history, markdown | |
| βββ .env # Environment variables (API key) | |
| βββ pyproject.toml # Python project config & dependencies | |
| βββ uv.lock # Dependency lock file | |
| βββ README.md # You are here! | |
| ``` | |
| --- | |
| ## π Getting Started | |
| ### Prerequisites | |
| - **Python 3.13+** installed | |
| - **[uv](https://docs.astral.sh/uv/)** package manager (recommended) or `pip` | |
| - An **OpenRouter API key** β get one free at [openrouter.ai/keys](https://openrouter.ai/keys) | |
| ### 1. Clone the Repository | |
| ```bash | |
| git clone <your-repo-url> | |
| cd "Simple Chatbot" | |
| ``` | |
| ### 2. Set Up Environment Variables | |
| Create a `.env` file in the project root: | |
| ```env | |
| OPENROUTER_API_KEY=sk-or-v1-your-api-key-here | |
| ``` | |
| > β οΈ **Never commit your `.env` file to version control.** It's already in `.gitignore`. | |
| ### 3. Install Dependencies | |
| **Using uv (recommended):** | |
| ```bash | |
| uv sync | |
| ``` | |
| **Using pip:** | |
| ```bash | |
| pip install fastapi uvicorn openai python-dotenv | |
| ``` | |
| ### 4. Run the Server | |
| ```bash | |
| uv run python -m uvicorn main:app --reload --port 8000 | |
| ``` | |
| ### 5. Open the Chatbot | |
| Navigate to **[http://127.0.0.1:8000](http://127.0.0.1:8000)** in your browser. That's it! π | |
| --- | |
| ## π§ How It Works | |
| ### Architecture Overview | |
| ``` | |
| ββββββββββββββββ POST /api/chat ββββββββββββββββ Stream ββββββββββββββββ | |
| β β ββββββββββββββββββββββββββββΊ β β ββββββββββββββββΊ β β | |
| β Browser β { messages: [...] } β FastAPI β completions β OpenRouter β | |
| β (Frontend) β ββββββββββββββββββββββββββ β (Backend) β ββββββββββββββ β (AI API) β | |
| β β Streaming text chunks β β SSE chunks β β | |
| ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ | |
| ``` | |
| ### Step-by-Step Flow | |
| 1. **User types a message** in the textarea and hits Enter (or clicks send) | |
| 2. **Frontend** appends the message to the local `conversationHistory` array | |
| 3. **Frontend sends** the full conversation history to `POST /api/chat` | |
| 4. **Backend** forwards the messages to OpenRouter's API with `stream=True` | |
| 5. **Backend streams** each text chunk back to the frontend as it arrives | |
| 6. **Frontend renders** each chunk in real-time with a blinking cursor animation | |
| 7. **Assistant response** is saved to `conversationHistory` for context in future messages | |
| ### API Endpoint | |
| #### `POST /api/chat` | |
| Streams a chat completion from the AI model. | |
| **Request Body:** | |
| ```json | |
| { | |
| "messages": [ | |
| { "role": "user", "content": "Hello, who are you?" }, | |
| { "role": "assistant", "content": "I'm an AI assistant..." }, | |
| { "role": "user", "content": "Tell me a joke" } | |
| ] | |
| } | |
| ``` | |
| **Response:** `text/plain` streamed response (chunked transfer encoding) | |
| --- | |
| ## π§ Memory & Context | |
| The chatbot maintains **in-session memory**: | |
| - β **Within a session** β the AI remembers everything you've said | |
| - β **Across page refreshes** β memory is lost (stored in browser JS only) | |
| - β **Across sessions** β no database persistence | |
| The full conversation history is sent with every request, so the AI model has complete context to generate relevant responses. | |
| --- | |
| ## βοΈ Configuration | |
| ### Changing the AI Model | |
| In `main.py`, modify the `model` parameter: | |
| ```python | |
| stream = client.chat.completions.create( | |
| model="openrouter/free", # β Change this | |
| messages=[m.model_dump() for m in request.messages], | |
| stream=True, | |
| ) | |
| ``` | |
| **Popular free models on OpenRouter:** | |
| | Model | ID | | |
| |-------|----| | |
| | Auto (free tier) | `openrouter/free` | | |
| | Gemma 3 | `google/gemma-3-27b-it:free` | | |
| | Llama 4 Scout | `meta-llama/llama-4-scout:free` | | |
| | Mistral Small | `mistralai/mistral-small-3.1-24b-instruct:free` | | |
| Browse all models at [openrouter.ai/models](https://openrouter.ai/models). | |
| ### Changing the Port | |
| ```bash | |
| uv run python -m uvicorn main:app --reload --port 3000 | |
| ``` | |
| --- | |
| ## π¦ Dependencies | |
| | Package | Purpose | | |
| |---------|---------| | |
| | `fastapi` | Web framework for the API server | | |
| | `uvicorn` | ASGI server to run FastAPI | | |
| | `openai` | OpenAI-compatible client (works with OpenRouter) | | |
| | `python-dotenv` | Loads `.env` variables into the environment | | |
| --- | |
| ## π οΈ Development | |
| ### Hot Reload | |
| The server runs with `--reload`, so any changes to Python files will auto-restart the server. For frontend changes (HTML/CSS/JS), just refresh the browser. | |
| ### Project Dependencies | |
| All dependencies are managed via `pyproject.toml` and locked in `uv.lock`. To add a new package: | |
| ```bash | |
| uv add <package-name> | |
| ``` | |
| --- | |
| ## βοΈ Deploying to Hugging Face Spaces | |
| You can deploy this chatbot for free on [Hugging Face Spaces](https://huggingface.co/spaces) using Docker. | |
| ### 1. Create a Hugging Face Account | |
| Sign up at [huggingface.co/join](https://huggingface.co/join) if you don't have an account. | |
| ### 2. Create a New Space | |
| 1. Go to [huggingface.co/new-space](https://huggingface.co/new-space) | |
| 2. Fill in: | |
| - **Space name:** `simple-chatbot` | |
| - **SDK:** Select **Docker** | |
| - **Visibility:** Public or Private | |
| 3. Click **Create Space** | |
| ### 3. Set Your API Key as a Secret | |
| > β οΈ **Do NOT push your `.env` file.** Use Space Secrets instead. | |
| 1. In your Space, go to **Settings** β **Variables and secrets** | |
| 2. Click **New secret** | |
| 3. Set: | |
| - **Name:** `OPENROUTER_API_KEY` | |
| - **Value:** Your OpenRouter API key | |
| 4. Save β HF automatically injects secrets as environment variables | |
| ### 4. Push Your Code | |
| **Option A β Add HF as a remote (recommended if you already have a git repo):** | |
| ```bash | |
| git remote add hf https://huggingface.co/spaces/YOUR_USERNAME/simple-chatbot | |
| git push hf main | |
| ``` | |
| **Option B β Clone and copy:** | |
| ```bash | |
| git clone https://huggingface.co/spaces/YOUR_USERNAME/simple-chatbot | |
| # Copy your project files into the cloned repo | |
| cd simple-chatbot | |
| git add . | |
| git commit -m "Initial deployment" | |
| git push | |
| ``` | |
| > π‘ Replace `YOUR_USERNAME` with your Hugging Face username. | |
| ### 5. Wait for Build & Go Live | |
| 1. Visit `https://huggingface.co/spaces/YOUR_USERNAME/simple-chatbot` | |
| 2. Watch the build logs under the **"Building"** status badge | |
| 3. Once it shows **"Running"**, your chatbot is live at: | |
| ``` | |
| https://YOUR_USERNAME-simple-chatbot.hf.space | |
| ``` | |
| ### Troubleshooting | |
| | Issue | Fix | | |
| |-------|-----| | |
| | Build fails on `requirements.txt` | Make sure the file is committed and not in `.dockerignore` | | |
| | "API key not found" crash | Verify the secret name is exactly `OPENROUTER_API_KEY` in Space Settings | | |
| | Port mismatch error | Ensure `app_port: 7860` in README frontmatter matches `EXPOSE 7860` in Dockerfile | | |
| | Space is sleeping | Free Spaces sleep after inactivity β visit the URL to wake it, or upgrade for persistent uptime | | |
| --- | |
| ## π License | |
| This project is open source and available under the [MIT License](LICENSE). | |
| --- | |
| ## π Acknowledgments | |
| - [OpenRouter](https://openrouter.ai/) β Free AI model access | |
| - [FastAPI](https://fastapi.tiangolo.com/) β Modern Python web framework | |
| - [Inter Font](https://rsms.me/inter/) β Clean UI typography | |