main 71f03c950a18 cached
17 files
36.8 KB
11.2k tokens
33 symbols
1 requests
Download .txt
Repository: nftblackmagic/sdwebui-api-manager
Branch: main
Commit: 71f03c950a18
Files: 17
Total size: 36.8 KB

Directory structure:
gitextract_2av0vv_n/

├── .circleci/
│   └── config.yml
├── .gitignore
├── .vscode/
│   └── settings.json
├── Dockerfile
├── README.md
├── app/
│   ├── __init__.py
│   ├── api/
│   │   └── api.py
│   ├── db/
│   │   └── models.py
│   ├── main.py
│   └── manager/
│       └── reqq.py
├── docker-compose.yml
├── install.sh
├── launch.sh
├── launch_sd.sh
├── requirements.txt
└── test/
    ├── __init__.py
    └── test.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2
jobs:
  unit_test:
    docker:
      - image: circleci/python:3.6.1

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "requirements.txt" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            python3 -m venv venv
            . venv/bin/activate
            pip install -r requirements.txt

      - save_cache:
          paths:
            - ./venv
          key: v1-dependencies-{{ checksum "requirements.txt" }}

      # run tests!
      - run:
          name: run tests
          command: |
            . venv/bin/activate
            pytest test/test.py

workflows:
  version: 2
  build:
    jobs:
      - unit_test


================================================
FILE: .gitignore
================================================

# Created by https://www.gitignore.io/api/linux,macos,python,pycharm,windows,visualstudiocode
# Edit at https://www.gitignore.io/?templates=linux,macos,python,pycharm,windows,visualstudiocode

### Linux ###
*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn.  Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr

# Sonarlint plugin
.idea/**/sonarlint/

# SonarQube Plugin
.idea/**/sonarIssues.xml

# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# pyenv
.python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

### VisualStudioCode Patch ###
# Ignore all local history of files
.history

### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

# End of https://www.gitignore.io/api/linux,macos,python,pycharm,windows,visualstudiocode

================================================
FILE: .vscode/settings.json
================================================
{
  "[python]": {
    "editor.defaultFormatter": "ms-python.autopep8"
  },
  "python.formatting.provider": "none"
}


================================================
FILE: Dockerfile
================================================
# pull official base image
FROM python:3.8.1-alpine

# set work directory
WORKDIR /src

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy requirements file
COPY ./requirements.txt /src/requirements.txt

# install dependencies
RUN set -eux \
    && apk add --no-cache --virtual .build-deps build-base \
    libressl-dev libffi-dev gcc musl-dev python3-dev \
    postgresql-dev \
    && pip install --upgrade pip setuptools wheel \
    && pip install -r /src/requirements.txt \
    && rm -rf /root/.cache/pip

# copy project
COPY . /src/

EXPOSE 5001
CMD ["uvicorn", "app.main:app", "--reload",  "--host", "0.0.0.0", "--port", "5001"]

================================================
FILE: README.md
================================================
## Problem of stable diffusion webui

Stable diffusion webui provides a powerful tool for AI image generation. However, the webui api has some limitations:

1. a blocking REST api call, which might take more than 30s to return the final value. Most gateways don't allow such long blocking time on api call.
2. webui api is a single thread process. Once the thread is occupied, other webui api will fail. (Even though there is a multi thread mode in stable diffusion webui)

This repo is aiming to solve the above problems.

## Preconditions:

- Python 3
- Stable diffusion Webui

## Inspired by the project

https://github.com/marciovrl/fastapi-example.git

## Run local

### Before run this project, please make sure you launched the stable diffusion webui api.

### Install dependencies

```
pip install -r requirements.txt
```

### Run server

```
uvicorn app.main:app --reload --port 5001
```

<!-- ### Run test

```
pytest app/test.py
```

## Run with docker

### Run server

```
docker-compose up -d --build
```

### Run test

```
docker-compose exec app pytest test/test.py
``` -->

## API documentation (provided by Swagger UI)

```
http://127.0.0.1:8000/docs
```

<!-- ### Run server

```
docker-compose exec db psql --username=fastapi --dbname=fastapi_dev
``` -->

## Model swtich

There is an extra filed in txt2img/img2img api:

    options: Optional[dict]

You can swtich stable diffusion by using this options.

```
"options":
{
"sd_model_checkpoint": <The model you want to use>
}
```


================================================
FILE: app/__init__.py
================================================


================================================
FILE: app/api/api.py
================================================
import json
import requests


def img2img(payload):

    url = 'http://0.0.0.0:7860/sdapi/v1/img2img'

    headers = {
        'Content-Type': 'application/json',
    }

    filter_data = {}

    for k, v in payload.items():
        if payload[k] != None:
            filter_data[k] = v

    print("img2img settings", filter_data)

    response = requests.post(url, headers=headers,
                             data=json.dumps(filter_data))

    res = response.json()

    return res


def txt2img(payload):

    url = 'http://0.0.0.0:7860/sdapi/v1/txt2img'

    headers = {
        'Content-Type': 'application/json',
    }

    filter_data = {}

    for k, v in payload.items():
        if payload[k] != None:
            filter_data[k] = v

    print("txt2img settings", filter_data)

    response = requests.post(url, headers=headers,
                             data=json.dumps(filter_data))

    res = response.json()

    return res


def progress():
    url = 'http://0.0.0.0:7860/sdapi/v1/progress?skip_current_image=false'

    headers = {
        'Content-Type': 'application/json',
    }

    response = requests.get(url, headers=headers)

    res = response.json()

    return res


def get_options():
    url = 'http://0.0.0.0:7860/sdapi/v1/options'

    headers = {
        'Content-Type': 'application/json',
    }

    response = requests.get(url, headers=headers, timeout=5)

    res = response.json()

    return res


def set_options(payload):
    url = 'http://0.0.0.0:7860/sdapi/v1/options'

    headers = {
        'Content-Type': 'application/json',
    }

    filter_data = {}

    for k, v in payload.items():
        if payload[k] != None:
            filter_data[k] = v

    print("set_options settings", filter_data)

    response = requests.post(url, headers=headers,
                             data=json.dumps(filter_data))

    res = response.json()

    return res


def extra_single_image(payload):
    url = 'http://0.0.0.0:7860/sdapi/v1/extra-single-image'

    headers = {
        'Content-Type': 'application/json',
    }

    filter_data = {}

    for k, v in payload.items():
        if payload[k] != None:
            filter_data[k] = v

    print("set_options settings", filter_data)

    response = requests.post(url, headers=headers,
                             data=json.dumps(filter_data))

    res = response.json()

    return res


def controlnet_model_list():
    url = 'http://0.0.0.0:7860/controlnet/model_list'

    headers = {
        'Content-Type': 'application/json',
    }

    response = requests.get(url, headers=headers)

    res = response.json()

    return res


def controlnet_module_list():
    url = 'http://0.0.0.0:7860/controlnet/module_list'

    headers = {
        'Content-Type': 'application/json',
    }

    response = requests.get(url, headers=headers)

    res = response.json()

    return res


def sd_models():
    url = 'http://0.0.0.0:7860/sdapi/v1/sd-models'

    headers = {
        'Content-Type': 'application/json',
    }

    response = requests.get(url, headers=headers)

    res = response.json()

    return res


================================================
FILE: app/db/models.py
================================================
from pydantic import BaseModel
from typing import List, Optional


class Img2imgArgs(BaseModel):
    init_images: Optional[List[str]]
    resize_mode: Optional[int]
    denoising_strength: Optional[float]
    image_cfg_scale: Optional[int]
    mask: Optional[str]
    mask_blur: Optional[int]
    inpainting_fill: Optional[int]
    inpaint_full_res: Optional[bool]
    inpaint_full_res_padding: Optional[int]
    inpainting_mask_invert: Optional[bool]
    initial_noise_multiplier: Optional[int]
    prompt: Optional[str]
    styles: Optional[List[str]]
    seed: Optional[int]
    subseed: Optional[int]
    subseed_strength: Optional[int]
    seed_resize_from_h: Optional[int]
    seed_resize_from_w: Optional[int]
    sampler_name: Optional[str]
    batch_size: Optional[int]
    n_iter: Optional[int]
    steps: Optional[int]
    cfg_scale: Optional[int]
    width: Optional[int]
    height: Optional[int]
    restore_faces: Optional[bool]
    tiling: Optional[bool]
    do_not_save_samples: Optional[bool]
    do_not_save_grid: Optional[bool]
    negative_prompt: Optional[str]
    eta: Optional[int]
    s_min_uncond: Optional[int]
    s_churn: Optional[int]
    s_tmax: Optional[int]
    s_tmin: Optional[int]
    s_noise: Optional[int]
    override_settings: Optional[dict]
    override_settings_restore_afterwards: Optional[bool]
    script_args: Optional[List[dict]]
    sampler_index: Optional[str]
    include_init_images: Optional[bool]
    script_name: Optional[str]
    send_images: Optional[bool]
    save_images: Optional[bool]
    alwayson_scripts: Optional[dict]
    options: Optional[dict]


class Txt2imgArgs(BaseModel):
    enable_hr: Optional[bool]
    denoising_strength: Optional[float]
    firstphase_width: Optional[int]
    firstphase_height: Optional[int]
    hr_scale: Optional[int]
    hr_upscaler: Optional[str]
    hr_second_pass_steps: Optional[int]
    hr_resize_x: Optional[int]
    hr_resize_y: Optional[int]
    prompt: Optional[str]
    styles: Optional[List[str]]
    seed: Optional[int]
    subseed: Optional[int]
    subseed_strength: Optional[int]
    seed_resize_from_h: Optional[int]
    seed_resize_from_w: Optional[int]
    sampler_name: Optional[str]
    batch_size: Optional[int]
    n_iter: Optional[int]
    steps: Optional[int]
    cfg_scale: Optional[int]
    width: Optional[int]
    height: Optional[int]
    restore_faces: Optional[bool]
    tiling: Optional[bool]
    do_not_save_samples: Optional[bool]
    do_not_save_grid: Optional[bool]
    negative_prompt: Optional[str]
    eta: Optional[int]
    s_min_uncond: Optional[int]
    s_churn: Optional[int]
    s_tmax: Optional[int]
    s_tmin: Optional[int]
    s_noise: Optional[int]
    override_settings: Optional[dict]
    override_settings_restore_afterwards: Optional[bool]
    script_args: Optional[List[dict]]
    sampler_index: Optional[str]
    script_name: Optional[str]
    send_images: Optional[bool]
    save_image: Optional[bool]
    alwayson_scripts: Optional[dict]
    options: Optional[dict]


class ExtraSingleImage(BaseModel):
    resize_mode: Optional[int]
    show_extras_results: Optional[bool]
    gfpgan_visibility: Optional[int]
    codeformer_visibility: Optional[int]
    codeformer_weight: Optional[float]
    upscaling_resize: Optional[int]
    upscaling_resize_w: Optional[int]
    upscaling_resize_h: Optional[int]
    upscaling_crop: Optional[bool]
    upscaler_1: Optional[str]
    upscaler_2: Optional[str]
    extras_upscaler_2_visibility: Optional[int]
    upscale_first: Optional[bool]
    image: Optional[str]


================================================
FILE: app/main.py
================================================
from fastapi import FastAPI, HTTPException
from starlette.responses import Response

from app.db.models import Img2imgArgs, Txt2imgArgs, ExtraSingleImage
from app.api import api
from app.manager import reqq

app = FastAPI()


@app.get("/")
def root():
    return {"message": "Fast API in Python"}


@app.post("/rawimg2img", status_code=201)
def rawimg2img(payload: Img2imgArgs):
    payload = payload.dict()

    return api.img2img(payload)


@app.post("/rawtxt2img", status_code=201)
def rawtxt2img(payload: Txt2imgArgs):
    payload = payload.dict()

    return api.txt2img(payload)


@app.post("/img2img", status_code=201)
def img2img(payload: Img2imgArgs):
    payload = payload.dict()
    return reqq.add_req_queue(payload, "img2img")


@app.post("/txt2img", status_code=201)
def txt2img(payload: Txt2imgArgs):
    payload = payload.dict()
    return reqq.add_req_queue(payload, "txt2img")


@app.get("/progress/{req_id}")
def progress(req_id: str):
    return reqq.get_result(req_id)


@app.get("/controlnet/model_list")
def controlnet_model_list():
    return api.controlnet_model_list()


@app.get("/controlnet/module_list")
def controlnet_module_list():
    return api.controlnet_module_list()


@app.post("/sdapi/v1/extra-single-image", status_code=201)
def extra_single_image(payload: ExtraSingleImage):
    payload = payload.dict()
    return api.extra_single_image(payload)


@app.get("/sdapi/v1/sd-models")
def sd_models():
    return api.sd_models()


================================================
FILE: app/manager/reqq.py
================================================
import uuid
import queue
import threading
import time
import copy
from app.api import api
from fastapi import HTTPException


current_request = {}
final_results = {}
current_options = {}


class QueueMonitor:
    def __init__(self, q):
        self.q = q
        self.monitor_thread = threading.Thread(
            target=self.monitor_queue, daemon=True)
        self.monitor_thread.start()

    def get_queue_size(self):
        return self.q.qsize()

    def monitor_queue(self):
        while True:
            current_size = self.get_queue_size()
            if current_size > 0:
                self.queue_has_items()
            time.sleep(1)  # check the queue every second

    def queue_has_items(self):
        print(f"Queue has items. Current size: {self.get_queue_size()}")
        self.callback_function()

    def callback_function(self):
        start_process_queue()


requests_queue = queue.Queue(20)

# Create a QueueMonitor object with the Queue
monitor = QueueMonitor(requests_queue)


def start_process_queue():
    global current_request
    global final_results
    if ((current_request.get("status") != "pending") and (current_request.get("status") != "processing")):
        if not requests_queue.empty():
            current_request = requests_queue.get()
            current_request["status"] = "processing"
            print("current_request is processing", current_request.get(
                "request_id"), current_request.get("status"))
            request_options = current_request.get("options")
            compare_options(request_options)
            if (current_request.get("type") == "txt2img"):
                res = api.txt2img(current_request.get("payload"))
                final_request = copy.deepcopy(current_request)
                final_request["status"] = "done"
                final_request["result"] = res
                final_results[final_request.get("request_id")] = final_request
                print("request is complete", final_request.get(
                    "request_id"), final_request.get("status"))
                current_request["status"] = "finishing"
            if (current_request.get("type") == "img2img"):
                res = api.img2img(current_request.get("payload"))
                final_request = copy.deepcopy(current_request)
                final_request["status"] = "done"
                final_request["result"] = res
                final_results[final_request.get("request_id")] = final_request
                print("request is complete", final_request.get(
                    "request_id"), final_request.get("status"))
                current_request["status"] = "finishing"


def add_req_queue(payload, type):
    # try:
    #     api.get_options()
    # except:
    #     raise HTTPException(
    #         status_code=500, detail="No options found, please check backend is running correctly.")

    filter_data = {}
    options = {}

    for k, v in payload.items():
        if (k == "options"):
            options = v
        if payload[k] != None:
            filter_data[k] = v

    request_id = str(uuid.uuid4())
    temp_request = {
        "type": type,
        "payload": filter_data,
        "request_id": request_id,
        "status": "pending",
        "options": options
    }
    requests_queue.put(temp_request)
    print("add request into queue, pending", request_id)
    return temp_request


def check_variable_in_queue(q, var):
    queue_as_list = list(q.queue)
    pending_requests = []
    for i in queue_as_list:
        pending_requests.append(i.get("request_id"))
    if var in pending_requests:
        print(f"{var} is in the queue.")
        return pending_requests.index(var)
    else:
        print(f"{var} is not in the queue.")
        return -1


def get_result(request_id):
    global final_results
    print("final_results", final_results.keys(), request_id)
    if (request_id in final_results):
        print("Found final result", request_id)
        return final_results[request_id]
    elif (request_id == current_request.get("request_id")):
        res = api.progress()
        temp_res = current_request
        temp_res["result"] = res
        return temp_res
    else:
        index = check_variable_in_queue(requests_queue, request_id)
        if (index > -1):
            return {"status": "pending", "request_id": request_id, "pending_count": index+1}
        else:
            return {"status": "not_found"}


def compare_options(options):
    global current_options
    is_change = False
    print("compare_options", options)
    for k, v in options.items():
        if (current_options.get(k) != v):
            is_change = True
            break

    if (is_change):
        current_options = copy.deepcopy(options)
        print("start to set options to api", current_options)
        api.set_options(options)


================================================
FILE: docker-compose.yml
================================================
version: "3.7"

services:
  app:
    build: .
    container_name: app
    command: uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 8000
    volumes:
      - ./:/src/
    ports:
      - 8002:8000
    environment:
      - DATABASE_URL=postgresql://fastapi:fastapi@db/fastapi

  db:
    image: postgres:12.1-alpine
    container_name: db
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=fastapi
      - POSTGRES_PASSWORD=fastapi
      - POSTGRES_DB=fastapi

volumes:
  postgres_data:


================================================
FILE: install.sh
================================================
apt update
apt install -y aria2
apt-get install python3-pip
apt install vim
apt-get install tmux

pip3 install -r requirements.txt

git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
git reset --hard 394ffa7
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/embed/upscale/resolve/main/4x-UltraSharp.pth -d ./stable-diffusion-webui/models/ESRGAN -o 4x-UltraSharp.pth
wget https://raw.githubusercontent.com/camenduru/stable-diffusion-webui-scripts/main/run_n_times.py -O ./stable-diffusion-webui/scripts/run_n_times.py
git clone https://github.com/camenduru/stable-diffusion-webui-images-browser ./stable-diffusion-webui/extensions/stable-diffusion-webui-images-browser
git clone https://github.com/camenduru/sd-civitai-browser ./stable-diffusion-webui/extensions/sd-civitai-browser
git clone https://github.com/kohya-ss/sd-webui-additional-networks ./stable-diffusion-webui/extensions/sd-webui-additional-networks
git clone https://github.com/Mikubill/sd-webui-controlnet ./stable-diffusion-webui/extensions/sd-webui-controlnet
git clone https://github.com/camenduru/sd-webui-tunnels ./stable-diffusion-webui/extensions/sd-webui-tunnels
git clone https://github.com/etherealxx/batchlinks-webui ./stable-diffusion-webui/extensions/batchlinks-webui
git clone https://github.com/camenduru/stable-diffusion-webui-catppuccin ./stable-diffusion-webui/extensions/stable-diffusion-webui-catppuccin
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui-rembg ./stable-diffusion-webui/extensions/stable-diffusion-webui-rembg
git clone https://github.com/ashen-sensored/stable-diffusion-webui-two-shot ./stable-diffusion-webui/extensions/stable-diffusion-webui-two-shot
git clone https://github.com/thomasasfk/sd-webui-aspect-ratio-helper ./stable-diffusion-webui/extensions/sd-webui-aspect-ratio-helper
git clone https://github.com/nonnonstop/sd-webui-3d-open-pose-editor ./stable-diffusion-webui/extensions/sd-webui-3d-open-pose-editor
git clone https://github.com/continue-revolution/sd-webui-segment-anything.git ./stable-diffusion-webui/extensions/sd-webui-segment-anything
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11e_sd15_ip2p_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11e_sd15_shuffle_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_canny_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11f1p_sd15_depth_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_inpaint_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_lineart_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_lineart_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_mlsd_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_normalbae_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_openpose_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_scribble_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_seg_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_seg_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15_softedge_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_softedge_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15s2_lineart_anime_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/control_v11f1e_sd15_tile_fp16.safetensors -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11f1e_sd15_tile_fp16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11e_sd15_ip2p_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11e_sd15_ip2p_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11e_sd15_shuffle_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11e_sd15_shuffle_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_canny_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_canny_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11f1p_sd15_depth_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11f1p_sd15_depth_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_inpaint_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_inpaint_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_lineart_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_lineart_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_mlsd_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_mlsd_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_normalbae_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_normalbae_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_openpose_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_openpose_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_scribble_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_scribble_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_seg_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_seg_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15_softedge_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15_softedge_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11p_sd15s2_lineart_anime_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11p_sd15s2_lineart_anime_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/raw/main/control_v11f1e_sd15_tile_fp16.yaml -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o control_v11f1e_sd15_tile_fp16.yaml
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_style_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_style_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_sketch_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_sketch_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_seg_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_seg_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_openpose_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_openpose_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_keypose_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_keypose_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_depth_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_depth_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_color_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_color_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_canny_sd14v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_canny_sd14v1.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_canny_sd15v2.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_canny_sd15v2.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_depth_sd15v2.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_depth_sd15v2.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_sketch_sd15v2.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_sketch_sd15v2.pth
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/ControlNet-v1-1/resolve/main/t2iadapter_zoedepth_sd15v1.pth -d ./stable-diffusion-webui/extensions/sd-webui-controlnet/models -o t2iadapter_zoedepth_sd15v1.pth

aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/anything-v3.0/resolve/main/Anything-V3.0-pruned.ckpt -d ./stable-diffusion-webui/models/Stable-diffusion -o Anything-V3.0-pruned.ckpt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/ckpt/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt -d ./stable-diffusion-webui/models/Stable-diffusion -o Anything-V3.0-pruned.vae.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/xiaozaa/animaTest/resolve/main/animeoutlineV4_16.safetensors -d ./stable-diffusion-webui/models/Lora -o animeoutlineV4_16.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/SG161222/Realistic_Vision_V4.0/resolve/main/Realistic_Vision_V4.0.safetensors -d ./stable-diffusion-webui/models/Stable-diffusion -o Realistic_Vision_V4.0.safetensors

aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/Sasulee/animeLineartMangaLike_v30MangaLike/resolve/main/animeLineartMangaLike_v30MangaLike.safetensors -d ./stable-diffusion-webui/models/Lora -o animeLineartMangaLike_v30MangaLike.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/datasets/Nerfgun3/bad_prompt/resolve/main/bad_prompt_version2.pt -d ./stable-diffusion-webui/embeddings -o bad_prompt_version2.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/datasets/gsdf/EasyNegative/resolve/main/EasyNegative.pt -d ./stable-diffusion-webui/embeddings -o EasyNegative.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/nick-x-hacker/bad-artist/resolve/main/bad-artist.pt -d ./stable-diffusion-webui/embeddings -o bad-artist.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/embed/negative/resolve/main/bad-hands-5.pt -d ./stable-diffusion-webui/embeddings -o bad-hands-5.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/embed/negative/resolve/main/ng_deepnegative_v1_75t.pt -d ./stable-diffusion-webui/embeddings -o ng_deepnegative_v1_75t.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/embed/negative/resolve/main/EasyNegativeV2.safetensors -d ./stable-diffusion-webui/embeddings -o EasyNegativeV2.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/embed/negative/resolve/main/verybadimagenegative_v1.3.pt -d ./stable-diffusion-webui/embeddings -o verybadimagenegative_v1.3.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/embed/negative/resolve/main/bad-image-v2-39000.pt -d ./stable-diffusion-webui/embeddings -o bad-image-v2-39000.pt
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://civitai.com/api/download/models/90072?type=Model&format=SafeTensor&size=pruned&fp=fp16  -d ./stable-diffusion-webui/models/Stable-diffusion -o photon_v1.safetensors
aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth -d ./stable-diffusion-webui/models/sam -o sam_vit_h_4b8939.pth

sed -i -e '/    api = create_api/a\' -e '    modules.script_callbacks.before_ui_callback()' ./stable-diffusion-webui/webui.py
sed -i -e 's/\"sd_model_checkpoint\"\,/\"sd_model_checkpoint\,sd_vae\,CLIP_stop_at_last_layers\"\,/g' ./stable-diffusion-webui/modules/shared.py

cd ./stable-diffusion-webui
apt install python3.10-venv
python3.10 -m venv venv

================================================
FILE: launch.sh
================================================
python3 -m uvicorn app.main:app --reload --host 0.0.0.0 --port 5001 


================================================
FILE: launch_sd.sh
================================================
cd ./stable-diffusion-webui
bash <(wget -qO- https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh) -f --listen --xformers --enable-insecure-extension-access --theme dark --api 

================================================
FILE: requirements.txt
================================================
fastapi==0.98.0
pytest==7.4.0
requests==2.31.0
uvicorn==0.22.0

================================================
FILE: test/__init__.py
================================================


================================================
FILE: test/test.py
================================================
from starlette.testclient import TestClient
from app.main import app
import json

client = TestClient(app)

Download .txt
gitextract_2av0vv_n/

├── .circleci/
│   └── config.yml
├── .gitignore
├── .vscode/
│   └── settings.json
├── Dockerfile
├── README.md
├── app/
│   ├── __init__.py
│   ├── api/
│   │   └── api.py
│   ├── db/
│   │   └── models.py
│   ├── main.py
│   └── manager/
│       └── reqq.py
├── docker-compose.yml
├── install.sh
├── launch.sh
├── launch_sd.sh
├── requirements.txt
└── test/
    ├── __init__.py
    └── test.py
Download .txt
SYMBOL INDEX (33 symbols across 4 files)

FILE: app/api/api.py
  function img2img (line 5) | def img2img(payload):
  function txt2img (line 29) | def txt2img(payload):
  function progress (line 53) | def progress():
  function get_options (line 67) | def get_options():
  function set_options (line 81) | def set_options(payload):
  function extra_single_image (line 104) | def extra_single_image(payload):
  function controlnet_model_list (line 127) | def controlnet_model_list():
  function controlnet_module_list (line 141) | def controlnet_module_list():
  function sd_models (line 155) | def sd_models():

FILE: app/db/models.py
  class Img2imgArgs (line 5) | class Img2imgArgs(BaseModel):
  class Txt2imgArgs (line 54) | class Txt2imgArgs(BaseModel):
  class ExtraSingleImage (line 100) | class ExtraSingleImage(BaseModel):

FILE: app/main.py
  function root (line 12) | def root():
  function rawimg2img (line 17) | def rawimg2img(payload: Img2imgArgs):
  function rawtxt2img (line 24) | def rawtxt2img(payload: Txt2imgArgs):
  function img2img (line 31) | def img2img(payload: Img2imgArgs):
  function txt2img (line 37) | def txt2img(payload: Txt2imgArgs):
  function progress (line 43) | def progress(req_id: str):
  function controlnet_model_list (line 48) | def controlnet_model_list():
  function controlnet_module_list (line 53) | def controlnet_module_list():
  function extra_single_image (line 58) | def extra_single_image(payload: ExtraSingleImage):
  function sd_models (line 64) | def sd_models():

FILE: app/manager/reqq.py
  class QueueMonitor (line 15) | class QueueMonitor:
    method __init__ (line 16) | def __init__(self, q):
    method get_queue_size (line 22) | def get_queue_size(self):
    method monitor_queue (line 25) | def monitor_queue(self):
    method queue_has_items (line 32) | def queue_has_items(self):
    method callback_function (line 36) | def callback_function(self):
  function start_process_queue (line 46) | def start_process_queue():
  function add_req_queue (line 77) | def add_req_queue(payload, type):
  function check_variable_in_queue (line 106) | def check_variable_in_queue(q, var):
  function get_result (line 119) | def get_result(request_id):
  function compare_options (line 138) | def compare_options(options):
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (40K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 901,
    "preview": "version: 2\njobs:\n  unit_test:\n    docker:\n      - image: circleci/python:3.6.1\n\n    working_directory: ~/repo\n\n    steps"
  },
  {
    "path": ".gitignore",
    "chars": 4861,
    "preview": "\n# Created by https://www.gitignore.io/api/linux,macos,python,pycharm,windows,visualstudiocode\n# Edit at https://www.git"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 116,
    "preview": "{\n  \"[python]\": {\n    \"editor.defaultFormatter\": \"ms-python.autopep8\"\n  },\n  \"python.formatting.provider\": \"none\"\n}\n"
  },
  {
    "path": "Dockerfile",
    "chars": 671,
    "preview": "# pull official base image\nFROM python:3.8.1-alpine\n\n# set work directory\nWORKDIR /src\n\n# set environment variables\nENV "
  },
  {
    "path": "README.md",
    "chars": 1500,
    "preview": "## Problem of stable diffusion webui\n\nStable diffusion webui provides a powerful tool for AI image generation. However, "
  },
  {
    "path": "app/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/api/api.py",
    "chars": 3109,
    "preview": "import json\nimport requests\n\n\ndef img2img(payload):\n\n    url = 'http://0.0.0.0:7860/sdapi/v1/img2img'\n\n    headers = {\n "
  },
  {
    "path": "app/db/models.py",
    "chars": 3558,
    "preview": "from pydantic import BaseModel\nfrom typing import List, Optional\n\n\nclass Img2imgArgs(BaseModel):\n    init_images: Option"
  },
  {
    "path": "app/main.py",
    "chars": 1465,
    "preview": "from fastapi import FastAPI, HTTPException\nfrom starlette.responses import Response\n\nfrom app.db.models import Img2imgAr"
  },
  {
    "path": "app/manager/reqq.py",
    "chars": 4854,
    "preview": "import uuid\nimport queue\nimport threading\nimport time\nimport copy\nfrom app.api import api\nfrom fastapi import HTTPExcept"
  },
  {
    "path": "docker-compose.yml",
    "chars": 548,
    "preview": "version: \"3.7\"\n\nservices:\n  app:\n    build: .\n    container_name: app\n    command: uvicorn app.main:app --reload --worke"
  },
  {
    "path": "install.sh",
    "chars": 15668,
    "preview": "apt update\napt install -y aria2\napt-get install python3-pip\napt install vim\napt-get install tmux\n\npip3 install -r requir"
  },
  {
    "path": "launch.sh",
    "chars": 69,
    "preview": "python3 -m uvicorn app.main:app --reload --host 0.0.0.0 --port 5001 \n"
  },
  {
    "path": "launch_sd.sh",
    "chars": 210,
    "preview": "cd ./stable-diffusion-webui\nbash <(wget -qO- https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/mast"
  },
  {
    "path": "requirements.txt",
    "chars": 62,
    "preview": "fastapi==0.98.0\npytest==7.4.0\nrequests==2.31.0\nuvicorn==0.22.0"
  },
  {
    "path": "test/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "test/test.py",
    "chars": 108,
    "preview": "from starlette.testclient import TestClient\nfrom app.main import app\nimport json\n\nclient = TestClient(app)\n\n"
  }
]

About this extraction

This page contains the full source code of the nftblackmagic/sdwebui-api-manager GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (36.8 KB), approximately 11.2k tokens, and a symbol index with 33 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!