Building an AI-Powered Code Generator with OpenAI API: A Complete Guide
Introduction
AI-powered code generation has revolutionized how developers write code. Tools like GitHub Copilot have become essential for productivity, but what if you want to build your own custom code generator? In this comprehensive guide, we'll build a complete AI code generator using OpenAI API, FastAPI backend, and a React frontend.
🚀 Why build your own? Custom code generators can be tailored to your specific tech stack, coding standards, and project requirements.
What We'll Build
Our AI code generator will include:
- Backend API with FastAPI for handling OpenAI requests
- React Frontend with real-time code generation
- Code highlighting and syntax formatting
- Template system for different programming languages
- Error handling and rate limiting
Prerequisites
Before we start, ensure you have:
- OpenAI API key (get one at platform.openai.com)
- Python 3.8+ and Node.js 16+
- Basic knowledge of FastAPI and React
Step 1: Setting Up the FastAPI Backend
First, let's create our FastAPI backend with proper structure:
mkdir ai-code-generator
cd ai-code-generator
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install fastapi uvicorn openai python-multipart python-dotenv
Create the main FastAPI application:
# main.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import openai
import os
from dotenv import load_dotenv
load_dotenv()
app = FastAPI(title="AI Code Generator API")
# CORS middleware for frontend communication
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Configure OpenAI
openai.api_key = os.getenv("OPENAI_API_KEY")
class CodeRequest(BaseModel):
prompt: str
language: str = "python"
context: str = ""
@app.post("/generate-code")
async def generate_code(request: CodeRequest):
try:
# Create a comprehensive prompt for code generation
system_prompt = f"""You are an expert {request.language} developer.
Generate clean, well-documented code based on the user's request.
Always include comments explaining complex logic.
Follow best practices for {request.language}."""
user_prompt = f"""
Context: {request.context}
Request: {request.prompt}
Please generate {request.language} code that addresses this request.
"""
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
max_tokens=1000,
temperature=0.3
)
return {
"code": response.choices[0].message.content,
"usage": response.usage
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health_check():
return {"status": "healthy", "service": "AI Code Generator"}
Step 2: Creating the React Frontend
Now let's build a modern React frontend with real-time code generation:
npx create-react-app frontend --template typescript
cd frontend
npm install axios react-syntax-highlighter @types/react-syntax-highlighter
Create the main code generator component:
// src/components/CodeGenerator.tsx
import React, { useState } from 'react';
import axios from 'axios';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { tomorrow } from 'react-syntax-highlighter/dist/esm/styles/prism';
interface CodeResponse {
code: string;
usage: {
total_tokens: number;
prompt_tokens: number;
completion_tokens: number;
};
}
const CodeGenerator: React.FC = () => {
const [prompt, setPrompt] = useState('');
const [language, setLanguage] = useState('python');
const [context, setContext] = useState('');
const [generatedCode, setGeneratedCode] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const languages = [
'python', 'javascript', 'typescript', 'java', 'cpp', 'csharp',
'go', 'rust', 'php', 'ruby', 'swift', 'kotlin'
];
const generateCode = async () => {
if (!prompt.trim()) {
setError('Please enter a prompt');
return;
}
setLoading(true);
setError('');
try {
const response = await axios.post<CodeResponse>('http://localhost:8000/generate-code', {
prompt,
language,
context
});
setGeneratedCode(response.data.code);
} catch (err) {
setError('Failed to generate code. Please try again.');
console.error(err);
} finally {
setLoading(false);
}
};
const copyToClipboard = () => {
navigator.clipboard.writeText(generatedCode);
};
return (
<div className="max-w-4xl mx-auto p-6">
<h1 className="text-3xl font-bold mb-8 text-center">
AI Code Generator
</h1>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Input Section */}
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">
Programming Language
</label>
<select
value={language}
onChange={(e) => setLanguage(e.target.value)}
className="w-full p-2 border rounded-md"
>
{languages.map(lang => (
<option key={lang} value={lang}>
{lang.charAt(0).toUpperCase() + lang.slice(1)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium mb-2">
Context (Optional)
</label>
<textarea
value={context}
onChange={(e) => setContext(e.target.value)}
placeholder="Provide additional context about your project..."
className="w-full p-2 border rounded-md h-20"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">
What code do you want to generate?
</label>
<textarea
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Describe the code you want to generate..."
className="w-full p-2 border rounded-md h-32"
/>
</div>
<button
onClick={generateCode}
disabled={loading}
className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 disabled:opacity-50"
>
{loading ? 'Generating...' : 'Generate Code'}
</button>
{error && (
<div className="text-red-600 text-sm">{error}</div>
)}
</div>
{/* Output Section */}
<div>
<div className="flex justify-between items-center mb-2">
<label className="block text-sm font-medium">
Generated Code
</label>
{generatedCode && (
<button
onClick={copyToClipboard}
className="text-sm bg-gray-200 px-2 py-1 rounded hover:bg-gray-300"
>
Copy
</button>
)}
</div>
<div className="border rounded-md overflow-hidden">
{generatedCode ? (
<SyntaxHighlighter
language={language}
style={tomorrow}
customStyle={{ margin: 0, minHeight: '400px' }}
>
{generatedCode}
</SyntaxHighlighter>
) : (
<div className="p-4 text-gray-500 text-center min-h-[400px] flex items-center justify-center">
Generated code will appear here...
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default CodeGenerator;
Step 3: Adding Advanced Features
Let's enhance our code generator with some advanced features:
Template System
# templates.py
CODE_TEMPLATES = {
"python": {
"function": "Create a Python function that {description}",
"class": "Create a Python class that {description}",
"api": "Create a FastAPI endpoint that {description}",
"test": "Create unit tests for {description}"
},
"javascript": {
"function": "Create a JavaScript function that {description}",
"class": "Create a JavaScript class that {description}",
"react": "Create a React component that {description}",
"api": "Create an Express.js endpoint that {description}"
}
}
def get_template_prompt(language: str, template_type: str, description: str) -> str:
if language in CODE_TEMPLATES and template_type in CODE_TEMPLATES[language]:
return CODE_TEMPLATES[language][template_type].format(description=description)
return description
Rate Limiting
# rate_limiter.py
from fastapi import HTTPException
import time
from collections import defaultdict
class RateLimiter:
def __init__(self, max_requests: int = 10, window_seconds: int = 60):
self.max_requests = max_requests
self.window_seconds = window_seconds
self.requests = defaultdict(list)
def is_allowed(self, client_id: str) -> bool:
now = time.time()
client_requests = self.requests[client_id]
# Remove old requests outside the window
client_requests[:] = [req_time for req_time in client_requests
if now - req_time < self.window_seconds]
if len(client_requests) >= self.max_requests:
return False
client_requests.append(now)
return True
rate_limiter = RateLimiter()
Step 4: Environment Configuration
Create a .env
file for your backend:
# .env
OPENAI_API_KEY=your_openai_api_key_here
MAX_TOKENS=1000
MODEL_NAME=gpt-3.5-turbo
RATE_LIMIT_REQUESTS=10
RATE_LIMIT_WINDOW=60
Step 5: Running the Application
Start the backend:
# Backend
uvicorn main:app --reload --port 8000
Start the frontend:
# Frontend
cd frontend
npm start
Advanced Features to Add
- Code Analysis: Integrate with tools like SonarQube for code quality
- Version Control: Save generated code snippets to a database
- Collaboration: Share code snippets with team members
- Custom Models: Fine-tune models for specific domains
- Code Review: AI-powered code review suggestions
Best Practices
- Prompt Engineering: Craft specific, detailed prompts for better results
- Error Handling: Implement comprehensive error handling for API failures
- Security: Validate and sanitize all user inputs
- Performance: Implement caching for frequently requested code patterns
- Monitoring: Track usage patterns and API costs
Cost Optimization
# cost_tracker.py
import openai
from datetime import datetime
class CostTracker:
def __init__(self):
self.costs = {
'gpt-3.5-turbo': {'input': 0.0015, 'output': 0.002}, # per 1K tokens
'gpt-4': {'input': 0.03, 'output': 0.06}
}
def calculate_cost(self, model: str, usage: dict) -> float:
if model not in self.costs:
return 0.0
input_cost = (usage['prompt_tokens'] / 1000) * self.costs[model]['input']
output_cost = (usage['completion_tokens'] / 1000) * self.costs[model]['output']
return input_cost + output_cost
Conclusion
You've now built a complete AI-powered code generator! This system provides:
- Customizable code generation for multiple languages
- Real-time feedback with syntax highlighting
- Rate limiting to control costs
- Extensible architecture for adding new features
The possibilities are endless - you can extend this to support:
- Database schema generation
- API documentation creation
- Test case generation
- Code refactoring suggestions
🚀 Next Steps: Consider integrating with your IDE, adding support for more AI models, or building a marketplace for custom code templates.
Resources:
Related Articles: