API-Handler commited on
Commit
6349504
·
verified ·
1 Parent(s): d148a6b

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +11 -0
  2. app.py +32 -0
  3. image_handler.py +86 -0
  4. requirements.txt +5 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ WORKDIR /code
4
+
5
+ COPY ./requirements.txt /code/requirements.txt
6
+
7
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
8
+
9
+ COPY . .
10
+
11
+ CMD ["flask", "run", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # server.py
2
+ from flask import Flask, request, jsonify
3
+ from image_handler import ImageHandler
4
+ import os
5
+
6
+ app = Flask(__name__)
7
+ image_handler = ImageHandler()
8
+
9
+ @app.route('/v2/images/generations', methods=['POST'])
10
+ def generate_images():
11
+ try:
12
+ # Verify authorization
13
+ auth_header = request.headers.get('Authorization')
14
+ if not auth_header or not auth_header.startswith('Bearer '):
15
+ return jsonify({"error": "Invalid authorization"}), 401
16
+
17
+ # Get request data
18
+ data = request.get_json()
19
+
20
+ # Validate required fields
21
+ if not data.get('prompt'):
22
+ return jsonify({"error": "prompt is required"}), 400
23
+
24
+ # Generate images
25
+ result = image_handler.generate_images(data)
26
+ return jsonify(result)
27
+
28
+ except Exception as e:
29
+ return jsonify({"error": str(e)}), 500
30
+
31
+ if __name__ == '__main__':
32
+ app.run(port=5000, debug=True)
image_handler.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # image_handler.py
2
+ import time
3
+ from typing import Dict, Any
4
+ from datetime import datetime
5
+ import requests
6
+ import base64
7
+ from requests.exceptions import RequestException
8
+ import tempfile
9
+ import os
10
+
11
+ class ImageHandler:
12
+ def __init__(self):
13
+ self.available_models = ["flux", "flux-realism", "flux-3d", "flux-pro",
14
+ "flux-anime", "flux-cablyai", "turbo", "flux-dark"]
15
+ self.base_url = "https://image.pollinations.ai/prompt/{prompt}"
16
+
17
+ def _get_size_dimensions(self, size: str) -> tuple:
18
+ size_map = {
19
+ "256x256": (256, 256),
20
+ "512x512": (512, 512),
21
+ "1024x1024": (1024, 1024),
22
+ "1792x1024": (1792, 1024),
23
+ "1024x1792": (1024, 1792)
24
+ }
25
+ return size_map.get(size, (768, 768))
26
+
27
+ def _save_temp_image(self, image_data: bytes) -> str:
28
+ """Save image to temporary file and return its URL."""
29
+ temp_dir = tempfile.gettempdir()
30
+ temp_file = os.path.join(temp_dir, f"image_{int(time.time())}.jpg")
31
+ with open(temp_file, 'wb') as f:
32
+ f.write(image_data)
33
+ return f"file://{temp_file}"
34
+
35
+ def generate_images(self, params: Dict[str, Any]) -> Dict[str, Any]:
36
+ prompt = params.get("prompt")
37
+ n = min(params.get("n", 1), 10)
38
+ size = params.get("size", "1024x1024")
39
+ model = params.get("model", "flux-pro")
40
+ if model not in self.available_models:
41
+ model = "flux-pro"
42
+ response_format = params.get("response_format", "b64_json")
43
+ if response_format != "b64_json":
44
+ response_format = "bs64_json"
45
+ width, height = self._get_size_dimensions(size)
46
+
47
+ headers = {
48
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
49
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0",
50
+ }
51
+
52
+ images = []
53
+ for _ in range(n):
54
+ try:
55
+ url = self.base_url.format(prompt=prompt)
56
+ url += f"?width={width}&height={height}&model={model}"
57
+
58
+ response = requests.get(url, headers=headers, timeout=60)
59
+ response.raise_for_status()
60
+
61
+ # Get the image data
62
+ image_data = response.content
63
+
64
+ if response_format == "b64_json":
65
+ # Convert to base64
66
+ image_b64 = base64.b64encode(image_data).decode('utf-8')
67
+ images.append({"b64_json": image_b64})
68
+ else:
69
+ # Two options for URL:
70
+ # 1. Save locally and return file URL (good for testing)
71
+ # 2. Return the pollinations URL (might expire)
72
+
73
+ # Option 1: Local file
74
+ temp_url = self._save_temp_image(image_data)
75
+ images.append({"url": temp_url})
76
+
77
+ # Option 2: Pollinations URL (uncomment if preferred)
78
+ # images.append({"url": url})
79
+
80
+ except RequestException as e:
81
+ raise Exception(f"Image generation failed: {str(e)}")
82
+
83
+ return {
84
+ "created": int(datetime.now().timestamp()),
85
+ "data": images
86
+ }
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi==0.110.2
2
+ Flask==3.0.3
3
+ python-dotenv==1.0.1
4
+ Requests==2.31.0
5
+ uvicorn==0.29.0