Spaces:
Runtime error
Runtime error
#!/usr/bin/env python | |
import os | |
import io | |
import time | |
import base64 | |
import logging | |
import argparse | |
import requests | |
import urllib3 | |
from PIL import Image | |
sd_url = os.environ.get('SDAPI_URL', "http://127.0.0.1:7860") | |
sd_username = os.environ.get('SDAPI_USR', None) | |
sd_password = os.environ.get('SDAPI_PWD', None) | |
logging.basicConfig(level = logging.INFO, format = '%(asctime)s %(levelname)s: %(message)s') | |
log = logging.getLogger(__name__) | |
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | |
options = { | |
"save_images": False, | |
"send_images": True, | |
} | |
def auth(): | |
if sd_username is not None and sd_password is not None: | |
return requests.auth.HTTPBasicAuth(sd_username, sd_password) | |
return None | |
def post(endpoint: str, dct: dict = None): | |
req = requests.post(f'{sd_url}{endpoint}', json = dct, timeout=300, verify=False, auth=auth()) | |
if req.status_code != 200: | |
return { 'error': req.status_code, 'reason': req.reason, 'url': req.url } | |
else: | |
return req.json() | |
def encode(f): | |
image = Image.open(f) | |
if image.mode == 'RGBA': | |
image = image.convert('RGB') | |
with io.BytesIO() as stream: | |
image.save(stream, 'JPEG') | |
image.close() | |
values = stream.getvalue() | |
encoded = base64.b64encode(values).decode() | |
return encoded | |
def generate(args): # pylint: disable=redefined-outer-name | |
t0 = time.time() | |
if args.model is not None: | |
post('/sdapi/v1/options', { 'sd_model_checkpoint': args.model }) | |
post('/sdapi/v1/reload-checkpoint') # needed if running in api-only to trigger new model load | |
options['prompt'] = args.prompt | |
options['negative_prompt'] = args.negative | |
options['steps'] = int(args.steps) | |
options['seed'] = int(args.seed) | |
options['sampler_name'] = args.sampler | |
options['init_images'] = [encode(args.init)] | |
image = Image.open(args.init) | |
options['width'] = image.width | |
options['height'] = image.height | |
image.close() | |
if args.mask is not None: | |
options['mask'] = encode(args.mask) | |
data = post('/sdapi/v1/img2img', options) | |
t1 = time.time() | |
if 'images' in data: | |
for i in range(len(data['images'])): | |
b64 = data['images'][i].split(',',1)[0] | |
info = data['info'] | |
image = Image.open(io.BytesIO(base64.b64decode(b64))) | |
log.info(f'received image: size={image.size} time={t1-t0:.2f} info="{info}"') | |
if args.output: | |
image.save(args.output) | |
log.info(f'image saved: size={image.size} filename={args.output}') | |
else: | |
log.warning(f'no images received: {data}') | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description = 'simple-img2img') | |
parser.add_argument('--init', required=True, help='init image') | |
parser.add_argument('--mask', required=False, help='mask image') | |
parser.add_argument('--prompt', required=False, default='', help='prompt text') | |
parser.add_argument('--negative', required=False, default='', help='negative prompt text') | |
parser.add_argument('--steps', required=False, default=20, help='number of steps') | |
parser.add_argument('--seed', required=False, default=-1, help='initial seed') | |
parser.add_argument('--sampler', required=False, default='Euler a', help='sampler name') | |
parser.add_argument('--output', required=False, default=None, help='output image file') | |
parser.add_argument('--model', required=False, help='model name') | |
args = parser.parse_args() | |
log.info(f'img2img: {args}') | |
generate(args) | |