|
import os |
|
import base64 |
|
import json |
|
from flask import Flask, render_template, request, jsonify |
|
from flask_cors import CORS |
|
import requests |
|
from werkzeug.utils import secure_filename |
|
import tempfile |
|
|
|
app = Flask(__name__) |
|
CORS(app) |
|
|
|
|
|
app.config['MAX_CONTENT_LENGTH'] = 25 * 1024 * 1024 |
|
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'webp'} |
|
|
|
|
|
OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY') |
|
API_BASE_URL = os.environ.get('API_BASE_URL', 'https://api.openai.com/v1') |
|
|
|
def allowed_file(filename): |
|
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS |
|
|
|
@app.route('/') |
|
def index(): |
|
return render_template('index.html') |
|
|
|
@app.route('/generate', methods=['POST']) |
|
def generate_image(): |
|
try: |
|
data = request.json |
|
prompt = data.get('prompt', '') |
|
|
|
if not prompt: |
|
return jsonify({'error': 'Prompt is required'}), 400 |
|
|
|
headers = { |
|
'Content-Type': 'application/json', |
|
'Authorization': f'Bearer {OPENAI_API_KEY}' |
|
} |
|
|
|
payload = { |
|
'model': 'dall-e-3', |
|
'prompt': prompt, |
|
'n': 1, |
|
'size': data.get('size', '1024x1024'), |
|
'quality': data.get('quality', 'standard'), |
|
'style': data.get('style', 'vivid') |
|
} |
|
|
|
response = requests.post( |
|
f'{API_BASE_URL}/images/generations', |
|
headers=headers, |
|
json=payload |
|
) |
|
|
|
if response.status_code == 200: |
|
result = response.json() |
|
|
|
image_url = result['data'][0]['url'] |
|
|
|
|
|
image_response = requests.get(image_url) |
|
if image_response.status_code == 200: |
|
image_base64 = base64.b64encode(image_response.content).decode('utf-8') |
|
return jsonify({ |
|
'success': True, |
|
'image': f'data:image/png;base64,{image_base64}', |
|
'usage': result.get('usage', {}) |
|
}) |
|
else: |
|
return jsonify({'error': 'Failed to download generated image'}), 500 |
|
else: |
|
return jsonify({'error': response.json()}), response.status_code |
|
|
|
except Exception as e: |
|
return jsonify({'error': str(e)}), 500 |
|
|
|
@app.route('/edit', methods=['POST']) |
|
def edit_image(): |
|
try: |
|
|
|
if 'image' not in request.files: |
|
return jsonify({'error': 'No image provided'}), 400 |
|
|
|
image_file = request.files['image'] |
|
prompt = request.form.get('prompt', '') |
|
|
|
if not prompt: |
|
return jsonify({'error': 'Prompt is required'}), 400 |
|
|
|
if not image_file or image_file.filename == '': |
|
return jsonify({'error': 'Image is required'}), 400 |
|
|
|
if not allowed_file(image_file.filename): |
|
return jsonify({'error': 'Invalid image format'}), 400 |
|
|
|
|
|
headers = { |
|
'Authorization': f'Bearer {OPENAI_API_KEY}' |
|
} |
|
|
|
|
|
image_content = image_file.read() |
|
|
|
|
|
files = { |
|
'model': (None, 'dall-e-2'), |
|
'prompt': (None, prompt), |
|
'n': (None, '1'), |
|
'size': (None, request.form.get('size', '1024x1024')), |
|
'image': (image_file.filename, image_content, image_file.content_type) |
|
} |
|
|
|
|
|
if 'mask' in request.files: |
|
mask_file = request.files['mask'] |
|
if mask_file and mask_file.filename != '': |
|
mask_content = mask_file.read() |
|
files['mask'] = (mask_file.filename, mask_content, mask_file.content_type) |
|
|
|
response = requests.post( |
|
f'{API_BASE_URL}/images/edits', |
|
headers=headers, |
|
files=files |
|
) |
|
|
|
if response.status_code == 200: |
|
result = response.json() |
|
|
|
|
|
if 'b64_json' in result['data'][0]: |
|
image_data = f'data:image/png;base64,{result["data"][0]["b64_json"]}' |
|
else: |
|
|
|
image_url = result['data'][0]['url'] |
|
image_response = requests.get(image_url) |
|
if image_response.status_code == 200: |
|
image_base64 = base64.b64encode(image_response.content).decode('utf-8') |
|
image_data = f'data:image/png;base64,{image_base64}' |
|
else: |
|
return jsonify({'error': 'Failed to download generated image'}), 500 |
|
|
|
return jsonify({ |
|
'success': True, |
|
'image': image_data, |
|
'usage': result.get('usage', {}) |
|
}) |
|
else: |
|
error_msg = 'Request failed' |
|
try: |
|
error_data = response.json() |
|
error_msg = error_data.get('error', {}).get('message', error_msg) |
|
except: |
|
error_msg = response.text |
|
return jsonify({'error': error_msg}), response.status_code |
|
|
|
except Exception as e: |
|
return jsonify({'error': str(e)}), 500 |
|
|
|
if __name__ == '__main__': |
|
if not OPENAI_API_KEY: |
|
print("Warning: OPENAI_API_KEY environment variable not set!") |
|
app.run(host='0.0.0.0', port=7860, debug=True) |