A full-stack web application demonstrating how to integrate ChatGPT API with a modern web interface. This tutorial covers everything from basic HTML/CSS/JavaScript to advanced FastAPI backend development.
This project demonstrates:
- Frontend: Modern HTML5, CSS3, and Vanilla JavaScript
- Backend: FastAPI with Python 3.10+
- Integration: Real-time ChatGPT API communication
- Best Practices: Error handling, CORS, responsive design
Complete application in under 200 lines of code!
Already have the files? Skip to running:
- Get OpenAI API Key: platform.openai.com/api-keys
- Create
.env
file in project root:OPENAI_API_KEY=your-actual-api-key-here
- Install dependencies:
pip install fastapi uvicorn openai python-dotenv
- Start backend (Terminal 1):
python -m uvicorn backend.main:app --reload --port 8000
- Start frontend (Terminal 2):
python -m http.server 3000
- Open: http://localhost:3000
New to the project? Continue with full setup below.
- Operating System: Windows 10+, macOS 10.14+, or Linux (Ubuntu 18.04+)
- Python 3.10+ - Download Python
- Node.js 16+ (optional, for npm scripts) - Download Node.js
- Internet Connection - Required for OpenAI API calls
- OpenAI API Key - Get API Key
⚠️ Cost Warning: Each API call costs money (typically $0.002 per 1K tokens)- Consider setting usage limits in your OpenAI dashboard
- Text Editor - VS Code recommended
- Terminal/Command Prompt - Git Bash for Windows, Terminal for macOS/Linux
# Check Python version (must be 3.10+)
python --version
# If above fails on Windows, try:
python3 --version
# or
py --version
# Check if pip is available
pip --version
# If above fails, try:
pip3 --version
# or
py -m pip --version
# Verify internet connection
ping google.com
- Use Git Bash or PowerShell (Command Prompt may have issues)
- Python path: Ensure Python is added to PATH during installation
- Virtual environment activation:
source venv/Scripts/activate
(Git Bash) orvenv\Scripts\activate.bat
(Command Prompt)
- Python installation: Use Homebrew (
brew install python
) or official installer - Virtual environment activation:
source venv/bin/activate
- Install Python:
sudo apt install python3 python3-pip python3-venv
(Ubuntu/Debian) - Virtual environment activation:
source venv/bin/activate
First, let's create the complete folder structure for our project:
# Create the main project directory
mkdir simple-chatgpt-app
cd simple-chatgpt-app
# Create frontend directories
mkdir css js
# Create backend directory
mkdir backend
# Create configuration directory
mkdir .cursor
mkdir .cursor/rules
# Create the main files
touch index.html
touch css/styles.css
touch js/api.js
touch backend/main.py
touch main.py
touch package.json
touch .env
touch .gitignore
touch README.md
Your project should now have this structure:
simple-chatgpt-app/
├── index.html # Main HTML file
├── css/
│ └── styles.css # CSS styling
├── js/
│ └── api.js # JavaScript functionality
├── backend/
│ └── main.py # FastAPI server
├── main.py # Entry point for uvicorn
├── package.json # Project configuration
├── .env # Environment variables
├── .gitignore # Git ignore file
├── README.md # This file
└── .cursor/
└── rules/ # Cursor rules (optional)
# Initialize git repository
git init
# Create .gitignore file
cat > .gitignore << EOF
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/
env.bak/
venv.bak/
# Environment variables
.env
.env.local
.env.production
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Logs
*.log
EOF
# Make initial commit
git add .
git commit -m "Initial project setup"
Start by creating the main HTML file: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple ChatGPT App</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="container">
<!-- Header -->
<h1>🤖 Simple ChatGPT App</h1>
<!-- Input Section -->
<div class="input-section">
<label for="user-input">Ask ChatGPT anything:</label>
<textarea
id="user-input"
placeholder="Type your question here... For example: 'Explain quantum physics in simple terms' or 'Write a short poem about coding'"
></textarea>
<!-- Example Questions -->
<div class="example-questions">
<h3>💡 Try these examples:</h3>
<button class="example-btn" onclick="fillExample('Explain artificial intelligence in simple terms')">
What is AI?
</button>
<button class="example-btn" onclick="fillExample('Write a short poem about programming')">
Write a poem
</button>
<button class="example-btn" onclick="fillExample('Give me 3 tips for learning JavaScript')">
JavaScript tips
</button>
<button class="example-btn" onclick="fillExample('What are the benefits of exercise?')">
Exercise benefits
</button>
</div>
<button id="send-btn" onclick="sendToChatGPT()">
Send to ChatGPT
</button>
</div>
<!-- Response Section -->
<div class="response-section">
<label>ChatGPT Response:</label>
<div id="ai-response">
<div class="placeholder">
Your AI response will appear here after you send a message...
</div>
</div>
</div>
</div>
</body>
<script src="js/api.js"></script>
</html>
Key HTML Concepts:
- Semantic HTML: Proper use of
<div>
,<section>
,<label>
- Accessibility:
for
attributes linking labels to inputs - Responsive Design: Viewport meta tag for mobile compatibility
- Clean Structure: Logical organization of content sections
Create the CSS file: css/styles.css
/* Reset and Base Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.container {
background: white;
border-radius: 15px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
max-width: 600px;
width: 100%;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
font-size: 2.5em;
}
.input-section {
margin-bottom: 30px;
}
label {
display: block;
margin-bottom: 10px;
font-weight: 600;
color: #555;
}
#user-input {
width: 100%;
padding: 15px;
border: 2px solid #e0e0e0;
border-radius: 10px;
font-size: 16px;
resize: vertical;
min-height: 120px;
transition: border-color 0.3s ease;
}
#user-input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
#send-btn {
width: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px;
border-radius: 10px;
font-size: 18px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 15px;
}
#send-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
}
#send-btn:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
}
.response-section {
margin-top: 30px;
padding-top: 30px;
border-top: 2px solid #f0f0f0;
}
#ai-response {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 10px;
padding: 20px;
min-height: 100px;
font-size: 16px;
line-height: 1.6;
color: #333;
}
.loading {
text-align: center;
color: #666;
font-style: italic;
}
.error {
background: #f8d7da;
color: #721c24;
border-color: #f5c6cb;
}
.placeholder {
color: #999;
text-align: center;
font-style: italic;
}
.example-questions {
margin-top: 20px;
padding: 15px;
background: #e7f3ff;
border-radius: 8px;
}
.example-questions h3 {
margin-bottom: 10px;
color: #0066cc;
font-size: 1.1em;
}
.example-btn {
background: #0066cc;
color: white;
border: none;
padding: 8px 12px;
border-radius: 5px;
margin: 5px;
cursor: pointer;
font-size: 14px;
transition: background 0.3s ease;
}
.example-btn:hover {
background: #0052a3;
}
Key CSS Concepts:
- CSS Reset: Normalize browser defaults
- Flexbox Layout: Modern layout system
- CSS Gradients: Beautiful background effects
- Transitions: Smooth hover animations
- Responsive Design: Mobile-friendly styling
- CSS Variables: Consistent color scheme
Create the JavaScript file: js/api.js
// ============================================================================
// JAVASCRIPT APPLICATION
// ============================================================================
/**
* Fill the input with an example question
*/
function fillExample(text) {
document.getElementById('user-input').value = text;
document.getElementById('user-input').focus();
}
/**
* Send user input to ChatGPT via our backend API
*/
async function sendToChatGPT() {
// Get user input
const userInput = document.getElementById('user-input').value.trim();
const sendBtn = document.getElementById('send-btn');
const responseDiv = document.getElementById('ai-response');
// Validate input
if (!userInput) {
alert('Please enter a question first!');
return;
}
try {
// Update UI to show loading state
sendBtn.disabled = true;
sendBtn.textContent = 'Sending to ChatGPT...';
responseDiv.innerHTML = '<div class="loading">🤖 ChatGPT is thinking...</div>';
console.log('📤 Sending to ChatGPT:', userInput);
// Make API call to our backend
const response = await fetch('http://localhost:8000/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: userInput
})
});
// Check if request was successful
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// Parse JSON response
const data = await response.json();
console.log('📥 Received from ChatGPT:', data);
// Display the AI response
displayResponse(data.response);
} catch (error) {
console.error('❌ Error:', error);
// Show error message to user
responseDiv.innerHTML = `
<div class="error">
<strong>Oops! Something went wrong:</strong><br>
${error.message}<br><br>
<em>Make sure the backend server is running on http://localhost:8000</em>
</div>
`;
} finally {
// Reset button state
sendBtn.disabled = false;
sendBtn.textContent = 'Send to ChatGPT';
}
}
/**
* Display the ChatGPT response in the UI
*/
function displayResponse(responseText) {
const responseDiv = document.getElementById('ai-response');
// Format the response text (preserve line breaks)
const formattedText = responseText.replace(/\n/g, '<br>');
responseDiv.innerHTML = `
<div style="white-space: pre-line;">
${formattedText}
</div>
`;
}
/**
* Allow Enter key to send message (with Shift+Enter for new lines)
*/
document.getElementById('user-input').addEventListener('keydown', function(event) {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
sendToChatGPT();
}
});
// Initialize
console.log('✅ Simple ChatGPT App loaded and ready!');
Key JavaScript Concepts:
- Async/Await: Modern asynchronous programming
- Fetch API: Making HTTP requests
- DOM Manipulation: Updating page elements
- Error Handling: Graceful error management
- Event Listeners: User interaction handling
- Console Logging: Debugging and monitoring
First, create a Python virtual environment:
# Create virtual environment
python -m venv venv
# Activate virtual environment (Windows Git Bash)
source venv/Scripts/activate
# Activate virtual environment (macOS/Linux)
source venv/bin/activate
# Verify activation (should show venv in prompt)
which python
Install required dependencies:
# Install FastAPI and related packages
pip install fastapi uvicorn openai python-dotenv
# Verify installations
python -c "import fastapi, uvicorn, openai; print('✅ All packages installed successfully!')"
# Or use the project script (if package.json exists)
npm setup
# or
pnpm setup
Create the package.json
file:
# Create package.json with project scripts
cat > package.json << 'EOF'
{
"name": "simple-chatgpt-app",
"version": "1.0.0",
"description": "A simple ChatGPT integration with FastAPI backend",
"main": "index.html",
"scripts": {
"setup": "python -m pip install -r requirements.txt",
"run-backend": "python -m uvicorn backend.main:app --reload --host localhost --port 8000",
"run-website": "python -m http.server 3000 --bind localhost",
"dev": "concurrently \"npm run run-backend\" \"npm run run-website\"",
"build": "echo 'Building frontend assets...' && mkdir -p dist && cp -r css js index.html dist/",
"test": "echo 'No tests specified yet'"
},
"keywords": [
"chatgpt",
"fastapi",
"javascript",
"html",
"css"
],
"author": "Your Name",
"license": "MIT"
}
EOF
Create the requirements.txt
file:
# Create requirements.txt with Python dependencies
cat > requirements.txt << 'EOF'
fastapi==0.104.1
uvicorn[standard]==0.24.0
openai==1.3.7
python-dotenv==1.0.0
pydantic==2.5.0
EOF
Create a .env
file in your project root:
# Create .env file with your OpenAI API key
cat > .env << 'EOF'
# OpenAI Configuration
OPENAI_API_KEY=sk-your-actual-api-key-here
# Server Configuration
DEBUG=True
PORT=8000
HOST=localhost
EOF
sk-your-actual-api-key-here
with your real OpenAI API key!
You can get your API key from: https://platform.openai.com/api-keys
Check that all files are created correctly:
# List all files and directories
ls -la
# Check the project structure
tree . || find . -type f -name "*.py" -o -name "*.html" -o -name "*.css" -o -name "*.js" | sort
# Verify key files exist
echo "Checking key files..."
[ -f "index.html" ] && echo "✅ index.html exists" || echo "❌ index.html missing"
[ -f "css/styles.css" ] && echo "✅ css/styles.css exists" || echo "❌ css/styles.css missing"
[ -f "js/api.js" ] && echo "✅ js/api.js exists" || echo "❌ js/api.js missing"
[ -f "backend/main.py" ] && echo "✅ backend/main.py exists" || echo "❌ backend/main.py missing"
[ -f "package.json" ] && echo "✅ package.json exists" || echo "❌ package.json missing"
[ -f ".env" ] && echo "✅ .env exists" || echo "❌ .env missing"
Create the main backend file: backend/main.py
"""
Simple ChatGPT Integration Backend
This is a minimal FastAPI server that:
1. Receives text from the frontend
2. Sends it to ChatGPT
3. Returns the AI response
Only ~80 lines of actual code!
"""
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from openai import OpenAI
import os
from dotenv import load_dotenv
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Load environment variables
load_dotenv()
# Configure OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Create FastAPI app
app = FastAPI(
title="Simple ChatGPT API",
description="A minimal API that sends text to ChatGPT and returns responses",
version="1.0.0"
)
# Enable CORS so frontend can call the backend
app.add_middleware(
CORSMiddleware,
allow_origins=[
"http://localhost:3000",
"http://127.0.0.1:3000",
"http://[::1]:3000", # IPv6 localhost
"http://localhost:3001",
"http://127.0.0.1:3001",
"http://[::1]:3001"
],
allow_methods=["POST", "GET", "OPTIONS"],
allow_headers=["*"],
allow_credentials=True,
)
# ============================================================================
# DATA MODELS
# ============================================================================
class ChatRequest(BaseModel):
"""Model for incoming chat requests"""
message: str
model_config = {
"json_schema_extra": {
"example": {
"message": "Explain artificial intelligence in simple terms"
}
}
}
class ChatResponse(BaseModel):
"""Model for chat responses"""
response: str
# ============================================================================
# API ENDPOINTS
# ============================================================================
@app.get("/")
async def root():
"""Health check endpoint"""
return {
"message": "Simple ChatGPT API is running!",
"status": "healthy",
"api_key_configured": bool(client.api_key)
}
@app.post("/api/chat", response_model=ChatResponse)
async def chat_with_gpt(request: ChatRequest):
"""
Send user message to ChatGPT and return the response
This endpoint:
1. Receives user text from frontend
2. Sends it to OpenAI's ChatGPT API
3. Returns the AI response
4. Handles errors gracefully
"""
try:
# Log the incoming request
logger.info(f"📥 Received message: {request.message[:50]}...")
# Check if API key is configured
if not client.api_key:
logger.error("OpenAI API key not configured")
raise HTTPException(
status_code=500,
detail="OpenAI API key not configured. Please add OPENAI_API_KEY to .env file"
)
# Prepare the ChatGPT request
logger.info("🤖 Sending request to ChatGPT...")
response = client.chat.completions.create(
model="gpt-3.5-turbo", # Cost-effective model
messages=[
{
"role": "system",
"content": "You are a helpful AI assistant. Provide clear, concise, and helpful responses."
},
{
"role": "user",
"content": request.message
}
],
max_tokens=500, # Limit response length
temperature=0.7, # Balanced creativity
)
# Extract the AI response
ai_response = response.choices[0].message.content.strip()
logger.info(f"✅ ChatGPT response received: {len(ai_response)} characters")
# Return structured response
return ChatResponse(response=ai_response)
except Exception as e:
logger.error(f"OpenAI API error: {str(e)}")
raise HTTPException(
status_code=500,
detail=f"ChatGPT service error: {str(e)}"
)
# ============================================================================
# SERVER STARTUP
# ============================================================================
if __name__ == "__main__":
import uvicorn
print("🚀 Starting Simple ChatGPT API...")
print("📚 API Documentation: http://localhost:8000/docs")
print("🔗 Frontend should connect to: http://localhost:8000")
if not os.getenv("OPENAI_API_KEY"):
print("⚠️ WARNING: OPENAI_API_KEY not found in .env file!")
print(" Create a .env file with your OpenAI API key")
else:
print("✅ OpenAI API key configured")
# Start the server
uvicorn.run(
app,
host="localhost",
port=8000,
reload=True,
log_level="info"
)
Key FastAPI Concepts:
- FastAPI Framework: Modern, fast web framework
- CORS Middleware: Cross-origin resource sharing
- Pydantic Models: Data validation and serialization
- Async Endpoints: Non-blocking request handling
- Error Handling: Proper HTTP status codes
- Logging: Request/response monitoring
Create the main entry point: main.py
"""
Main entry point for the Simple ChatGPT application
"""
from backend.main import app
# This allows uvicorn to find the app when running from the root directory
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="localhost", port=8000, reload=True)
# Start FastAPI server
npm run-backend
# or
pnpm run-backend
# Server will run on http://localhost:8000
# API documentation available at http://localhost:8000/docs
# In a new terminal, start the frontend
npm run run-website
# or
pnpm run run-website
# Website will run on http://localhost:3000
If you have concurrently
installed:
# Install concurrently (optional)
npm install -g concurrently
# Run both servers with one command
npm run dev
- Open http://localhost:3000 in your browser
- Try the example questions or type your own
- Check the backend logs for API calls
- Verify the integration is working
# Development workflow commands
npm run run-backend # Start backend only
npm run run-website # Start frontend only
npm run dev # Start both (if concurrently installed)
npm run build # Build for production
npm run test # Run tests (when implemented)
- MDN Web Docs: HTML Guide
- W3Schools: HTML Tutorial
- HTML5 Semantic Elements: MDN Reference
- Accessibility: Web Accessibility Guidelines
- CSS Flexbox: Complete Guide
- CSS Grid: Complete Guide
- CSS Gradients: MDN Guide
- CSS Transitions: MDN Reference
- Responsive Design: CSS Media Queries
- Modern JavaScript: ES6+ Features
- Async/Await: MDN Guide
- Fetch API: MDN Reference
- DOM Manipulation: MDN Guide
- Event Handling: MDN Events
- Official Documentation: FastAPI Docs
- FastAPI Tutorial: Step-by-step guide
- FastAPI Examples: GitHub Repository
- FastAPI Best Practices: Official Guide
- Official Documentation: Pydantic Docs
- Pydantic Tutorial: Getting Started
- Data Validation: Pydantic Guide
- Model Configuration: Pydantic Settings
- Python Official: python.org
- Python Tutorial: Official Guide
- Virtual Environments: venv Documentation
- Python Async: asyncio Documentation
- Frontend Masters: JavaScript Courses
- CSS-Tricks: CSS Articles
- JavaScript.info: Modern JavaScript Tutorial
- Real Python: FastAPI Tutorials
- Python Web Development: Django vs Flask vs FastAPI
- API Design: REST API Guidelines
- OpenAI API: Official Documentation
- OpenAI Cookbook: Examples and Tutorials
- LangChain: LLM Application Framework
- OpenAI API charges per token (~$0.002 per 1K tokens for GPT-3.5-turbo)
- Rate limits apply - 3 requests/minute for free tier users
- No built-in usage tracking - Monitor costs in OpenAI dashboard
- No request caching - Each identical question costs money
- API key in .env file - Not suitable for production deployment
- No input validation - Malicious prompts could be expensive
- No user authentication - Anyone can access your API
- CORS enabled for localhost only - Not production-ready
- No persistent storage - Chat history is lost on page refresh
- No real-time updates - Traditional request/response only
- Fixed response length - Limited to 500 tokens max
- Single conversation - No conversation context/memory
- No file upload support - Text-only interactions
- Local development only - No production deployment guide
- No error recovery - Failed requests require manual retry
- No offline mode - Requires constant internet connection
- Basic UI - Mobile optimization needs improvement
- Use for learning only - Not production-ready
- Set OpenAI usage limits - Prevent unexpected charges
- Monitor API usage - Check OpenAI dashboard regularly
- Test with cheap models first - Start with GPT-3.5-turbo before GPT-4
Error: "ModuleNotFoundError: No module named 'fastapi'"
# Solution: Install dependencies in virtual environment
python -m venv venv
source venv/Scripts/activate # Windows Git Bash
# or venv\Scripts\activate.bat # Windows Command Prompt
# or source venv/bin/activate # macOS/Linux
pip install fastapi uvicorn openai python-dotenv
Error: "OpenAI API key not configured"
# Solution: Create .env file with your API key
echo "OPENAI_API_KEY=your-actual-key-here" > .env
# Restart the backend server after creating .env
Error: "Port 8000 already in use"
# Solution: Kill existing process or use different port
# Windows:
netstat -ano | findstr :8000
taskkill /PID <PID_NUMBER> /F
# macOS/Linux:
lsof -ti:8000 | xargs kill -9
# Or use different port:
python -m uvicorn backend.main:app --reload --port 8001
Error: "CORS policy: No 'Access-Control-Allow-Origin' header"
- Cause: Backend server not running or wrong URL
- Solution: Ensure backend is running on http://localhost:8000
- Check: Visit http://localhost:8000 in browser - should show API status
Error: "fetch failed" or "Failed to fetch"
- Cause: Backend server not reachable
- Solution:
- Check backend server is running
- Check firewall/antivirus blocking ports
- Try http://127.0.0.1:8000 instead of localhost
Error: "Port 3000 already in use"
# Solution: Use different port
python -m http.server 3001
# Then update API URLs in js/api.js to http://localhost:8001 if needed
Error: "Incorrect API key provided"
- Solution: Get valid API key from https://platform.openai.com/api-keys
- Check: API key starts with "sk-" and is 51 characters long
Error: "You exceeded your current quota"
- Cause: No credits in OpenAI account
- Solution: Add payment method at https://platform.openai.com/account/billing
Error: "Rate limit reached"
- Cause: Too many requests (3 requests/minute for free tier)
- Solution: Wait 1 minute between requests or upgrade OpenAI plan
Error: "python: command not found"
# Windows: Try these alternatives
py --version
python3 --version
# Add Python to PATH:
# 1. Find Python installation: where python
# 2. Add to system PATH environment variable
Error: "Permission denied" when creating files
# Solution: Run terminal as administrator (Windows) or use sudo (macOS/Linux)
# Or change to directory you have write permissions
# Check if backend server is running
curl http://localhost:8000/
# Expected response: {"message": "Simple ChatGPT API is running!", ...}
# If curl not available (Windows), use PowerShell:
Invoke-RestMethod -Uri http://localhost:8000/
# Or visit in browser: http://localhost:8000
# Check if frontend is accessible
curl -I http://localhost:3000/
# Expected: HTTP/1.0 200 OK
# Or visit in browser: http://localhost:3000
# Test the chat endpoint directly
curl -X POST http://localhost:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Hello, test message"}'
# PowerShell version:
Invoke-RestMethod -Uri http://localhost:8000/api/chat -Method POST -ContentType "application/json" -Body '{"message": "Hello, test message"}'
# Check Python and virtual environment
python --version
which python # Should show venv path if activated
pip list | grep -E "(fastapi|uvicorn|openai)"
# Windows equivalent:
where python
pip list | findstr "fastapi uvicorn openai"
# Verify .env file exists and has API key
cat .env # macOS/Linux
type .env # Windows
# Check if environment variable is loaded (don't print actual key!)
python -c "import os; from dotenv import load_dotenv; load_dotenv(); print('API Key configured:', bool(os.getenv('OPENAI_API_KEY')))"
- Backend Logs: Watch FastAPI server terminal for error messages
- Browser Console: Open Developer Tools (F12) → Console tab
- Network Tab: Developer Tools → Network tab to see API calls/responses
- API Documentation: Visit http://localhost:8000/docs for interactive API testing
# Check if backend is running
curl http://localhost:8000/
# Check if frontend is accessible
curl http://localhost:3000/
# Verify Python environment
python --version
pip list | grep -E "(fastapi|uvicorn|openai)"
# Check environment variables
echo "OpenAI API Key configured: $([ -n "$OPENAI_API_KEY" ] && echo "Yes" || echo "No")"
Run this comprehensive check to ensure everything is set up correctly:
# 1. Check all required files exist
echo "=== File Structure Check ==="
required_files=("index.html" "css/styles.css" "js/api.js" "backend/main.py" "main.py" "package.json" ".env" "requirements.txt")
for file in "${required_files[@]}"; do
if [ -f "$file" ]; then
echo "✅ $file exists"
else
echo "❌ $file missing - CREATE THIS FILE!"
fi
done
# 2. Check Python environment
echo -e "\n=== Python Environment Check ==="
python --version
pip list | grep -E "(fastapi|uvicorn|openai|python-dotenv|pydantic)" || echo "❌ Missing Python packages - run 'pip install fastapi uvicorn openai python-dotenv'"
# 3. Check API key configuration
echo -e "\n=== API Key Check ==="
if [ -f ".env" ]; then
if grep -q "OPENAI_API_KEY=" .env; then
if grep -q "sk-" .env; then
echo "✅ OpenAI API key configured"
else
echo "❌ API key doesn't look valid (should start with 'sk-')"
fi
else
echo "❌ No OPENAI_API_KEY found in .env file"
fi
else
echo "❌ .env file missing"
fi
# 4. Check port availability
echo -e "\n=== Port Check ==="
if command -v netstat &> /dev/null; then
if netstat -tuln | grep -q ":8000 "; then
echo "⚠️ Port 8000 already in use"
else
echo "✅ Port 8000 available"
fi
if netstat -tuln | grep -q ":3000 "; then
echo "⚠️ Port 3000 already in use"
else
echo "✅ Port 3000 available"
fi
else
echo "ℹ️ Netstat not available - cannot check ports"
fi
echo -e "\n=== Setup Complete! ==="
echo "If all checks passed, you can now run:"
echo "1. Terminal 1: python -m uvicorn backend.main:app --reload --port 8000"
echo "2. Terminal 2: python -m http.server 3000"
echo "3. Open: http://localhost:3000"
For Windows users, create a verify.bat
file:
@echo off
echo === Simple ChatGPT App Verification ===
echo.
echo === File Structure Check ===
for %%f in (index.html css\styles.css js\api.js backend\main.py main.py package.json .env) do (
if exist "%%f" (
echo ✅ %%f exists
) else (
echo ❌ %%f missing
)
)
echo.
echo === Python Environment Check ===
python --version 2>nul || echo ❌ Python not found - install Python 3.10+
pip list | findstr "fastapi uvicorn openai" >nul || echo ❌ Missing packages - run: pip install fastapi uvicorn openai python-dotenv
echo.
echo === API Key Check ===
if exist ".env" (
findstr "OPENAI_API_KEY=" .env >nul && echo ✅ API key configured || echo ❌ No API key in .env
) else (
echo ❌ .env file missing
)
echo.
echo === Port Check ===
netstat -an | findstr ":8000" >nul && echo ⚠️ Port 8000 in use || echo ✅ Port 8000 available
netstat -an | findstr ":3000" >nul && echo ⚠️ Port 3000 in use || echo ✅ Port 3000 available
echo.
echo === Setup Complete ===
echo Run these commands in separate terminals:
echo 1. python -m uvicorn backend.main:app --reload --port 8000
echo 2. python -m http.server 3000
echo 3. Open: http://localhost:3000
pause
For detailed troubleshooting, see the Troubleshooting Guide.
This tutorial is for DEVELOPMENT/LEARNING ONLY. DO NOT deploy to production as-is.
Security Issues to Address:
- API keys in environment files (use secret management)
- No rate limiting (implement request throttling)
- No input validation (sanitize user inputs)
- CORS wide open (restrict to your domain)
- No HTTPS (use SSL certificates)
- No authentication (add user login system)
-
Add Input Validation:
# In backend/main.py, validate message length if len(request.message) > 1000: raise HTTPException(400, "Message too long")
-
Implement Rate Limiting:
pip install slowapi # Add rate limiting to prevent abuse
-
Add Request Logging:
# Log all requests for monitoring logger.info(f"Request from {request.client.host}: {request.message[:50]}")
- Chat History: Store conversations in SQLite/PostgreSQL
- User Authentication: Add login/signup with JWT tokens
- Real-time Updates: Implement WebSocket connections
- File Upload: Allow document uploads for analysis
- Multiple AI Models: Support GPT-4, Claude, etc.
- Conversation Memory: Maintain chat context across messages
- Export Conversations: Download chat history as PDF/text
- Frontend: Vercel, Netlify, AWS S3 + CloudFront
- Backend: Railway, Render, DigitalOcean, AWS EC2
- Database: PostgreSQL on Railway/Render, AWS RDS
- Monitoring: Sentry for error tracking, LogRocket for user sessions
- Testing: Pytest for backend, Jest for frontend
- CI/CD: GitHub Actions for automated deployment
- Docker: Containerize the application
- Monitoring: Application performance monitoring with DataDog/New Relic
- Security: Input validation, rate limiting, API key rotation
- Caching: Redis for response caching to reduce API costs
Happy Coding! 🚀
This tutorial provides a complete foundation for building modern web applications with AI integration. Start with the basics and gradually explore the advanced topics as you become more comfortable with the technologies.