Updated API (markdown)

This commit is contained in:
missionfloyd 2024-02-20 18:11:29 -07:00 committed by netherquark
parent 1ef05c303d
commit eb2eee9e6f
1 changed files with 37 additions and 57 deletions

94
API.md
View File

@ -1,17 +1,16 @@
## Example script
[txt2img and img2img example python script](https://gist.github.com/w-e-w/0f37c04c18e14e4ee1482df5c4eb9f53)
## Useful utility
[API payload display](https://github.com/huchenlei/sd-webui-api-payload-display) a extension that
converts webui image generation call to json for API
[API payload display](https://github.com/huchenlei/sd-webui-api-payload-display) a extension that converts webui image generation call to JSON for API
###
## API guide by [@Kilvoctu](https://github.com/Kilvoctu)
> **Note:**
> As of 2023-09-09, this guide is currently not maintained, and information is likely out of date. Note that the internal docs can always be accessed via the `/docs` endpoint (i.e. http://127.0.0.1:7860/docs)
- First, of course, is to run web ui with `--api` commandline argument
- First, of course, is to run webui with `--api` commandline argument
- example in your "webui-user.bat": `set COMMANDLINE_ARGS=--api`
- This enables the api which can be reviewed at http://127.0.0.1:7860/docs (or whever the URL is + /docs)
- This enables the API which can be reviewed at http://127.0.0.1:7860/docs (or whever the URL is + /docs)
The basic ones I'm interested in are these two. Let's just focus only on ` /sdapi/v1/txt2img`
![image](https://user-images.githubusercontent.com/2993060/198171114-ed1c5edd-76ce-4c34-ad73-04e388423162.png)
@ -23,41 +22,38 @@ The basic ones I'm interested in are these two. Let's just focus only on ` /sdap
------
- So that's the backend. The API basically says what's available, what it's asking for, and where to send it. Now moving onto the frontend, I'll start with constructing a payload with the parameters I want. An example can be:
```py
payload = {
"prompt": "maltese puppy",
"steps": 5
}
```
I can put in as few or as many parameters as I want in the payload. The API will use the defaults for anything I don't set.
```py
payload = {
"prompt": "maltese puppy",
"steps": 5
}
```
I can put in as few or as many parameters as I want in the payload. The API will use the defaults for anything I don't set.
- After that, I can send it to the API
```py
response = requests.post(url=f'http://127.0.0.1:7860/sdapi/v1/txt2img', json=payload)
```
Again, this URL needs to match the web UI's URL.
If we execute this code, the web UI will generate an image based on the payload. That's great, but then what? There is no image anywhere...
```py
response = requests.post(url='http://127.0.0.1:7860/sdapi/v1/txt2img', json=payload)
```
Again, this URL needs to match the web UI's URL.
If we execute this code, the web UI will generate an image based on the payload. That's great, but then what? There is no image anywhere...
------
- After the backend does its thing, the API sends the response back in a variable that was assigned above: `response`. The response contains three entries; `images`, `parameters`, and `info`, and I have to find some way to get the information from these entries.
- First, I put this line `r = response.json()` to make it easier to work with the response.
- "images" is a list of base64-encoded generated images.
```py
image = Image.open(io.BytesIO(base64.b64decode(r['images'][0])))
```
- With that, we have an image in the `image` variable that we can work with, for example saving it with `image.save('output.png')`.
- From there, we can decode and save it.
```python
with open("output.png", 'wb') as f:
f.write(base64.b64decode(r['images'][0]))
```
------
A sample code that should work can look like this:
A sample script that should work can look like this:
```py
import json
import requests
import io
import base64
from PIL import Image
# Define the URL and the payload to send.
url = "http://127.0.0.1:7860"
payload = {
@ -65,46 +61,33 @@ payload = {
"steps": 5
}
# Send said payload to said URL through the API.
response = requests.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
r = response.json()
image = Image.open(io.BytesIO(base64.b64decode(r['images'][0])))
image.save('output.png')
# Decode and save the image.
with open("output.png", 'wb') as f:
f.write(base64.b64decode(r['images'][0]))
```
- Import the things I need.
- Define the URL and the payload to send.
- Send said payload to said URL through the API.
- Decode and save the image.
-----
A note on `override_settings`.
The purpose of this endpoint is to override the web UI settings such as CLIP skip for a single request. The settings that can be passed into this parameter are can be found at the URL `/docs`.
The purpose of this parameter is to override the webui settings such as model or CLIP skip for a single request. The settings that can be passed into this parameter are can be found at the URL `/docs`.
![image](https://user-images.githubusercontent.com/2993060/202877368-c31a6e9e-0d05-40ec-ade0-49ed2c4be22b.png)
You can expand the tab and the API will provide a list. There are a few ways you can add this value to your payload, but this is how I do it. I'll demonstrate with "filter_nsfw", and "CLIP_stop_at_last_layers".
You can expand the tab and the API will provide a list. There are a few ways you can add this value to your payload, but this is how I do it. I'll demonstrate with "sd_model_checkpoint", and "CLIP_stop_at_last_layers".
```py
payload = {
"prompt": "cirno",
"steps": 20
"steps": 20,
"override_settings" = {
"sd_model_checkpoint": "Anything-V3.0-pruned",
"CLIP_stop_at_last_layers": 2,
}
}
override_settings = {
"filter_nsfw": True,
"CLIP_stop_at_last_layers": 2,
}
payload["override_settings"] = override_settings
```
- Define the normal payload.
- Define a dictionary containing your settings.
- Add it to the original payload.
So in this case, when I send the payload, I should get a "cirno" at 20 steps, with the CLIP skip at 2, as well as the NSFW filter on.
So in this case, when I send the payload, I should get a "cirno" at 20 steps, using the "Anything-V3.0-pruned" model with the CLIP skip at 2.
For certain settings or situations, you may want your changes to stay. For that you can post to the `/sdapi/v1/options` API endpoint
We can use what we learned so far and set up the code easily for this. Here is an example:
@ -112,18 +95,15 @@ We can use what we learned so far and set up the code easily for this. Here is a
url = "http://127.0.0.1:7860"
option_payload = {
"sd_model_checkpoint": "Anything-V3.0-pruned.ckpt [2700c435]",
"sd_model_checkpoint": "Anything-V3.0-pruned",
"CLIP_stop_at_last_layers": 2
}
response = requests.post(url=f'{url}/sdapi/v1/options', json=option_payload)
```
After sending this payload to the API, the model should swap to the one I set and set the CLIP skip to 2. Reiterating, this is different from `override_settings`, because this change will persist, while `override_settings` is for a single request.
Note that if you're changing `sd_model_checkpoint`, the value should be the name of the checkpoint as it appears in the web UI. This can be referenced with this API endpoint (same way we reference "options" API)
After sending this payload to the API, the model should swap to the one I set and set the CLIP skip to 2. Reiterating, this is different from `override_settings` because this change will persist, while `override_settings` is for a single request.
![image](https://user-images.githubusercontent.com/2993060/202928589-114aff91-2777-4269-9492-2eab015c5bca.png)
The `title` (name and hash) is what you want to use.
Note that if you're changing `sd_model_checkpoint`, the value can be the name of the checkpoint as it appears in the web UI, the filename (with or without extension), or the hash.
-----