AI-generated Dynamic Website Builder Python, React, AI
👤 Sharing: AI
```python
# --- Backend (Python/Flask - ai_backend.py) ---
import os
import json
from flask import Flask, request, jsonify
from flask_cors import CORS # Import CORS
import openai
app = Flask(__name__)
CORS(app) # Enable CORS for all routes. This is essential for React to talk to the Flask server.
# Replace with your actual OpenAI API key. Store this in an environment variable for security!
openai.api_key = os.environ.get("OPENAI_API_KEY")
if not openai.api_key:
print("WARNING: OpenAI API key not found. Please set the OPENAI_API_KEY environment variable.")
# You might want to exit the program or disable AI features if the API key is missing.
@app.route('/generate_code', methods=['POST'])
def generate_code():
"""
Generates React code based on a user's website description using OpenAI's GPT-3.5/4.
The request should contain a JSON payload with a 'description' field.
Returns the generated React code as a JSON response. If there is an error with the openai API,
returns an error message instead.
"""
try:
data = request.get_json()
description = data.get('description')
if not description:
return jsonify({'error': 'Description is required'}), 400
# Construct the prompt for OpenAI. Be specific!
prompt = f"""
You are an expert React code generator. A user will describe a website to you,
and you will return the complete React code (JSX) for that website, along with
any necessary CSS. The code should be functional and well-formatted. Only include the necessary CSS.
Use functional components and modern React best practices. Assume react and react-dom are installed.
Do not include any introduction or explanation before or after the code.
Focus on delivering valid, runnable code immediately.
Website Description: {description}
React Code:
"""
# Call OpenAI API
response = openai.Completion.create(
engine="gpt-3.5-turbo-instruct", # Or use "gpt-4" for potentially better results (more expensive)
prompt=prompt,
max_tokens=1000, # Adjust this based on the complexity of the expected code
n=1, # Number of code snippets to generate. Let's just generate one for now.
stop=None, # Stop generating code if you find this phrase
temperature=0.5, # Controls randomness. Lower values (e.g., 0.2) result in more predictable output. Higher values (e.g., 0.7) result in more creative output.
)
code = response.choices[0].text.strip()
# Return the generated code
return jsonify({'code': code})
except Exception as e:
print(f"Error generating code: {e}") # Log the error for debugging
return jsonify({'error': str(e)}), 500 # Return an error message with a 500 status code
if __name__ == '__main__':
app.run(debug=True, port=5000) # Enable debug mode for easier development
# WARNING: Do NOT use debug mode in production!
# --- Frontend (React - src/App.js) ---
# (Create React app using create-react-app: npx create-react-app my-website-builder)
# Install axios for making HTTP requests: npm install axios
```javascript
import React, { useState } from 'react';
import axios from 'axios';
import './App.css'; // Import the CSS file
function App() {
const [description, setDescription] = useState('');
const [code, setCode] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
setError(''); // Clear any previous errors
setCode('');
setLoading(true);
try {
const response = await axios.post('http://localhost:5000/generate_code', { description }); // Replace with your Flask server's URL
setCode(response.data.code);
} catch (error) {
console.error('Error generating code:', error);
setError(error.message || 'An error occurred while generating code.'); // Use error.message if it exists.
if (error.response && error.response.data && error.response.data.error) {
setError(error.response.data.error); //Prefer error from server if available
}
} finally {
setLoading(false);
}
};
return (
<div className="App">
<h1>AI Website Builder</h1>
<form onSubmit={handleSubmit}>
<label htmlFor="description">Enter website description:</label>
<textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<button type="submit" disabled={loading}>
{loading ? 'Generating...' : 'Generate Code'}
</button>
</form>
{error && <div className="error">Error: {error}</div>}
{code && (
<div className="code-output">
<h2>Generated Code:</h2>
<pre>
<code>{code}</code>
</pre>
</div>
)}
</div>
);
}
export default App;
```
```css
/* src/App.css */
.App {
font-family: sans-serif;
text-align: center;
padding: 20px;
}
h1 {
margin-bottom: 20px;
}
form {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
}
label {
margin-bottom: 10px;
font-weight: bold;
}
textarea {
width: 500px; /* Adjusted for better readability */
height: 150px;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
resize: vertical;
}
button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.error {
color: red;
margin-bottom: 10px;
}
.code-output {
margin-top: 20px;
text-align: left;
}
.code-output h2 {
margin-bottom: 10px;
}
.code-output pre {
background-color: #f0f0f0;
padding: 10px;
border-radius: 5px;
overflow-x: auto; /* Add horizontal scroll for long lines */
}
.code-output code {
font-family: monospace;
white-space: pre; /* Preserve whitespace */
display: block; /* Prevent line breaks */
}
```
**Explanation:**
1. **Backend (Python/Flask): `ai_backend.py`**
* **Imports:** Imports necessary libraries like `Flask` for creating the web server, `request` for handling incoming requests, `jsonify` for creating JSON responses, `CORS` to handle cross-origin requests, `os` for environment variables, `json` for working with JSON data, and `openai` to interact with the OpenAI API.
* **Flask App Initialization:** Creates a Flask application instance.
* **CORS Setup:** `CORS(app)` enables Cross-Origin Resource Sharing (CORS). This is *crucial* because your React frontend (running on `localhost:3000` by default) will be making requests to your Flask backend (running on `localhost:5000`). Without CORS, the browser will block these requests due to security restrictions.
* **OpenAI API Key:** Retrieves the OpenAI API key from an environment variable (`OPENAI_API_KEY`). **Important:** Never hardcode your API key directly into your code. Environment variables are a much more secure way to manage sensitive information. You'll need to set this environment variable before running the script (e.g., `export OPENAI_API_KEY="YOUR_API_KEY"`). The code checks for the API key and prints a warning if it's missing.
* **`generate_code` Route:**
* This is the core route that handles the AI code generation. It's decorated with `@app.route('/generate_code', methods=['POST'])`, which means it listens for POST requests to the `/generate_code` endpoint.
* **Request Handling:** It retrieves the JSON payload from the request using `request.get_json()`. It then extracts the `description` from the JSON data. If the description is missing, it returns an error response with a 400 status code (Bad Request).
* **OpenAI Prompt Construction:** This is where the magic happens. A `prompt` string is created. This prompt is carefully crafted to instruct the OpenAI model to generate React code based on the user's description. The prompt is *very important*. The better the prompt, the better the generated code. The prompt should be clear, specific, and tell the model exactly what you want (e.g., the format of the output, the technologies to use, any specific requirements). I added instructions about using functional components, modern React practices, and assumptions about installed dependencies. I also added explicit negative constraints - do NOT include introduction text.
* **OpenAI API Call:** The `openai.Completion.create()` method is called to send the prompt to the OpenAI API. Key parameters:
* `engine`: Specifies the OpenAI model to use (e.g., `"gpt-3.5-turbo-instruct"` or `"gpt-4"`). GPT-4 is more powerful, but also more expensive.
* `prompt`: The prompt we constructed.
* `max_tokens`: The maximum number of tokens (words/subwords) in the generated response. Adjust this based on the expected complexity of the code.
* `n`: The number of code snippets to generate. We only want one for this example.
* `stop`: This could be used to tell the model when to stop generating text (e.g., a specific delimiter). We set it to `None` here.
* `temperature`: Controls the randomness of the generated text. Lower values (e.g., 0.2) make the output more predictable.
* **Code Extraction:** The generated code is extracted from the OpenAI API response using `response.choices[0].text.strip()`.
* **Response:** The generated code is returned as a JSON response using `jsonify({'code': code})`.
* **Error Handling:** A `try...except` block is used to catch any exceptions that might occur during the process (e.g., network errors, OpenAI API errors). If an error occurs, it's logged to the console, and an error message is returned as a JSON response with a 500 status code (Internal Server Error).
* **Running the App:** The `app.run(debug=True, port=5000)` line starts the Flask development server. `debug=True` enables debug mode, which is helpful during development because it provides more detailed error messages and automatically reloads the server when you make changes to the code. **Important:** Do not use `debug=True` in a production environment.
2. **Frontend (React): `src/App.js`**
* **Imports:** Imports necessary React hooks (`useState`) and the `axios` library for making HTTP requests. Also imports the CSS file for styling.
* **State Variables:**
* `description`: Stores the user's website description.
* `code`: Stores the generated React code.
* `error`: Stores any error messages.
* `loading`: A boolean flag to indicate whether the code generation is in progress (used to disable the button and show a loading message).
* **`handleSubmit` Function:**
* This function is called when the user submits the form.
* It prevents the default form submission behavior using `event.preventDefault()`.
* It clears any previous errors and resets the code.
* It sets the `loading` state to `true` to indicate that the code generation is in progress.
* **API Call:** It uses `axios.post()` to send a POST request to the Flask backend at `http://localhost:5000/generate_code`. The request body includes the user's description.
* **Response Handling:**
* If the API call is successful, it extracts the generated code from the response (`response.data.code`) and sets the `code` state.
* If the API call fails, it catches the error, logs it to the console, and sets the `error` state. It also checks `error.response.data.error` and prefers to use the error message from the backend if it's available (more informative).
* **Finally Block:** The `finally` block ensures that the `loading` state is set back to `false` regardless of whether the API call was successful or not.
* **JSX (Rendering):**
* The `return` statement renders the UI.
* It displays a heading, a form with a textarea for the website description, and a button to trigger the code generation.
* The button is disabled when `loading` is true.
* An error message is displayed if the `error` state is not empty.
* The generated code is displayed in a `<pre>` block (to preserve formatting) and a `<code>` block (for syntax highlighting).
* **CSS:** The CSS in `src/App.css` provides basic styling for the components. Crucially, `overflow-x: auto` is added to the `pre` tag to handle long lines of code by providing a horizontal scrollbar.
3. **CSS (`src/App.css`)**
* Provides basic styling for the React app.
**How to Run the Code:**
1. **Set up Python environment:**
* Make sure you have Python installed (3.7 or higher).
* Create a virtual environment (recommended):
```bash
python -m venv venv
source venv/bin/activate # On Linux/macOS
venv\Scripts\activate # On Windows
```
* Install the required Python packages:
```bash
pip install flask flask-cors openai python-dotenv
```
2. **Set the OpenAI API key:**
* Set the `OPENAI_API_KEY` environment variable:
```bash
export OPENAI_API_KEY="YOUR_API_KEY" # Linux/macOS
set OPENAI_API_KEY="YOUR_API_KEY" # Windows
```
(Replace `"YOUR_API_KEY"` with your actual OpenAI API key)
3. **Run the Flask backend:**
```bash
python ai_backend.py
```
4. **Set up the React frontend:**
* If you don't have Node.js and npm installed, download and install them from [https://nodejs.org/](https://nodejs.org/)
* Create a new React app (if you haven't already):
```bash
npx create-react-app my-website-builder
cd my-website-builder
```
* Install `axios`:
```bash
npm install axios
```
* Replace the contents of `src/App.js` with the code provided above.
* Replace the contents of `src/App.css` with the code provided above.
5. **Run the React frontend:**
```bash
npm start
```
6. **Open your browser:** Go to `http://localhost:3000` to see the React app.
**Important Considerations:**
* **OpenAI API Key Security:** Storing your OpenAI API key in an environment variable is crucial for security. Never commit your API key directly to your code repository.
* **Error Handling:** The code includes basic error handling, but you might want to add more robust error handling, especially on the frontend, to provide more informative error messages to the user.
* **Prompt Engineering:** The quality of the generated code heavily depends on the quality of the prompt. Experiment with different prompts to see what works best. Be specific about the desired output format, the technologies to use, and any specific constraints. Consider adding examples to the prompt.
* **Code Validation:** The generated code might not always be perfect. It's a good idea to have some mechanism for validating the generated code before displaying it to the user. You could use a linter or a code formatter to check for syntax errors and style issues.
* **Rate Limits:** The OpenAI API has rate limits. If you make too many requests in a short period of time, you might get an error. You can handle rate limits by implementing a retry mechanism with exponential backoff.
* **Cost:** The OpenAI API is not free. You will be charged based on the number of tokens you use. Be mindful of your usage and set up billing alerts to avoid unexpected charges. Consider using a less expensive model (like `gpt-3.5-turbo-instruct`) if it meets your needs.
* **Model Choice:** The choice of OpenAI model significantly affects the quality and cost. `gpt-4` is generally better than `gpt-3.5-turbo-instruct` but more expensive.
* **Security:** Be careful about executing code generated by AI. Always review the code and make sure it is safe before running it. Avoid using AI to generate code that will be executed in a privileged environment.
* **CSS generation:** This example doesn't specifically request a stylesheet from GPT, but it might provide CSS inline in the React code. You could expand this by adding a separate field in the JSON response for the CSS and adding logic to inject that into a `<style>` tag or a separate `.css` file in React.
* **Dependencies:** The prompt currently assumes that `react` and `react-dom` are installed. For a more robust solution, you might consider having the AI generate a `package.json` file with the necessary dependencies.
This example provides a basic framework for building an AI-powered website builder. You can extend this framework by adding more features, such as:
* A visual editor for designing the website layout.
* The ability to add custom components.
* The ability to deploy the generated website to a hosting provider.
* User authentication and authorization.
* More sophisticated prompt engineering to guide the AI model to generate more specific types of websites.
👁️ Viewed: 9
Comments