arevedudaa commited on
Commit
52bae2d
·
verified ·
1 Parent(s): f9933a5

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +18 -0
  2. main.py +115 -0
  3. requirements.txt +3 -0
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.9-slim
3
+
4
+ # Set the working directory in the container
5
+ WORKDIR /app
6
+
7
+ # Copy the requirements file and install dependencies
8
+ COPY requirements.txt .
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ # Copy the FastAPI application code into the container
12
+ COPY main.py .
13
+
14
+ # Expose port 80 for the app to be accessible externally
15
+ EXPOSE 7860
16
+
17
+ # Run the application with Uvicorn
18
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
main.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import requests
4
+ from fastapi import FastAPI, HTTPException, Form
5
+ from fastapi.responses import FileResponse
6
+
7
+ app = FastAPI()
8
+
9
+ def generate_image_and_download(prompt: str, id_image: str) -> str:
10
+ # Base API endpoint for image generation
11
+ base_url = "https://yanze-pulid-flux.hf.space/call/generate_image"
12
+
13
+ # JSON payload with 13 custom parameters
14
+ payload = {
15
+ "data": [
16
+ prompt, # Prompt text
17
+ {"path": id_image}, # ID image file
18
+ 0, # start_step
19
+ 4, # guidance
20
+ "-1", # seed ("-1" for random)
21
+ 1, # true_cfg
22
+ 896, # width
23
+ 1152, # height
24
+ 20, # num_steps
25
+ 1, # id_weight
26
+ "bad quality, worst quality, text, signature, watermark, extra limbs", # neg_prompt
27
+ 1, # timestep_to_start_cfg
28
+ 128 # max_sequence_length
29
+ ]
30
+ }
31
+ headers = {"Content-Type": "application/json"}
32
+
33
+ # Send the initial POST request
34
+ response = requests.post(base_url, json=payload, headers=headers)
35
+ if response.status_code != 200:
36
+ raise HTTPException(status_code=response.status_code, detail=f"Error in POST request: {response.text}")
37
+
38
+ # Extract event ID from the response (using splitting as in your shell command)
39
+ try:
40
+ event_id = response.text.split('"')[3]
41
+ except IndexError:
42
+ raise HTTPException(status_code=500, detail="Failed to extract event ID from response.")
43
+
44
+ # Poll the event endpoint to get the streaming response
45
+ poll_url = f"{base_url}/{event_id}"
46
+ complete_event_received = False
47
+ data_buffer = []
48
+
49
+ try:
50
+ with requests.get(poll_url, stream=True) as poll_response:
51
+ if poll_response.status_code != 200:
52
+ raise HTTPException(status_code=poll_response.status_code, detail=f"Error while polling event: {poll_response.text}")
53
+ for line in poll_response.iter_lines(decode_unicode=True):
54
+ if not line:
55
+ if complete_event_received and data_buffer:
56
+ break
57
+ data_buffer = []
58
+ continue
59
+
60
+ if line.startswith("event:"):
61
+ event_type = line[len("event:"):].strip()
62
+ if event_type == "complete":
63
+ complete_event_received = True
64
+ elif line.startswith("data:"):
65
+ data_line = line[len("data:"):].strip()
66
+ if complete_event_received:
67
+ data_buffer.append(data_line)
68
+ except Exception as e:
69
+ raise HTTPException(status_code=500, detail=f"Error while polling: {e}")
70
+
71
+ if not data_buffer:
72
+ raise HTTPException(status_code=500, detail="No complete event data received.")
73
+
74
+ complete_event_data = "\n".join(data_buffer)
75
+ try:
76
+ json_data = json.loads(complete_event_data)
77
+ except json.JSONDecodeError as e:
78
+ raise HTTPException(status_code=500, detail=f"JSON decode error: {e}")
79
+
80
+ # Extract the image path from the JSON response.
81
+ if isinstance(json_data, list) and len(json_data) > 0 and isinstance(json_data[0], dict) and "path" in json_data[0]:
82
+ image_path = json_data[0]["path"]
83
+ else:
84
+ raise HTTPException(status_code=500, detail="Could not extract image path from response JSON.")
85
+
86
+ # Construct the download URL
87
+ download_base_url = "https://yanze-pulid-flux.hf.space/file="
88
+ download_url = f"{download_base_url}{image_path}"
89
+
90
+ # Download the image file
91
+ try:
92
+ image_response = requests.get(download_url, stream=True)
93
+ if image_response.status_code == 200:
94
+ # Use the original filename from the image path
95
+ filename = image_path.split("/")[-1]
96
+ with open(filename, "wb") as f:
97
+ for chunk in image_response.iter_content(chunk_size=1024):
98
+ f.write(chunk)
99
+ return filename
100
+ else:
101
+ raise HTTPException(status_code=image_response.status_code, detail="Failed to download image.")
102
+ except Exception as e:
103
+ raise HTTPException(status_code=500, detail=f"Error downloading image: {e}")
104
+
105
+ @app.post("/generate")
106
+ async def generate(prompt: str = Form(...), id_image: str = Form(...)):
107
+ """
108
+ Expects form data with 'prompt' and 'id_image' keys.
109
+ When complete, returns the generated image file.
110
+ """
111
+ filename = generate_image_and_download(prompt, id_image)
112
+ if os.path.exists(filename):
113
+ return FileResponse(path=filename, filename=filename, media_type="application/octet-stream")
114
+ else:
115
+ raise HTTPException(status_code=500, detail="Image file not found after generation.")
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ requests