Updated API (markdown)

missionfloyd 2023-09-27 02:53:17 -06:00
parent ff1520216a
commit 5a546980e7

75
API.md

@ -29,27 +29,18 @@ I can put in as few or as many parameters as I want in the payload. The API will
```py ```py
response = requests.post(url=f'http://127.0.0.1:7860/sdapi/v1/txt2img', json=payload) 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. 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... 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. - 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. - First, I put this line `r = response.json()` to make it easier to work with the response.
- "images" is the generated image, which is what I want mostly. There's no link or anything; it's a giant string of random characters, apparently we have to decode it. This is how I do it: - "images" is a list of base64-encoded generated images.
```py ```py
for i in r['images']: image = Image.open(io.BytesIO(base64.b64decode(r['images'][0])))
image = Image.open(io.BytesIO(base64.b64decode(i.split(",",1)[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')`. - With that, we have an image in the `image` variable that we can work with, for example saving it with `image.save('output.png')`.
- "parameters" shows what was sent to the API, which could be useful, but what I want in this case is "info". I use it to insert metadata into the image, so I can drop it into web ui PNG Info. For that, I can access the `/sdapi/v1/png-info` API. I'll need to feed the image I got above into it.
```py
png_payload = {
"image": "data:image/png;base64," + i
}
response2 = requests.post(url=f'http://127.0.0.1:7860/sdapi/v1/png-info', json=png_payload)
```
After that, I can get the information with `response2.json().get("info")`
------ ------
@ -59,7 +50,7 @@ import json
import requests import requests
import io import io
import base64 import base64
from PIL import Image, PngImagePlugin from PIL import Image
url = "http://127.0.0.1:7860" url = "http://127.0.0.1:7860"
@ -72,30 +63,18 @@ response = requests.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
r = response.json() r = response.json()
for i in r['images']: image = Image.open(io.BytesIO(base64.b64decode(r['images'][0])))
image = Image.open(io.BytesIO(base64.b64decode(i.split(",",1)[0]))) image.save('output.png')
png_payload = {
"image": "data:image/png;base64," + i
}
response2 = requests.post(url=f'{url}/sdapi/v1/png-info', json=png_payload)
pnginfo = PngImagePlugin.PngInfo()
pnginfo.add_text("parameters", response2.json().get("info"))
image.save('output.png', pnginfo=pnginfo)
``` ```
- Import the things I need - Import the things I need.
- define the url and the payload to send - Define the URL and the payload to send.
- send said payload to said url through the API - Send said payload to said URL through the API.
- in a loop grab "images" and decode it - Decode and save the image.
- for each image, send it to png info API and get that info back
- define a plugin to add png info, then add the png info I defined into it
- at the end here, save the image with the png info
----- -----
A note on `"override_settings"`. A note on `override_settings`.
The purpose of this endpoint is to override the web ui settings for a single request, such as the CLIP skip. The settings that can be passed into this parameter are visible here at the url's /docs. 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`.
![image](https://user-images.githubusercontent.com/2993060/202877368-c31a6e9e-0d05-40ec-ade0-49ed2c4be22b.png) ![image](https://user-images.githubusercontent.com/2993060/202877368-c31a6e9e-0d05-40ec-ade0-49ed2c4be22b.png)
@ -107,20 +86,16 @@ payload = {
"steps": 20 "steps": 20
} }
override_settings = {} override_settings = {
override_settings["filter_nsfw"] = true "filter_nsfw": True,
override_settings["CLIP_stop_at_last_layers"] = 2 "CLIP_stop_at_last_layers": 2,
override_payload = {
"override_settings": override_settings
} }
payload.update(override_payload)
payload["override_settings"] = override_settings
``` ```
- Have the normal payload - Define the normal payload.
- after that, initialize a dictionary (I call it "override_settings", but maybe not the best name) - Define a dictionary containing your settings.
- then I can add as many key:value pairs as I want to it - Add it to the original payload.
- make a new payload with just this parameter
- update the original payload to add this one to it
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, with the CLIP skip at 2, as well as the NSFW filter on.
@ -137,12 +112,12 @@ option_payload = {
response = requests.post(url=f'{url}/sdapi/v1/options', json=option_payload) 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. 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 the `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) 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)
![image](https://user-images.githubusercontent.com/2993060/202928589-114aff91-2777-4269-9492-2eab015c5bca.png) ![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. The `title` (name and hash) is what you want to use.
----- -----