# meta pic: https://static.whypodg.me/mods!stablediffusion.png # meta banner: https://mods.whypodg.me/badges/stablediffusion.jpg # meta developer: @idiotcoders # scope: hikka_only # scope: hikka_min 1.6.2 import json import re import requests import datetime from hikkatl.types import Message from .. import loader, utils @loader.tds class StableDiffusionMod(loader.Module): """Some mod for work with StableDiffusion. API KEY required!""" strings = { "name": "StableDiffusion", "_cfg_api_key": "Insert the StableDiffusionApi.com API Key", "_cfg_model": "Pass the AI model", "_cfg_bad_prompt": "Pass the bad prompt — is that what you don't want to see in the pic", "_cfg_debug": "Debug mode", "_cfg_samples": "Default quantity of images to generate", "_cfg_steps": "Steps — The higher the number, the more the image will be detailed", "_cfg_upscale": "Using upscale", "error": " Some error occured!\n\n{}", "key_required": "API Key required! Insert it in .cfg StableDiffusion", "done": " Image is generated!\n\n", "debug": "Model: {model}\nPrompt: {prompt}\n" \ "Bad prompt: {negative}\nSteps: {steps}, {upsc}" \ "upscaled using external AI{time}", "not": "not ", "drawing": "🎨 Image is drawing...", "help": "🥹 Help for StableDiffusion module\n\n\n" \ "1️⃣ Configuration:\nAll configuration in the config" \ " - .cfg StableDiffusion\n\n\n2️⃣ " \ "Parameters and their description:\n api_key is your personal access key to StableDiffusionAPI.com, " \ " you can get it here\n\n model is the model to be generated (in config specifies which " \ "models are available)\n\n bad_prompt - negative input. It is needed in order to remove from your " \ "images what you don't wanna see\n\n debug - if value is True, the response will contain" \ " information about the generated image(s) (model, prompt, bad_prompt, steps, etc.)\n samples — " \ "number of images generated\n\n steps are «steps» . the higher the number, the more detailed" \ " the image will be\n\n upscale - improved generation using AI\n\n\n3️⃣ Usage:\nLet's suppose that you have finished the setup. Let's move on to use.\n" \ "You need to use it like this: .sd <prompt>\nWhere <prompt> is whatever you wanna see on " \ "the image" } strings_ru = { "_cls_doc": "Какой-то модуль для работы с StableDiffusion. Нужен API KEY!", "_cfg_api_key": "Укажи свой API Key от StableDiffusionAPI.com", "_cfg_model": "Укажи модель", "_cfg_bad_prompt": "Укажи негативный ввод — то, что ты не хочешь видеть на изображении", "_cfg_debug": "Debug мод", "_cfg_samples": "Количество изображений по умолчанию для генерации", "_cfg_steps": "Шаги - чем выше число, тем больше детальнее будет изображение.", "_cfg_upscale": "Использование улучшения", "error": " Произошла ошибка!\n\n{}", "key_required": " Нужен API Key! Укажи его в .cfg StableDiffusion", "done": " Изображение сгенерировано!\n\n", "debug": "Модель: {model}\nВвод: {prompt}\n" \ "Негативный ввод: {negative}\nШаги: {steps}, {upsc}" \ "улучшено с использованием ИИ{time}", "not": "не было ", "drawing": "🎨 Рисую…", "help": "🥹 Помощь по модулю StableDiffusion\n\n\n" \ "1️⃣ Настройка.\nВся настройка проводится в конфиге — " \ ".cfg StableDiffusion\n\n\n2️⃣ Параметры и их описание" \ ":\n api_key — это ваш персональный ключ доступа к StableDiffusionAPI.com, его можно получить на" \ " этом же сайте\n\n model — это модель для генерации (в конфиге указано, какие модели есть)\n\n" \ " bad_prompt — негативный ввод. он нужен для того, чтобы убрать с ваших изображений то, " \ "что вы не хотите видеть\n\n debug — если установлено True, в ответе будет информация" \ " о генерируемом(-ых) изображении(-ях) (модель, prompt, bad_prompt, steps и т.д.)" \ "\n\n samples — кол-во генерации изображений" \ "\n\n steps — это «шаги». чем выше число, тем детальнее будет изображение" \ "\n\n upscale — улучшение генерации с помощью ИИ" \ "\n\n\n3️⃣ Использование \nПредположим, что Вы закончили настройку. " \ "Перейдём к использованию.\n\nИспользовать нужно так: .sd <prompt>\nГде <prompt> — что угодно" \ ", что вы хотите видеть на изображении" } def __init__(self): # debug: bool, bad_prompt self.config = loader.ModuleConfig( loader.ConfigValue( "api_key", None, lambda: self.strings("_cfg_api_key"), validator=loader.validators.Hidden() ), loader.ConfigValue( "model", "anything-v5", lambda: self.strings("_cfg_model"), validator=loader.validators.Choice([ 'abyssorangemix2nsfw', 'anything-v4', 'anything-v5', 'anythingelse-v4', 'bro623jbfe32', 'cetusmix', 'cnwi74tjsdfw', 'counterfeit-v20', 'counterfeit-v30', 'dark-sushi-25d', 'disillusionmix', 'grapefruit-nsfw-anim', 'hanfu', 'hc-a-mecha-musume-a', 'hc-kokkoro', 'hc-kyoka', 'hc-sailor-mercury', 'majicmixfantasy', 'meinamix', 'meinapastel', 'night-sky-yozora-sty', 'tmnd-mix', 'troi4bwiyt4', 'ttksuperspirit' ]) ), loader.ConfigValue( "bad_prompt", ( "(bad_prompt:0.8), multiple persons, multiple views, extra hands," " ugly, lowres, bad quality, blurry, disfigured, extra limbs," " missing limbs, deep fried, cheap art, missing fingers, out of" " frame, cropped, bad art, face hidden, text, speech bubble," " stretched, bad hands, error, extra digit, fewer digits, worst" " quality, low quality, normal quality, mutated, mutation," " deformed, severed, dismembered, corpse, pubic, poorly drawn," " (((deformed hands))), (((more than two hands))), (((deformed" " body))), ((((mutant)))), painting, extra fingers, mutated hands," " poorly drawn hands, poorly drawn face, bad anatomy, bad" " proportions, cloned face, skinny, glitchy, double torso," " extra arms, mangled fingers, missing lips, distorted face," " extra legs" ), lambda: self.strings("_cfg_bad_prompt"), ), loader.ConfigValue( "debug", False, lambda: self.strings("_cfg_debug"), validator=loader.validators.Boolean() ), loader.ConfigValue( "samples", 1, lambda: self.strings("_cfg_samples"), validator=loader.validators.Integer(minimum=1, maximum=4), ), loader.ConfigValue( "steps", 30, lambda: self.strings("_cfg_steps"), validator=loader.validators.Integer(minimum=1, maximum=50), ), loader.ConfigValue( "upscale", False, lambda: self.strings("_cfg_upscale"), validator=loader.validators.Boolean() ) ) async def getFetch(self, url): payload = json.dumps({"key": self.config['api_key']}) headers = {"Content-Type": "application/json"} r = (await utils.run_sync( requests.post, url, headers=headers, data=payload )).json() if r.get('status') == "success": return r['output'] else: return (await self.getFetch(url)) @loader.command( ru_doc="— помощь по использованию и настройке модуля", alias="sdh" ) async def sdhelpcmd(self, message: Message): """— help on using and configure the module""" await utils.answer( message, response=self.strings['help'] ) @loader.command( ru_doc=" — генерация изобраения с использованием StableDiffusion API." ) async def sdcmd(self, message: Message): """ — generate an image using StableDiffusion API""" if not self.config['api_key']: await utils.answer( message, self.strings['key_required'] ) return await utils.answer( message, response=self.strings['drawing'] ) prompt = utils.get_args_raw(message) url = "https://stablediffusionapi.com/api/v3/dreambooth" payload = json.dumps({ "key": self.config['api_key'], "model_id": self.config['model'], "prompt": prompt, "negative_prompt": self.config['bad_prompt'], "width": "512", "height": "512", "samples": self.config['samples'], "num_inference_steps": self.config['steps'], "safety_checker": "no", "enhance_prompt": "yes", "seed": None, "guidance_scale": 7.5, "multi_lingual": "no", "panorama": "no", "self_attention": "no", "upscale": "yes" if self.config['upscale'] else "no", "embeddings": "embeddings_model_id", "lora": "lora_model_id", "webhook": None, "track_id": None }) headers = { "Content-Type": "application/json" } r = (await utils.run_sync(requests.post, url, headers=headers, data=payload)).json() if r.get('status') == "error": await utils.answer( message, response=self.strings['error'].format(r) ) return if r.get('output'): out = self.strings['done'] if self.config['debug']: out += self.strings['debug'].format( model=r['meta']['model_id'], prompt=r['meta']['prompt'], negative=r['meta']['negative_prompt'], steps=r['meta']['steps'], upsc=self.strings['not'] if not self.config['upscale'] else "", time=f", {round(r['generationTime'], 2)}s" ) imgs = [] for i in r['output']: img = (await utils.run_sync( requests.get, i )).content imgs.append(img) await utils.answer_file( message, file=imgs, caption=out ) elif r.get('status') == "processing": out = self.strings['done'] if self.config['debug']: out += self.strings['debug'].format( model=r['meta']['model_id'], prompt=r['meta']['prompt'], negative=r['meta']['negative_prompt'], steps=r['meta']['steps'], upsc=self.strings['not'] if not self.config['upscale'] else "", time="" ) rr = await self.getFetch(r) imgs = [] for i in rr['output']: img = (await utils.run_sync( requests.get, i )).content imgs.append(img) await utils.answer_file( message, file=imgs, caption=out ) else: await utils.answer( message, response=self.strings['error'].format(r) )