STABLE_DIFFUSION/server.py
Python source for AI models in Docker containers, 97 lines. Raw file
from diffusers import StableDiffusionPipeline
import PIL.Image
import asyncio
import websockets
import json
import base64
import torch
import io
model = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
next_job_id = 1
class Messenger:
def __init__(self, websocket):
self.websocket = websocket
async def progress(self, progress):
payload = {
"progress": progress
}
payload_serialized = json.dumps(payload)
await self.websocket.send(payload_serialized)
async def success(self, result):
payload = {
"type": "image",
"success": result
}
payload_serialized = json.dumps(payload)
await self.websocket.send(payload_serialized)
await self.websocket.close()
async def error(self, error):
payload = {
"error": error
}
payload_serialized = json.dumps(payload)
await self.websocket.send(payload_serialized)
await self.websocket.close()
def to_base64(image: PIL.Image.Image) -> str:
with io.BytesIO() as output:
image.save(output, format='PNG')
contents = output.getvalue()
img_str = base64.b64encode(contents).decode()
return f"data:image/png;base64,{img_str}"
# Websocket handler function, this is executed everytime new user connects
async def handler(websocket):
message = await websocket.recv()
message_data = json.loads(message)
messenger = Messenger(websocket)
if message_data.get("started"):
global next_job_id, model
current_job_id: int = next_job_id
next_job_id += 1
print(f"Started worker with job id: {current_job_id}")
await messenger.progress(0)
# Get the prompt, and model from the message
prompt: str = message_data.get("prompt")
settings = message_data.get("settings")
await messenger.progress(25)
pipe = model.to(settings["device"])
await messenger.progress(50)
generated_images_arr: list = pipe(prompt).images
encoded_images_arr: list = [to_base64(img) for _, img in enumerate(generated_images_arr)]
print(f"Sequence complete for job id: {current_job_id}")
await messenger.progress(100)
# Send the result back to the client
await messenger.success(encoded_images_arr)
if __name__ == "__main__":
start_server = websockets.serve(handler, "0.0.0.0", 1337)
asyncio.get_event_loop().run_until_complete(start_server)
print("Server started...")
try:
asyncio.get_event_loop().run_forever()
except KeyboardInterrupt:
print("Keyboard Interrupt: Exiting server")
except:
print("Unknown error")
finally:
exit(1)