INIT V0.9
This commit is contained in:
parent
d54f2ab498
commit
7f6da3926e
13 changed files with 1724 additions and 1 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
.vscode
|
||||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
Copyright (c) 2024 Tidoni
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
|
|||
46
docker-compose.yaml
Normal file
46
docker-compose.yaml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
################################################################
|
||||
#
|
||||
# Development:
|
||||
# nodemon.cmd --ext '*' --exec docker-compose up app database --build
|
||||
#
|
||||
# docker exec tti-provider-db sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /tmp/all-databases.sql
|
||||
# docker exec tti-provider-db sh -c 'exec mysqldump tti_db tti_tasks -uroot -p"$MYSQL_ROOT_PASSWORD"' > /tmp/tti_db-tti_tasks-database.sql
|
||||
#
|
||||
################################################################
|
||||
|
||||
networks:
|
||||
tti-provider-network:
|
||||
name: tti-provider-network
|
||||
|
||||
services:
|
||||
app:
|
||||
build: ./tti-provider
|
||||
container_name: tti-provider-app
|
||||
restart: always
|
||||
networks:
|
||||
- tti-provider-network
|
||||
command: >
|
||||
sh -c "
|
||||
./init.sh
|
||||
"
|
||||
ports:
|
||||
- 8889:8080
|
||||
environment:
|
||||
MYSQL_HOST: tti-provider-db
|
||||
MYSQL_USER: user
|
||||
MYSQL_PASSWORD: NGQ2ODk3NDc0YzRmOTcyOGRlZDg0N2M0
|
||||
MYSQL_DATABASE: tti_db
|
||||
database:
|
||||
build: ./tti-db
|
||||
container_name: tti-provider-db
|
||||
restart: always
|
||||
networks:
|
||||
- tti-provider-network
|
||||
ports:
|
||||
- "3308:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_USER: root
|
||||
MYSQL_ROOT_PASSWORD: MWVmNzZlOGRhOTQzZWI1MTBiMzhhZjU1
|
||||
MYSQL_DATABASE: tti_db
|
||||
MYSQL_USER: user
|
||||
MYSQL_PASSWORD: NGQ2ODk3NDc0YzRmOTcyOGRlZDg0N2M0
|
||||
3
tti-db/Dockerfile
Normal file
3
tti-db/Dockerfile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
FROM mysql:5.7.15
|
||||
|
||||
ADD ./db-data/init.sql /docker-entrypoint-initdb.d
|
||||
69
tti-db/db-data/init.sql
Normal file
69
tti-db/db-data/init.sql
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
DROP TABLE IF EXISTS `tti_tasks`;
|
||||
|
||||
CREATE TABLE `tti_tasks` (
|
||||
`task_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`model` varchar(511) DEFAULT 'stabilityai/sdxl-turbo',
|
||||
`itterations` int(4) DEFAULT 1,
|
||||
`initial_prompt` varchar(4096) DEFAULT '',
|
||||
`negative_prompt` varchar(4096) DEFAULT '',
|
||||
`image_style` varchar(256) DEFAULT '',
|
||||
`image_dimensions` varchar(256) DEFAULT 'Square',
|
||||
`callback_url` varchar(511) DEFAULT '',
|
||||
`processing_started` tinyint(4) DEFAULT 0,
|
||||
`callback_send` tinyint(4) DEFAULT 0,
|
||||
`error_encountered` tinyint(4) DEFAULT 0,
|
||||
`download_url` varchar(255) DEFAULT '',
|
||||
`file_name` varchar(255) DEFAULT '',
|
||||
`pit_task_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`pit_processing_started` timestamp NULL DEFAULT NULL,
|
||||
`pit_processing_finished` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`task_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- INSERT INTO `tti_tasks` VALUES (1, 'stabilityai/sdxl-turbo', 1, ,'', 0, 0, 0, '', 'foobar', NULL, NULL, NULL, 'A cinematic shot of a baby racoon wearing an intricate italian priest robe.');
|
||||
|
||||
-- https://stokemctoke.com/every-fooocus-style-ultimate-comparison-resource/
|
||||
|
||||
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Sushi Banana', 'Image of a Banana besides a plate of Sushi', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Sushi Banana_2', 'Banana besides a plate of Sushi standing infront of a woman sitting at the bar', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'People Asian City', 'People walking through the rain in an asian city', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Woman on Rock', 'Woman standing on the edge of a cliff about to jump into the ocean.', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Nutty Professor', 'Nutty professor like Doc Brown from the motion picture "Back To The Future" drawing weired formula and complicated diagrams on a chalkboard, photorealistic.', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Cute Robot', 'Cute, happy robot easily juggling with data, formula and diagrams, photorealistic.', 'Cinematic');
|
||||
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Cute Robot', 'Cute, happy robot easily juggling with data, formula and diagrams, photorealistic.', 'Astral Aura');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Cute Robot', 'Cute, happy robot easily juggling with data, formula and diagrams, photorealistic.', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Cute Robot', 'Cute, happy robot easily juggling with data, formula and diagrams, photorealistic.', 'Colored Pencile Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Cute Robot', 'Cute, happy robot easily juggling with data, formula and diagrams, photorealistic.', 'Color Field Painting');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Cute Robot', 'Cute, happy robot easily juggling with data, formula and diagrams, photorealistic.', 'Conceptual Art');
|
||||
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Juggernaut Testing', 'ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner)), blue eyes, shaved side haircut, hyper detail, cinematic lighting, magic neon, dark red city, Canon EOS R3, nikon, f/1.4, ISO 200, 1/160s, 8K, RAW, unedited, symmetrical balance, in-frame, 8K', 'Cinematic');
|
||||
|
||||
|
||||
-- Style Demos
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Astral Aura', 'portrait of a beautiful woman looking at the viewer', 'Astral Aura');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Cinematic', 'portrait of a beautiful woman looking at the viewer', 'Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Colored Pencile Art', 'portrait of a beautiful woman looking at the viewer', 'Colored Pencile Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Color Field Painting', 'portrait of a beautiful woman looking at the viewer', 'Color Field Painting');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Conceptual Art', 'portrait of a beautiful woman looking at the viewer', 'Conceptual Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Constructivism Art', 'portrait of a beautiful woman looking at the viewer', 'Constructivism Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Cubism Art', 'portrait of a beautiful woman looking at the viewer', 'Cubism Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Dadaism Art', 'portrait of a beautiful woman looking at the viewer', 'Dadaism Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Dark Fantasy Art', 'portrait of a beautiful woman looking at the viewer', 'Dark Fantasy Art');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Dark Moody Atmosphere', 'portrait of a beautiful woman looking at the viewer', 'Dark Moody Atmosphere');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: DMT Art Style', 'portrait of a beautiful woman looking at the viewer', 'DMT Art Style');
|
||||
-- INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: ', 'portrait of a beautiful woman looking at the viewer', '');
|
||||
|
||||
|
||||
|
||||
-- Fooocus Styles
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Fooocus Cinematic', 'portrait of a beautiful woman looking at the viewer', 'Fooocus Cinematic');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Fooocus Enhance', 'portrait of a beautiful woman looking at the viewer', 'Fooocus Enhance');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Fooocus Masterpiece', 'portrait of a beautiful woman looking at the viewer', 'Fooocus Masterpiece');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Fooocus Negative', 'portrait of a beautiful woman looking at the viewer', 'Fooocus Negative');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Fooocus Photograph', 'portrait of a beautiful woman looking at the viewer', 'Fooocus Photograph');
|
||||
INSERT INTO `tti_tasks` (model, itterations, file_name, initial_prompt, image_style) VALUES ('stabilityai/sdxl-turbo', 1, 'Art Demo: Fooocus Sharp', 'portrait of a beautiful woman looking at the viewer', 'Fooocus Sharp');
|
||||
|
||||
|
||||
|
||||
42
tti-provider/Dockerfile
Normal file
42
tti-provider/Dockerfile
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
################################################################
|
||||
#
|
||||
# Project: TTI Provider
|
||||
#
|
||||
# docker build -t tti-provider .
|
||||
# docker run -it -p 8889:8080 -t tti-provider
|
||||
#
|
||||
################################################################
|
||||
|
||||
FROM python:3.11-slim
|
||||
|
||||
# set the working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy models folder
|
||||
# RUN mkdir /app/models
|
||||
# COPY ./models /app/models
|
||||
|
||||
# Create image folder
|
||||
RUN mkdir /app/images
|
||||
|
||||
# Update Packagelist
|
||||
RUN apt-get update
|
||||
|
||||
# install dependencies
|
||||
COPY ./requirements.txt /app
|
||||
RUN pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --no-cache-dir --upgrade -r requirements.txt
|
||||
|
||||
# Set up Cron
|
||||
RUN apt-get install -y cron
|
||||
COPY ./tasks.cron /etc/cron.d/downloader-crontab
|
||||
RUN chmod 0644 /etc/cron.d/downloader-crontab
|
||||
RUN crontab /etc/cron.d/downloader-crontab
|
||||
RUN touch /var/log/cron.log
|
||||
RUN touch /var/log/uvicorn.log
|
||||
|
||||
# copy scripts to folder
|
||||
COPY ./*.py /app
|
||||
COPY ./init.sh /app
|
||||
COPY ./styles.json /app
|
||||
|
||||
CMD ["bash", "init.sh"]
|
||||
0
tti-provider/images/.gitkeep
Normal file
0
tti-provider/images/.gitkeep
Normal file
11
tti-provider/init.sh
Normal file
11
tti-provider/init.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
env >> /etc/environment
|
||||
service cron start
|
||||
|
||||
# /usr/local/bin/python /app/runner.py
|
||||
|
||||
(cd /app/ && uvicorn main:app --workers 8 --host 0.0.0.0 --port 8080)
|
||||
tail -f /var/log/*.log
|
||||
|
||||
/bin/bash
|
||||
215
tti-provider/main.py
Normal file
215
tti-provider/main.py
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
import json
|
||||
import mysql.connector
|
||||
import os
|
||||
import traceback
|
||||
import datetime
|
||||
import logging
|
||||
import sys
|
||||
from datetime import datetime as dt
|
||||
|
||||
import validators
|
||||
|
||||
from fastapi import FastAPI, Response, Query, Request
|
||||
from fastapi.responses import FileResponse
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List
|
||||
|
||||
from starlette.staticfiles import StaticFiles
|
||||
|
||||
env_var_mysql_host = os.environ['MYSQL_HOST']
|
||||
env_var_mysql_user = os.environ['MYSQL_USER']
|
||||
env_var_mysql_password = os.environ['MYSQL_PASSWORD']
|
||||
env_var_mysql_database = os.environ['MYSQL_DATABASE']
|
||||
|
||||
# Setup Logging
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
# level=logging.INFO,
|
||||
format="%(asctime)s [%(levelname)s] %(message)s",
|
||||
handlers=[
|
||||
logging.FileHandler("/var/log/" + str(dt.today().strftime('%Y-%m-%d')) + "_-_cron.log"),
|
||||
logging.StreamHandler(sys.stdout)
|
||||
]
|
||||
)
|
||||
|
||||
app = FastAPI()
|
||||
app.mount("/images", StaticFiles(directory="/app/images", html=False), name="images")
|
||||
|
||||
# app.mount("/styles", StaticFiles(directory=shared_files_directory, html=False), name="images")
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def info() -> Response:
|
||||
web_content = '{"Info": {"Tool":"TTI-Provider", "Version":1.0, "Documentation": ["/redoc", "/docs"]} }'
|
||||
headers = {"Content-Type": "application/json", "Content-Language": "en-US"}
|
||||
return Response(content=web_content, headers=headers)
|
||||
|
||||
|
||||
@app.get("/styles")
|
||||
async def image_styles():
|
||||
return FileResponse("/app/styles.json")
|
||||
|
||||
|
||||
class Generate(BaseModel):
|
||||
initial_prompt: str = Field(examples=["A cinematic shot of a baby racoon wearing an intricate italian priest robe."])
|
||||
model: Optional[str] = Field("stablediffusionapi/juggernaut-xl-v8", examples=["stabilityai/sdxl-turbo", "stablediffusionapi/juggernaut-xl-v8"])
|
||||
callback: Optional[str] = Field("", examples=["https://<your-callback-server>/PLACEBO"])
|
||||
itterations: Optional[int] = Field(1, examples=[1, 2, 3])
|
||||
file_name: Optional[str] = "No name given"
|
||||
negative_prompt: Optional[str] = ""
|
||||
# https://stokemctoke.com/every-fooocus-style-ultimate-comparison-resource/
|
||||
image_style: Optional[str] = Field("", examples=["Astral Aura, Cinematic, Colored Pencile Art, Color Field Painting, Conceptual Art, Constructivism Art, Cubism Art, Dadaism Art, Dark Fantasy Art"])
|
||||
image_dimensions: Optional[str] = Field("Square", examples=["Widescreen, Portrait, Square, Photo"])
|
||||
|
||||
|
||||
class GenerateResponse(BaseModel):
|
||||
status: int
|
||||
result: str
|
||||
task_id: Optional[int] = 0
|
||||
|
||||
|
||||
@app.post("/generate/", response_model=GenerateResponse)
|
||||
def generate(generate: Generate, request: Request):
|
||||
"""
|
||||
For a List of all available styles see: /styles
|
||||
"""
|
||||
try:
|
||||
mydb = mysql.connector.connect(
|
||||
host=env_var_mysql_host,
|
||||
user=env_var_mysql_user,
|
||||
password=env_var_mysql_password,
|
||||
database=env_var_mysql_database
|
||||
)
|
||||
cursor = mydb.cursor()
|
||||
|
||||
initial_prompt = generate.initial_prompt[:4090]
|
||||
|
||||
sql = "INSERT INTO tti_tasks (initial_prompt, file_name, model, callback_url, itterations, negative_prompt, image_style, image_dimensions) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
|
||||
val = (initial_prompt, generate.file_name, generate.model, generate.callback, generate.itterations, generate.negative_prompt, generate.image_style, generate.image_dimensions)
|
||||
cursor.execute(sql, val)
|
||||
mydb.commit()
|
||||
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
if validators.url(generate.callback):
|
||||
return GenerateResponse(status=200, result="Link added to queue. Result will be send to callback (\'" + generate.callback + "\')", task_id=cursor.lastrowid)
|
||||
else:
|
||||
return GenerateResponse(status=200, result="Link added to queue. Result will NOT be send to callback", task_id=cursor.lastrowid)
|
||||
except Exception as e:
|
||||
logging.warning(e)
|
||||
logging.warning(str(traceback.format_exc()))
|
||||
return GenerateResponse(status=500, result="Internal Error: Look at the logs")
|
||||
|
||||
|
||||
class TaskResponse(BaseModel):
|
||||
task_id: int
|
||||
file_name: str
|
||||
processing_started: int
|
||||
callback_send: int
|
||||
error_encountered: int
|
||||
|
||||
|
||||
@app.get("/list_tasks", response_model=List[TaskResponse])
|
||||
def list_tasks(
|
||||
show_all: str = Query("false", description="Show all entrys; Possible Values: true, false"),
|
||||
days: int = Query(0, description="Number of (last) days to be showen; Possible Values: (positive) integer")
|
||||
):
|
||||
try:
|
||||
mydb = mysql.connector.connect(
|
||||
host=env_var_mysql_host,
|
||||
user=env_var_mysql_user,
|
||||
password=env_var_mysql_password,
|
||||
database=env_var_mysql_database
|
||||
)
|
||||
|
||||
cursor = mydb.cursor(dictionary=True)
|
||||
if (show_all == "true"):
|
||||
cursor.execute("SELECT * FROM tti_tasks ORDER BY task_id DESC;")
|
||||
elif (isinstance(days, int) and days != 0):
|
||||
cursor.execute("SELECT * FROM tti_tasks WHERE pit_task_added > NOW() - INTERVAL " + str(days) + " DAY ORDER BY task_id DESC;")
|
||||
else:
|
||||
cursor.execute("SELECT * FROM tti_tasks ORDER BY task_id DESC LIMIT 100;")
|
||||
|
||||
data = cursor.fetchall()
|
||||
json_data = []
|
||||
for row in data:
|
||||
data_row = {}
|
||||
data_row['task_id'] = row['task_id']
|
||||
data_row['file_name'] = row['file_name'] + " | " + row['image_style']
|
||||
data_row['processing_started'] = row['processing_started']
|
||||
data_row['callback_send'] = row['callback_send']
|
||||
data_row['error_encountered'] = row['error_encountered']
|
||||
json_data.append(data_row)
|
||||
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
headers = {"Content-Type": "application/json", "Content-Language": "en-US"}
|
||||
return Response(content=json.dumps(json_data), headers=headers)
|
||||
except Exception as e:
|
||||
logging.warning(e)
|
||||
logging.warning(str(traceback.format_exc()))
|
||||
|
||||
|
||||
class TaskDetailsResponse(BaseModel):
|
||||
task_id: int
|
||||
pit_task_added: datetime.datetime
|
||||
download_url: str
|
||||
callback_url: str
|
||||
file_name: str
|
||||
initial_prompt: str
|
||||
negative_prompt: str
|
||||
image_style: str
|
||||
image_dimensions: str
|
||||
processing_started: int
|
||||
pit_processing_started: datetime.datetime
|
||||
callback_send: int
|
||||
error_encountered: int
|
||||
pit_processing_finished: datetime.datetime
|
||||
|
||||
|
||||
@app.get("/task_details/{task_id}", response_model=TaskDetailsResponse)
|
||||
def task_details(task_id: int, request: Request) -> Response:
|
||||
try:
|
||||
mydb = mysql.connector.connect(
|
||||
host=env_var_mysql_host,
|
||||
user=env_var_mysql_user,
|
||||
password=env_var_mysql_password,
|
||||
database=env_var_mysql_database
|
||||
)
|
||||
cursor = mydb.cursor(dictionary=True)
|
||||
|
||||
sql = "SELECT * FROM tti_tasks WHERE task_id = '%s'"
|
||||
val = (task_id,)
|
||||
cursor.execute(sql, val)
|
||||
data = cursor.fetchone()
|
||||
|
||||
json_data = {
|
||||
"task_id": data['task_id'],
|
||||
"pit_task_added": data['pit_task_added'] if data['pit_task_added'] is None else dt.strptime(str(data['pit_task_added']), '%Y-%m-%d %H:%M:%S').isoformat(),
|
||||
"download_url": str(request.base_url) + data['download_url'].replace('/app/', ''),
|
||||
"callback_url": data['callback_url'],
|
||||
"file_name": data['file_name'],
|
||||
"initial_prompt": data['initial_prompt'],
|
||||
"negative_prompt": data['negative_prompt'],
|
||||
"image_style": data['image_style'],
|
||||
"image_dimensions": data['image_dimensions'],
|
||||
"processing_started": data['processing_started'],
|
||||
"pit_processing_started": data['pit_processing_started'] if data['pit_processing_started'] is None else dt.strptime(str(data['pit_processing_started']), '%Y-%m-%d %H:%M:%S').isoformat(),
|
||||
"callback_send": data['callback_send'],
|
||||
"error_encountered": data['error_encountered'],
|
||||
"pit_processing_finished": data['pit_processing_finished'] if data['pit_processing_finished'] is None else dt.strptime(str(data['pit_processing_finished']), '%Y-%m-%d %H:%M:%S').isoformat(),
|
||||
}
|
||||
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
headers = {"Content-Type": "application/json", "Content-Language": "en-US"}
|
||||
return Response(content=json.dumps(json_data, default=str), headers=headers)
|
||||
except Exception as e:
|
||||
logging.warning(e)
|
||||
logging.warning(str(traceback.format_exc()))
|
||||
web_content = '{"status": 500, "result": "Error: task_id not found"}'
|
||||
headers = {"Content-Type": "application/json", "Content-Language": "en-US"}
|
||||
return Response(content=web_content, headers=headers)
|
||||
9
tti-provider/requirements.txt
Normal file
9
tti-provider/requirements.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
mysql-connector-python
|
||||
fastapi
|
||||
uvicorn
|
||||
validators
|
||||
|
||||
diffusers
|
||||
# transformers
|
||||
# accelerate
|
||||
torch
|
||||
169
tti-provider/runner.py
Normal file
169
tti-provider/runner.py
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
import os
|
||||
import sys
|
||||
import uuid
|
||||
import json
|
||||
import logging
|
||||
import traceback
|
||||
import requests
|
||||
import mysql.connector
|
||||
from datetime import datetime as dt
|
||||
|
||||
import torch
|
||||
from diffusers import DiffusionPipeline
|
||||
|
||||
env_var_mysql_host = os.environ['MYSQL_HOST']
|
||||
env_var_mysql_user = os.environ['MYSQL_USER']
|
||||
env_var_mysql_password = os.environ['MYSQL_PASSWORD']
|
||||
env_var_mysql_database = os.environ['MYSQL_DATABASE']
|
||||
|
||||
|
||||
# Setup Logging
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
# level=logging.INFO,
|
||||
format="%(asctime)s [%(levelname)s] %(message)s",
|
||||
handlers=[
|
||||
logging.FileHandler("/var/log/" + str(dt.today().strftime('%Y-%m-%d')) + "_-_cron.log"),
|
||||
logging.StreamHandler(sys.stdout)
|
||||
]
|
||||
)
|
||||
|
||||
mydb = mysql.connector.connect(
|
||||
host=env_var_mysql_host,
|
||||
user=env_var_mysql_user,
|
||||
password=env_var_mysql_password,
|
||||
database=env_var_mysql_database
|
||||
)
|
||||
|
||||
cursor = mydb.cursor(dictionary=True)
|
||||
cursor.execute("SELECT * FROM tti_tasks;")
|
||||
|
||||
data = cursor.fetchall()
|
||||
json_data = []
|
||||
try:
|
||||
for row in data:
|
||||
if row['processing_started'] == 0:
|
||||
logging.info(row)
|
||||
|
||||
cursor = mydb.cursor()
|
||||
sql = "UPDATE tti_tasks SET processing_started = 1, pit_processing_started = CURRENT_TIMESTAMP WHERE task_id = '%s'"
|
||||
val = (row['task_id'],)
|
||||
cursor.execute(sql, val)
|
||||
mydb.commit()
|
||||
|
||||
prompt = row["initial_prompt"]
|
||||
neg_prompt = ""
|
||||
|
||||
with open('/app/styles.json') as f:
|
||||
for entry in json.load(f):
|
||||
if entry['style'] == row['image_style']:
|
||||
prompt += ", " + entry['prompt_extension']
|
||||
neg_prompt += "extra fingers, mutated hands, poorly drawn hands, poorly drawn face, deformed, ugly, blurry, bad anatomy, bad proportions, extra limbs, glitchy, double torso, extra arms, extra hands, mangled fingers, missing lips, ugly face, distorted face, extra legs"
|
||||
neg_prompt += entry['negative_prompt']
|
||||
|
||||
"""
|
||||
# Demo Image (for DEV)
|
||||
# Setting the size of the image
|
||||
size = (400, 300)
|
||||
# Creating a new image with RGB mode
|
||||
image = Image.new('RGB', size, color='white')
|
||||
"""
|
||||
|
||||
"""
|
||||
# Current working...
|
||||
pipe = DiffusionPipeline.from_pretrained("stablediffusionapi/juggernaut-xl-v8")
|
||||
pipe.to("cpu")
|
||||
|
||||
image = pipe(
|
||||
prompt=prompt,
|
||||
# generator=torch.Generator(device="cpu").manual_seed(31),
|
||||
negative_prompt=neg_prompt,
|
||||
).images[0]
|
||||
"""
|
||||
|
||||
base = DiffusionPipeline.from_pretrained(
|
||||
"stablediffusionapi/juggernaut-xl-v8"
|
||||
).to("cpu")
|
||||
refiner = DiffusionPipeline.from_pretrained(
|
||||
"stablediffusionapi/juggernaut-xl-v8",
|
||||
text_encoder_2=base.text_encoder_2,
|
||||
vae=base.vae,
|
||||
).to("cpu")
|
||||
|
||||
image = base(
|
||||
prompt=prompt,
|
||||
generator=torch.Generator(device="cpu").manual_seed(31),
|
||||
negative_prompt=neg_prompt,
|
||||
num_inference_steps=40,
|
||||
denoising_end=0.8,
|
||||
output_type="latent",
|
||||
).images
|
||||
image = refiner(
|
||||
prompt=prompt,
|
||||
generator=torch.Generator(device="cpu").manual_seed(31),
|
||||
negative_prompt=neg_prompt,
|
||||
num_inference_steps=40,
|
||||
denoising_start=0.8,
|
||||
image=image,
|
||||
).images[0]
|
||||
image
|
||||
|
||||
# Resulution Widescreen: 1344 x 768
|
||||
# Portrait: 915 x 1144
|
||||
# Square: 1024 x 1024
|
||||
# Photo (4x3): 1182 x 886
|
||||
|
||||
"""
|
||||
pipe = StableDiffusionXLPipeline.from_pretrained(
|
||||
"stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16
|
||||
)
|
||||
|
||||
pipe = pipe.to("cpu")
|
||||
|
||||
prompt = "a photo of an astronaut riding a horse on mars"
|
||||
|
||||
image = pipe(prompt).images[0]
|
||||
# prompt = "A cinematic shot of a baby racoon wearing an intricate italian priest robe."
|
||||
|
||||
# image = pipe(prompt=row['initial_prompt'], num_inference_steps=1, guidance_scale=0.0).images[0]
|
||||
"""
|
||||
|
||||
img_uuid = str(uuid.uuid4())
|
||||
file_name = 'images/' + img_uuid + '.png'
|
||||
# logging.debug(file_name)
|
||||
image.save(file_name)
|
||||
|
||||
cursor = mydb.cursor()
|
||||
sql = "UPDATE tti_tasks SET download_url = %s WHERE task_id = %s;"
|
||||
val = (file_name, str(row['task_id']))
|
||||
cursor.execute(sql, val)
|
||||
mydb.commit()
|
||||
|
||||
if row['callback_url'] != "":
|
||||
myobj = {'download_url': file_name}
|
||||
logging.info("Sending to Callback-URL: " + str(myobj))
|
||||
x = requests.post(row['callback_url'], json=myobj, verify=False)
|
||||
logging.info(x.text)
|
||||
|
||||
cursor = mydb.cursor()
|
||||
sql = "UPDATE tti_tasks SET callback_send = 1, pit_processing_finished = CURRENT_TIMESTAMP WHERE task_id = '%s';"
|
||||
val = (row['task_id'],)
|
||||
cursor.execute(sql, val)
|
||||
mydb.commit()
|
||||
|
||||
elif row['callback_send'] == 0:
|
||||
logging.debug("A Task is already running...")
|
||||
exit(0)
|
||||
except Exception as e:
|
||||
logging.debug("There was an error: " + str(e))
|
||||
logging.debug("Stacktrace: " + str(traceback.format_exc()))
|
||||
|
||||
cursor = mydb.cursor()
|
||||
sql = "UPDATE tti_tasks SET callback_send = 1, error_encountered = 1, pit_processing_finished = CURRENT_TIMESTAMP WHERE task_id = '%s';"
|
||||
val = (row['task_id'],)
|
||||
cursor.execute(sql, val)
|
||||
mydb.commit()
|
||||
|
||||
finally:
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
1142
tti-provider/styles.json
Normal file
1142
tti-provider/styles.json
Normal file
File diff suppressed because it is too large
Load diff
16
tti-provider/tasks.cron
Normal file
16
tti-provider/tasks.cron
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
# must be ended with a new line "LF" (Unix) and not "CRLF" (Windows)
|
||||
* * * * * echo "Cronjob running..." >> /var/log/cron.log 2>&1
|
||||
|
||||
# runner.py to transcribe the text and send it to the callback_url
|
||||
* * * * * /usr/local/bin/python /app/runner.py >> /var/log/cron.log 2>&1
|
||||
# * * * * * bash -l -c '/usr/local/bin/python /app/runner.py >> /var/log/cron.log 2>&1'
|
||||
# An empty line is required at the end of this file for a valid cron file.
|
||||
|
||||
# Log cleanup
|
||||
1 0 * * * mv /var/log/cron.log /var/log/$(date -d "yesterday 13:00" -I)_cron.log
|
||||
3 1 * * * find /var/log/*_cron.log -type f -mtime +7 -delete
|
||||
|
||||
1 0 * * * mv /var/log/uvicorn.log /var/log/$(date -d "yesterday 13:00" -I)_uvicorn.log
|
||||
3 1 * * * find /var/log/*_uvicorn.log -type f -mtime +7 -delete
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue