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

  1. Code Analysis: Integrate with tools like SonarQube for code quality
  2. Version Control: Save generated code snippets to a database
  3. Collaboration: Share code snippets with team members
  4. Custom Models: Fine-tune models for specific domains
  5. 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:

STAY IN TOUCH

Get notified when I publish something new, and unsubscribe at any time.