├── .github
└── workflows
│ ├── build.yml
│ ├── pr.yml
│ └── release.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle.kts
├── docs
└── images
│ ├── img2img-dog.png
│ └── txt2img-dog.png
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
└── src
├── main
└── java
│ └── io
│ └── github
│ └── robothy
│ └── sdwebui
│ └── sdk
│ ├── ExtraImage.java
│ ├── GetFaceRestorers.java
│ ├── GetSdModels.java
│ ├── Image2Image.java
│ ├── Main.java
│ ├── SdWebui.java
│ ├── SdWebuiBeanContainer.java
│ ├── SdWebuiBeanFactory.java
│ ├── SystemInfoFetcher.java
│ ├── Txt2Image.java
│ ├── enums
│ ├── HiResUpscaler.java
│ └── Upscaler.java
│ ├── exceptions
│ ├── SdWebuiBadRequestException.java
│ ├── SdWebuiServerException.java
│ └── SdWebuiServerValidationException.java
│ ├── models
│ ├── SdWebuiOptions.java
│ ├── SystemInfo.java
│ ├── options
│ │ ├── ExtraImageOptions.java
│ │ ├── Image2ImageOptions.java
│ │ └── Txt2ImageOptions.java
│ └── results
│ │ ├── ExtraImageResult.java
│ │ ├── FaceRestorer.java
│ │ ├── Image2ImageResult.java
│ │ ├── SdModel.java
│ │ └── Txt2ImgResult.java
│ ├── services
│ ├── CacheableSystemInfoFetcher.java
│ ├── CommonGetService.java
│ ├── DefaultExtraImageService.java
│ ├── DefaultGetFaceRestorersService.java
│ ├── DefaultGetSdModelService.java
│ ├── DefaultImage2ImageService.java
│ ├── DefaultSdWebuiBeanContainer.java
│ ├── DefaultTxt2ImageService.java
│ └── SdWebuiInvocationHandler.java
│ └── utils
│ ├── JsonUtils.java
│ └── SdWebuiResponseUtils.java
└── test
└── java
└── io
└── github
└── robothy
└── sdwebui
└── sdk
├── GetFaceRestorersTest.java
├── MockSdServer.java
└── models
├── SystemInfoTest.java
├── options
├── ExtraImageOptionsTest.java
├── Image2ImageOptionsTest.java
└── Txt2ImageOptionsTest.java
└── results
├── FaceRestorerTest.java
├── Image2ImageResultTest.java
├── SdModelTest.java
└── Txt2ImgResultTest.java
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Main Branch Build
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-20.04
10 |
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v3
14 |
15 | - name: Setup Java 17 for Gradle
16 | uses: actions/setup-java@v3
17 | with:
18 | distribution: 'temurin'
19 | java-version: '17'
20 |
21 | - name: Gradle Cache
22 | uses: actions/cache@v3
23 | with:
24 | path: |
25 | ~/.gradle/caches
26 | ~/.gradle/wrapper
27 | key: ${{runner.os}}-build-gradle-${{hashFiles('**/gradle-wrapper.properties')}}
28 |
29 | - name: Prepare parameters
30 | run: |
31 | git log --pretty=format:"%H - %an, %aI : %s" -5
32 | mkdir -p ~/.gradle
33 | echo "GITHUB_TOKEN=${{secrets.PACKAGES_TOKEN}}" > ~/.gradle/gradle.properties
34 | echo "GITHUB_USERNAME=Robothy" >> ~/.gradle/gradle.properties
35 | chmod +x gradlew
36 | pwd
37 | ls -l
38 |
39 | - name: Build
40 | run: ./gradlew mergeReports
41 |
42 | - name: Upload coverage to Codecov
43 | uses: codecov/codecov-action@v3
44 | with:
45 | files: ./build/reports/jacoco/mergeReports/mergeReports.xml
46 | env:
47 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/pr.yml:
--------------------------------------------------------------------------------
1 | name: PR Build
2 | on:
3 | pull_request
4 |
5 | jobs:
6 | pr-build:
7 | runs-on: ubuntu-20.04
8 |
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v3
12 |
13 | - name: Setup Java 17 for Gradle
14 | uses: actions/setup-java@v3
15 | with:
16 | distribution: 'temurin'
17 | java-version: '17'
18 |
19 | - name: Gradle Cache
20 | uses: actions/cache@v3
21 | with:
22 | path: |
23 | ~/.gradle/caches
24 | key: ${{runner.os}}-build-gradle-${{hashFiles('**/gradle-wrapper.properties')}}
25 |
26 | - name: Prepare parameters
27 | run: |
28 | git log --pretty=format:"%H - %an, %aI : %s" -5
29 | mkdir -p ~/.gradle
30 | echo "GITHUB_TOKEN=${{secrets.PACKAGES_TOKEN}}" > ~/.gradle/gradle.properties
31 | echo "GITHUB_USERNAME=Robothy" >> ~/.gradle/gradle.properties
32 | chmod +x gradlew
33 | pwd
34 | ls -l
35 |
36 | - name: Build
37 | run: ./gradlew mergeReports
38 |
39 | - name: Upload coverage to Codecov
40 | uses: codecov/codecov-action@v3
41 | with:
42 | files: ./build/reports/jacoco/mergeReports/mergeReports.xml
43 | env:
44 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | gradleLogLevel:
6 | description: 'Gradle logging level.'
7 | required: false
8 | default: None
9 | type: choice
10 | options:
11 | - None
12 | - Info
13 | - Warn
14 | - Debug
15 | - Stacktrace
16 |
17 | jobs:
18 | release:
19 | runs-on: ubuntu-20.04
20 | env:
21 | GITHUB_USERNAME: Robothy
22 |
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v3
26 |
27 | - name: Setup Java 17 for Gradle
28 | uses: actions/setup-java@v3
29 | with:
30 | distribution: 'temurin'
31 | java-version: '17'
32 |
33 | - name: Gradle Cache
34 | uses: actions/cache@v3
35 | with:
36 | path: |
37 | ~/.gradle/caches
38 | key: ${{runner.os}}-build-gradle-${{hashFiles('**/gradle-wrapper.properties')}}
39 |
40 | - name: Prepare parameters
41 | run: |
42 | git log --pretty=format:"%H - %an, %aI : %s" -5
43 | mkdir -p ~/.gradle
44 | echo "GITHUB_TOKEN=${{secrets.PACKAGES_TOKEN}}" > ~/.gradle/gradle.properties
45 | echo "GITHUB_USERNAME=Robothy" >> ~/.gradle/gradle.properties
46 | echo "signing.secretKey=${{ secrets.SING_SECRET_KEY }}" >> ~/.gradle/gradle.properties
47 | echo "signing.password=${{ secrets.SING_PASSWORD }}" >> ~/.gradle/gradle.properties
48 | echo "OSSRH_USERNAME=${{ secrets.OSSRH_USERNAME }}" >> ~/.gradle/gradle.properties
49 | echo "OSSRH_PASSWORD=${{ secrets.OSSRH_PASSWORD }}" >> ~/.gradle/gradle.properties
50 | chmod +x gradlew
51 | pwd
52 | ls -l
53 |
54 | - name: Update release version
55 | run: |
56 | ./gradlew releaseVersion
57 |
58 | - name: Publish
59 | if: ${{inputs.gradleLogLevel == 'None'}}
60 | run: |
61 | ./gradlew check release
62 |
63 | - name: Publish(Info)
64 | if: ${{inputs.gradleLogLevel == 'Info'}}
65 | run: .|
66 | ./gradlew check release --info
67 |
68 | - name: Publish(Warn)
69 | if: ${{inputs.gradleLogLevel == 'Warn'}}
70 | run: .|
71 | ./gradlew check release --warn
72 |
73 | - name: Publish(Debug)
74 | if: ${{inputs.gradleLogLevel == 'Debug'}}
75 | run: |
76 | ./gradlew check release --debug
77 |
78 | - name: Publish(Stacktrace)
79 | if: ${{inputs.gradleLogLevel == 'Stacktrace'}}
80 | run: |
81 | ./gradlew check release --stacktrace
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 | !**/src/main/**/build/
5 | !**/src/test/**/build/
6 |
7 | ### IntelliJ IDEA ###
8 | .idea
9 | *.iws
10 | *.iml
11 | *.ipr
12 | out/
13 | !**/src/main/**/out/
14 | !**/src/test/**/out/
15 |
16 | ### Eclipse ###
17 | .apt_generated
18 | .classpath
19 | .factorypath
20 | .project
21 | .settings
22 | .springBeans
23 | .sts4-cache
24 | bin/
25 | !**/src/main/**/bin/
26 | !**/src/test/**/bin/
27 |
28 | ### NetBeans ###
29 | /nbproject/private/
30 | /nbbuild/
31 | /dist/
32 | /nbdist/
33 | /.nb-gradle/
34 |
35 | ### VS Code ###
36 | .vscode/
37 |
38 | ### Mac OS ###
39 | .DS_Store
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Stable Diffusion Webui Java SDK
2 |
3 | [](https://github.com/Robothy/sdwebui-java-sdk/actions/workflows/build.yml)
4 | [](https://github.com/robothy/sdwebui-java-sdk/blob/main/LICENSE)
5 | [](https://search.maven.org/artifact/io.github.robothy/sdwebui-java-sdk/)
6 |
7 | sdwebui-java-sdk is a Java library for building Java applications that integrate with [Stable Diffusion Webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui).
8 |
9 | ## Usage
10 |
11 | ### Add Denendencies
12 |
13 | Maven
14 |
15 | ```
16 |
17 | io.github.robothy
18 | sdwebui-java-sdk
19 | ${latest-version}
20 |
21 | ```
22 |
23 | Gradle
24 | ```
25 | implementation "io.github.robothy:sdwebui-java-sdk:${latest-version}"
26 | ```
27 |
28 | ### Create `SdWebui` instance
29 |
30 | ```java
31 | SdWebui sd = SdWebui.create("http://localhost:7860");
32 | ```
33 |
34 | ### Text to Image
35 |
36 | ```java
37 | Txt2ImgResult txt2ImgResult = sd.txt2Img(Txt2ImageOptions.builder()
38 | .prompt("1dog")
39 | .samplerName("DPM++ 2M Karras")
40 | .steps(20)
41 | .cfgScale(7)
42 | .seed(32749528)
43 | .build());
44 |
45 | Path step1Path = Paths.get("docs/images/txt2img-dog.png");
46 | Files.write(step1Path, Base64.getDecoder().decode(txt2ImgResult.getImages().get(0)));
47 | ```
48 |
49 | 
50 |
51 | ### Image to Image
52 |
53 | ```java
54 | Image2ImageResult image2ImageResult = sd.img2img(Image2ImageOptions.builder()
55 | .prompt("1dog, glass")
56 | .negativePrompt("bad fingers")
57 | .samplerName("DPM++ 2M Karras")
58 | .seed(32749528)
59 | .cfgScale(7)
60 | .denoisingStrength(0.3)
61 | .initImages(List.of(txt2ImgResult.getImages().get(0)))
62 | .build());
63 |
64 |
65 | String base64img = image2ImageResult.getImages().get(0);
66 |
67 | Path filepath = Paths.get("docs/images/img2img-dog.png");
68 | Files.write(filepath, Base64.getDecoder().decode(base64img));
69 | ```
70 |
71 | 
72 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import java.nio.file.Files
2 |
3 | plugins {
4 | `java-library`
5 | jacoco
6 | `maven-publish`
7 | id("io.franzbecker.gradle-lombok") version "5.0.0"
8 | id("com.robothy.github-repository-release-plugin") version "1.1"
9 | signing
10 | // id 'com.robothy.cn-repo' version '1.8'
11 | }
12 |
13 |
14 | group = "io.github.robothy"
15 |
16 | repositories {
17 | mavenLocal()
18 | mavenCentral()
19 | }
20 |
21 | val jacksonVersion = "2.15.2"
22 | val apacheHttpClient5Version = "5.2.1"
23 | val junitVersion = "5.9.1"
24 | val lombokVersion = "1.18.30"
25 | val mockServerVersion = "5.14.0"
26 |
27 |
28 | dependencies {
29 | implementation("org.apache.httpcomponents.client5:httpclient5:${apacheHttpClient5Version}")
30 | implementation("com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}")
31 | implementation("com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}")
32 | implementation("com.fasterxml.jackson.core:jackson-core:${jacksonVersion}")
33 | runtimeOnly("com.fasterxml.jackson.module:jackson-modules-java8:${jacksonVersion}")
34 |
35 | // lombok
36 | implementation("org.projectlombok:lombok:${lombokVersion}")
37 | annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
38 | testAnnotationProcessor("org.projectlombok:lombok:${lombokVersion}")
39 | testImplementation("org.projectlombok:lombok:${lombokVersion}")
40 |
41 | testImplementation("org.mock-server:mockserver-junit-jupiter-no-dependencies:${mockServerVersion}")
42 | testImplementation(platform("org.junit:junit-bom:${junitVersion}"))
43 | testImplementation("org.junit.jupiter:junit-jupiter")
44 | testImplementation("org.junit.jupiter:junit-jupiter-api")
45 | }
46 |
47 | java {
48 | withSourcesJar()
49 | withJavadocJar()
50 | sourceCompatibility = JavaVersion.VERSION_1_8
51 | targetCompatibility = JavaVersion.VERSION_1_8
52 | }
53 |
54 | tasks.compileJava {
55 | options.encoding = "UTF-8"
56 | }
57 |
58 | tasks.compileTestJava {
59 | options.encoding = "UTF-8"
60 | }
61 |
62 | tasks.test {
63 | useJUnitPlatform()
64 | }
65 |
66 | tasks.register("mergeReports") {
67 | group = "verification"
68 |
69 | executionData.from(project.fileTree(".") {
70 | include("**/build/jacoco/*.exec")
71 | })
72 |
73 | // kotlin source
74 | sourceDirectories.from(project.fileTree(".") {
75 | include("**/src/main/java/**")
76 | })
77 |
78 | classDirectories.from(project.fileTree(".") {
79 | include("**/build/classes/kotlin/main/**")
80 | })
81 |
82 | reports {
83 | xml.required.set(true)
84 | html.required.set(true)
85 | //csv.required.set(true)
86 | }
87 | }
88 |
89 | tasks.getByName("mergeReports").dependsOn("test")
90 |
91 |
92 |
93 | publishing {
94 |
95 | publications {
96 | create("maven") {
97 | groupId = project.group.toString()
98 | artifactId = project.name
99 | from(components["java"]).apply {
100 | pom {
101 | name = "sdwebui-java-sdk"
102 | description = "Stable Diffusion Web UI Java SDK"
103 | url = "https://github.com/Robothy/sdwebui-java-sdk"
104 |
105 | licenses {
106 | license {
107 | name = "The Apache License, Version 2.0"
108 | url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
109 | }
110 | }
111 |
112 | developers {
113 | developer {
114 | id = "robothy"
115 | name = "Fuxiang Luo"
116 | email = "robothyluo@gmail.com"
117 | }
118 | }
119 |
120 | scm {
121 | url = "https://github.com/Robothy/sdwebui-java-sdk.git"
122 | }
123 |
124 | }
125 | }
126 |
127 | }
128 | }
129 |
130 | repositories {
131 | mavenLocal()
132 |
133 | repositories {
134 | mavenLocal()
135 | maven {
136 | name = "GitHubPackages"
137 | url = uri("https://maven.pkg.github.com/Robothy/sdwebui-java-sdk")
138 | credentials {
139 | username = (project.findProperty("GITHUB_USERNAME") ?: System.getenv("GITHUB_USERNAME")).toString()
140 | password = (project.findProperty("GITHUB_TOKEN") ?: System.getenv("GITHUB_TOKEN")).toString()
141 | }
142 | }
143 |
144 | maven {
145 | name = "MavenCentral"
146 | url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
147 | credentials {
148 | username = findProperty("OSSRH_USERNAME").toString()
149 | password = findProperty("OSSRH_PASSWORD").toString()
150 | }
151 | }
152 |
153 | }
154 | }
155 | }
156 |
157 | signing {
158 | val signingKey = findProperty("signing.secretKeyRingFile")?.
159 | let { Files.readString(file(it).toPath()) } ?:
160 | findProperty("signing.secretKey").toString()
161 |
162 | val signingPassword = findProperty("signing.password").toString()
163 | useInMemoryPgpKeys(signingKey, signingPassword)
164 | sign(publishing.publications["maven"])
165 | }
--------------------------------------------------------------------------------
/docs/images/img2img-dog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robothy/sdwebui-java-sdk/643ffde5f10b65cb6b50e20e1d98f54aa22268a4/docs/images/img2img-dog.png
--------------------------------------------------------------------------------
/docs/images/txt2img-dog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robothy/sdwebui-java-sdk/643ffde5f10b65cb6b50e20e1d98f54aa22268a4/docs/images/txt2img-dog.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | version=1.3-SNAPSHOT
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robothy/sdwebui-java-sdk/643ffde5f10b65cb6b50e20e1d98f54aa22268a4/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Oct 07 21:45:57 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Use "xargs" to parse quoted args.
209 | #
210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
211 | #
212 | # In Bash we could simply go:
213 | #
214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
215 | # set -- "${ARGS[@]}" "$@"
216 | #
217 | # but POSIX shell has neither arrays nor command substitution, so instead we
218 | # post-process each arg (as a line of input to sed) to backslash-escape any
219 | # character that might be a shell metacharacter, then use eval to reverse
220 | # that process (while maintaining the separation between arguments), and wrap
221 | # the whole thing up as a single "set" statement.
222 | #
223 | # This will of course break if any of these variables contains a newline or
224 | # an unmatched quote.
225 | #
226 |
227 | eval "set -- $(
228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
229 | xargs -n1 |
230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
231 | tr '\n' ' '
232 | )" '"$@"'
233 |
234 | exec "$JAVACMD" "$@"
235 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | gradlePluginPortal()
5 | }
6 | }
7 |
8 | rootProject.name = "sdwebui-java-sdk"
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/ExtraImage.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 |
4 | import io.github.robothy.sdwebui.sdk.models.options.ExtraImageOptions;
5 | import io.github.robothy.sdwebui.sdk.models.results.ExtraImageResult;
6 |
7 | public interface ExtraImage {
8 |
9 | ExtraImageResult extraImage(ExtraImageOptions options);
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/GetFaceRestorers.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.results.FaceRestorer;
4 |
5 | import java.util.List;
6 |
7 | public interface GetFaceRestorers {
8 |
9 | List getFaceRestorers();
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/GetSdModels.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.results.SdModel;
4 |
5 | import java.util.List;
6 |
7 | public interface GetSdModels {
8 |
9 | List getSdModels();
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/Image2Image.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.options.Image2ImageOptions;
4 | import io.github.robothy.sdwebui.sdk.models.results.Image2ImageResult;
5 |
6 | public interface Image2Image {
7 |
8 | Image2ImageResult img2img(Image2ImageOptions options);
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/Main.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.options.Image2ImageOptions;
4 | import io.github.robothy.sdwebui.sdk.models.options.Txt2ImageOptions;
5 | import io.github.robothy.sdwebui.sdk.models.results.Image2ImageResult;
6 | import io.github.robothy.sdwebui.sdk.models.results.Txt2ImgResult;
7 |
8 | import java.io.IOException;
9 | import java.nio.file.Files;
10 | import java.nio.file.Path;
11 | import java.nio.file.Paths;
12 | import java.util.Base64;
13 | import java.util.List;
14 |
15 | public class Main {
16 |
17 | public static void main(String[] args) throws IOException {
18 | // SdWebui sd = SdWebui.create("http://localhost:7860");
19 | //
20 | // Txt2ImgResult txt2ImgResult = sd.txt2Img(Txt2ImageOptions.builder()
21 | // .prompt("1dog")
22 | // .samplerName("DPM++ 2M Karras")
23 | // .steps(20)
24 | // .cfgScale(7)
25 | // .seed(32749528)
26 | // .build());
27 | //
28 | // Path step1Path = Paths.get("docs/images/txt2img-dog.png");
29 | // Files.write(step1Path, Base64.getDecoder().decode(txt2ImgResult.getImages().get(0)));
30 | //
31 | // Image2ImageResult image2ImageResult = sd.img2img(Image2ImageOptions.builder()
32 | // .prompt("1dog, glass")
33 | // .negativePrompt("bad fingers")
34 | // .samplerName("DPM++ 2M Karras")
35 | // .seed(32749528)
36 | // .cfgScale(7)
37 | // .denoisingStrength(0.3)
38 | // .initImages(List.of(txt2ImgResult.getImages().get(0)))
39 | // .build());
40 | //
41 | //
42 | // String base64img = image2ImageResult.getImages().get(0);
43 | //
44 | // Path filepath = Paths.get("docs/images/img2img-dog.png");
45 | // Files.write(filepath, Base64.getDecoder().decode(base64img));
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/SdWebui.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 |
4 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
5 | import io.github.robothy.sdwebui.sdk.services.SdWebuiInvocationHandler;
6 |
7 | import java.lang.reflect.Proxy;
8 |
9 | public interface SdWebui extends SystemInfoFetcher, Txt2Image, Image2Image, ExtraImage, GetSdModels, GetFaceRestorers {
10 |
11 | static SdWebui create(String endpoint) {
12 | SdWebuiOptions options = new SdWebuiOptions(endpoint);
13 | return (SdWebui) Proxy.newProxyInstance(SdWebui.class.getClassLoader(), new Class[]{SdWebui.class}, new SdWebuiInvocationHandler(options));
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/SdWebuiBeanContainer.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
4 | import io.github.robothy.sdwebui.sdk.services.DefaultSdWebuiBeanContainer;
5 |
6 | public interface SdWebuiBeanContainer {
7 |
8 | static SdWebuiBeanContainer create(SdWebuiOptions options) {
9 | return new DefaultSdWebuiBeanContainer(options);
10 | }
11 |
12 | T getBean(Class serviceClass);
13 |
14 | void register(Class> serviceClass, Object service);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/SdWebuiBeanFactory.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | public interface SdWebuiBeanFactory {
4 |
5 | T getBean(SdWebuiBeanContainer beanContainer);
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/SystemInfoFetcher.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.SystemInfo;
4 |
5 | public interface SystemInfoFetcher {
6 |
7 | SystemInfo systemInfo();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/Txt2Image.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.options.Txt2ImageOptions;
4 | import io.github.robothy.sdwebui.sdk.models.results.Txt2ImgResult;
5 |
6 | public interface Txt2Image {
7 |
8 | /**
9 | * Generate images from text.
10 | *
11 | * @param options The options to generate images.
12 | * @return The result of the generation.
13 | *
14 | * @throws io.github.robothy.sdwebui.sdk.exceptions.SdWebuiServerValidationException
15 | * @throws io.github.robothy.sdwebui.sdk.exceptions.SdWebuiBadRequestException
16 | */
17 | Txt2ImgResult txt2Img(Txt2ImageOptions options);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/enums/HiResUpscaler.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.enums;
2 |
3 | public enum HiResUpscaler {
4 | None("None"),
5 | Latent("Latent"),
6 | LatentAntialiased("Latent (antialiased)"),
7 | LatentBicubic("Latent (bicubic)"),
8 | LatentBicubicAntialiased("Latent (bicubic antialiased)"),
9 | LatentNearest("Latent (nearist)"),
10 | LatentNearestExact("Latent (nearist-exact)"),
11 | Lanczos("Lanczos"),
12 | Nearest("Nearest"),
13 | ESRGAN_4x("ESRGAN_4x"),
14 | LDSR("LDSR"),
15 | ScuNET_GAN("ScuNET GAN"),
16 | ScuNET_PSNR("ScuNET PSNR"),
17 | SwinIR_4x("SwinIR 4x");
18 |
19 | private final String name;
20 |
21 | HiResUpscaler(String name) {
22 | this.name = name;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/enums/Upscaler.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.enums;
2 |
3 | public enum Upscaler {
4 | None("None"),
5 | Lanczos("Lanczos"),
6 | Nearest("Nearest"),
7 | LDSR("LDSR"),
8 | BSRGAN("BSRGAN"),
9 | ESRGAN_4x("ESRGAN_4x"),
10 | R_ESRGAN_General_4xV3("R-ESRGAN General 4xV3"),
11 | ScuNET_GAN("ScuNET GAN"),
12 | ScuNET_PSNR("ScuNET PSNR"),
13 | SwinIR_4x("SwinIR 4x");
14 |
15 | private final String name;
16 |
17 | Upscaler(String name) {
18 | this.name = name;
19 | }
20 |
21 | public String getName() {
22 | return name;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/exceptions/SdWebuiBadRequestException.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.exceptions;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.EqualsAndHashCode;
7 | import lombok.NoArgsConstructor;
8 |
9 | @EqualsAndHashCode(callSuper = true)
10 | @AllArgsConstructor
11 | @NoArgsConstructor
12 | @Data
13 | public class SdWebuiBadRequestException extends SdWebuiServerException {
14 | @JsonProperty("error")
15 | private String error;
16 |
17 | @JsonProperty("detail")
18 | private String detail;
19 |
20 | @JsonProperty("body")
21 | private String body;
22 |
23 | @JsonProperty("errors")
24 | private String errors;
25 |
26 | // getters and setters
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/exceptions/SdWebuiServerException.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.exceptions;
2 |
3 | public class SdWebuiServerException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/exceptions/SdWebuiServerValidationException.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.exceptions;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.EqualsAndHashCode;
7 | import lombok.NoArgsConstructor;
8 |
9 | @EqualsAndHashCode(callSuper = true)
10 | @Data
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class SdWebuiServerValidationException extends SdWebuiServerException {
14 |
15 | @JsonProperty("detail")
16 | private Detail[] detail;
17 |
18 | public Detail[] getDetail() {
19 | return detail;
20 | }
21 |
22 | public void setDetail(Detail[] detail) {
23 | this.detail = detail;
24 | }
25 |
26 | @Data
27 | public static class Detail {
28 |
29 | @JsonProperty("loc")
30 | private String[] loc;
31 |
32 | @JsonProperty("msg")
33 | private String msg;
34 |
35 | @JsonProperty("type")
36 | private String type;
37 |
38 | public String[] getLoc() {
39 | return loc;
40 | }
41 |
42 | public void setLoc(String[] loc) {
43 | this.loc = loc;
44 | }
45 |
46 | public String getMsg() {
47 | return msg;
48 | }
49 |
50 | public void setMsg(String msg) {
51 | this.msg = msg;
52 | }
53 |
54 | public String getType() {
55 | return type;
56 | }
57 |
58 | public void setType(String type) {
59 | this.type = type;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/SdWebuiOptions.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public class SdWebuiOptions {
7 |
8 | private final String endpoint;
9 |
10 | public SdWebuiOptions(String endpoint) {
11 | this.endpoint = endpoint;
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/SystemInfo.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models;
2 |
3 |
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import com.fasterxml.jackson.annotation.JsonProperty;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | @Data
11 | @AllArgsConstructor
12 | @NoArgsConstructor
13 | @JsonIgnoreProperties(ignoreUnknown = true)
14 | public class SystemInfo {
15 |
16 | @JsonProperty("Platform")
17 | private String platform;
18 |
19 | @JsonProperty("Python")
20 | private String pythonVersion;
21 |
22 | @JsonProperty("Version")
23 | private String sdwebuiVersion;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/options/ExtraImageOptions.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.options;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import com.fasterxml.jackson.annotation.JsonInclude;
5 | import com.fasterxml.jackson.annotation.JsonProperty;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | /*
12 | {
13 | "resize_mode": 0,
14 | "show_extras_results": true,
15 | "gfpgan_visibility": 0.07745869113225834,
16 | "codeformer_visibility": 0.47970707311691596,
17 | "codeformer_weight": 0.3154859812234816,
18 | "upscaling_resize": 5.823972728481651,
19 | "upscaling_resize_w": 78222408,
20 | "upscaling_resize_h": 11201482,
21 | "upscaling_crop": false,
22 | "upscaler_1": "sed ipsum anim proident dolor",
23 | "upscaler_2": "proident occaecat",
24 | "extras_upscaler_2_visibility": 0.6957613714482722,
25 | "upscale_first": true,
26 | "image": "http://dummyimage.com/400x400"
27 | }
28 | */
29 | @Data
30 | @AllArgsConstructor
31 | @NoArgsConstructor
32 | @Builder
33 | @JsonIgnoreProperties(ignoreUnknown = true)
34 | @JsonInclude(JsonInclude.Include.NON_NULL)
35 | public class ExtraImageOptions {
36 | /**
37 | * CodeFormer Visibility,Sets the visibility of CodeFormer, values should be between 0 and 1.
38 | */
39 | @Builder.Default
40 | @JsonProperty("codeformer_visibility")
41 | private Double codeformerVisibility = 0.0;
42 | /**
43 | * CodeFormer Weight,Sets the weight of CodeFormer, values should be between 0 and 1.
44 | */
45 | @Builder.Default
46 | @JsonProperty("codeformer_weight")
47 | private Double codeformerWeight = 0.0;
48 | /**
49 | * Secondary upscaler visibility,Sets the visibility of secondary upscaler, values should be
50 | * between 0 and 1.
51 | */
52 | @Builder.Default
53 | @JsonProperty("extras_upscaler_2_visibility")
54 | private Double extrasUpscaler2Visibility = 0.0;
55 | /**
56 | * GFPGAN Visibility,Sets the visibility of GFPGAN, values should be between 0 and 1.
57 | */
58 | @Builder.Default
59 | @JsonProperty("gfpgan_visibility")
60 | private Double gfpganVisibility = 0.0;
61 | /**
62 | * Image,Image to work on, must be a Base64 string containing the image's data.
63 | */
64 | @Builder.Default
65 | @JsonProperty("image")
66 | private String image = null;
67 | /**
68 | * Resize Mode,Sets the resize mode: 0 to upscale by upscaling_resize amount, 1 to upscale
69 | * up to upscaling_resize_h x upscaling_resize_w.
70 | */
71 | @Builder.Default
72 | @JsonProperty("resize_mode")
73 | private Long resizeMode = 0L;
74 | /**
75 | * Show results,Should the backend return the generated image?
76 | */
77 | @Builder.Default
78 | @JsonProperty("show_results")
79 | private Boolean showExtrasResults = false;
80 | /**
81 | * Upscale first,Should the upscaler run before restoring faces?
82 | */
83 | @Builder.Default
84 | @JsonProperty("upscale_first")
85 | private Boolean upscaleFirst = false;
86 | /**
87 | * Main upscaler,The name of the main upscaler to use, it has to be one of this list:
88 | */
89 | @Builder.Default
90 | @JsonProperty("upscaler_1")
91 | private String upscaler1 = "";
92 | /**
93 | * Secondary upscaler,The name of the secondary upscaler to use, it has to be one of this
94 | * list:
95 | */
96 | @Builder.Default
97 | @JsonProperty("upscaler_2")
98 | private String upscaler2 = "";
99 | /**
100 | * Crop to fit,Should the upscaler crop the image to fit in the chosen size?
101 | */
102 | @Builder.Default
103 | @JsonProperty("upscaling_crop")
104 | private Boolean upscalingCrop = false;
105 | /**
106 | * Upscaling Factor,By how much to upscale the image, only used when resize_mode=0.
107 | */
108 | @Builder.Default
109 | @JsonProperty("upscaling_resize")
110 | private Double upscalingResize = 0.0;
111 | /**
112 | * Target Height,Target height for the upscaler to hit. Only used when resize_mode=1.
113 | */
114 | @Builder.Default
115 | @JsonProperty("upscaling_resize_h")
116 | private Long upscalingResizeH = 512L;
117 | /**
118 | * Target Width,Target width for the upscaler to hit. Only used when resize_mode=1.
119 | */
120 | @Builder.Default
121 | @JsonProperty("upscaling_resize_w")
122 | private Long upscalingResizeW = 512L;
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/options/Image2ImageOptions.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.options;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.*;
5 | import lombok.Builder.Default;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | @Data
15 | @Builder
16 | public class Image2ImageOptions {
17 |
18 | @JsonProperty("prompt")
19 | @Default
20 | private String prompt = "";
21 |
22 | @JsonProperty("negative_prompt")
23 | @Default
24 | private String negativePrompt = "";
25 |
26 | @JsonProperty("styles")
27 | @Default
28 | private List styles = new ArrayList<>();
29 |
30 | @JsonProperty("seed")
31 | @Default
32 | private int seed = -1;
33 |
34 | @JsonProperty("subseed")
35 | @Default
36 | private int subseed = -1;
37 |
38 | @JsonProperty("subseed_strength")
39 | @Default
40 | private int subseedStrength = 0;
41 |
42 | @JsonProperty("seed_resize_from_h")
43 | @Default
44 | private int seedResizeFromH = -1;
45 |
46 | @JsonProperty("seed_resize_from_w")
47 | @Default
48 | private int seedResizeFromW = -1;
49 |
50 | @JsonProperty("sampler_name")
51 | @Default
52 | private String samplerName = "string";
53 |
54 | @JsonProperty("batch_size")
55 | @Default
56 | private int batchSize = 1;
57 |
58 | @JsonProperty("n_iter")
59 | @Default
60 | private int nIter = 1;
61 |
62 | @JsonProperty("steps")
63 | @Default
64 | private int steps = 50;
65 |
66 | @JsonProperty("cfg_scale")
67 | @Default
68 | private double cfgScale = 7;
69 |
70 | @JsonProperty("width")
71 | @Default
72 | private int width = 512;
73 |
74 | @JsonProperty("height")
75 | @Default
76 | private int height = 512;
77 |
78 | @JsonProperty("restore_faces")
79 | @Default
80 | private boolean restoreFaces = true;
81 |
82 | @JsonProperty("tiling")
83 | @Default
84 | private boolean tiling = true;
85 |
86 | @JsonProperty("do_not_save_samples")
87 | @Default
88 | private boolean doNotSaveSamples = false;
89 |
90 | @JsonProperty("do_not_save_grid")
91 | @Default
92 | private boolean doNotSaveGrid = false;
93 |
94 | @JsonProperty("eta")
95 | @Default
96 | private int eta = 0;
97 |
98 | @JsonProperty("denoising_strength")
99 | @Default
100 | private double denoisingStrength = 0.75;
101 |
102 | @JsonProperty("s_min_uncond")
103 | @Default
104 | private int sMinUncond = 0;
105 |
106 | @JsonProperty("s_churn")
107 | @Default
108 | private int sChurn = 0;
109 |
110 | @JsonProperty("s_tmax")
111 | @Default
112 | private int sTmax = 0;
113 |
114 | @JsonProperty("s_tmin")
115 | @Default
116 | private int sTmin = 0;
117 |
118 | @JsonProperty("s_noise")
119 | @Default
120 | private int sNoise = 0;
121 |
122 | @JsonProperty("override_settings")
123 | @Default
124 | private Map overrideSettings = Collections.emptyMap();
125 |
126 | @JsonProperty("override_settings_restore_afterwards")
127 | @Default
128 | private boolean overrideSettingsRestoreAfterwards = false;
129 |
130 | @JsonProperty("refiner_checkpoint")
131 | @Default
132 | private String refinerCheckpoint = "";
133 |
134 | @JsonProperty("refiner_switch_at")
135 | @Default
136 | private int refinerSwitchAt = 0;
137 |
138 | @JsonProperty("disable_extra_networks")
139 | @Default
140 | private boolean disableExtraNetworks = false;
141 |
142 | @JsonProperty("comments")
143 | @Default
144 | private Map comments = Collections.emptyMap();
145 |
146 | @JsonProperty("init_images")
147 | @Default
148 | private List initImages = new ArrayList<>();
149 |
150 | @JsonProperty("resize_mode")
151 | @Default
152 | private int resizeMode = 0;
153 |
154 | @JsonProperty("image_cfg_scale")
155 | @Default
156 | private int imageCfgScale = 0;
157 |
158 | @JsonProperty("mask")
159 | private String mask;
160 |
161 | @JsonProperty("mask_blur_x")
162 | @Default
163 | private int maskBlurX = 0;
164 |
165 | @JsonProperty("mask_blur_y")
166 | @Default
167 | private int maskBlurY = 0;
168 |
169 | @JsonProperty("mask_blur")
170 | @Default
171 | private int maskBlur = 0;
172 |
173 | @JsonProperty("inpainting_fill")
174 | @Default
175 | private int inpaintingFill = 0;
176 |
177 | @JsonProperty("inpaint_full_res")
178 | @Default
179 | private boolean inpaintFullRes = false;
180 |
181 | @JsonProperty("inpaint_full_res_padding")
182 | @Default
183 | private int inpaintingFullResPadding = 0;
184 |
185 | @JsonProperty("inpainting_mask_invert")
186 | @Default
187 | private int inpaintingMaskInvert = 0;
188 |
189 | @JsonProperty("initial_noise_multiplier")
190 | @Default
191 | private int initialNoiseMultiplier = 0;
192 |
193 | @JsonProperty("latent_mask")
194 | @Default
195 | private String latentMask = "";
196 |
197 | @JsonProperty("sampler_index")
198 | @Default
199 | @Deprecated
200 | private String samplerIndex = "";
201 |
202 | @JsonProperty("include_init_images")
203 | @Default
204 | private boolean includeInitImages = false;
205 |
206 | @JsonProperty("script_name")
207 | @Default
208 | private String scriptName = "";
209 |
210 | @JsonProperty("script_args")
211 | @Default
212 | private String[] scriptArgs = new String[]{};
213 |
214 | @JsonProperty("send_images")
215 | @Default
216 | private boolean sendImages = true;
217 |
218 | @JsonProperty("save_images")
219 | @Default
220 | private boolean saveImages = false;
221 |
222 | @JsonProperty("alwayson_scripts")
223 | @Default
224 | private Map alwaysonScripts = Collections.emptyMap();
225 |
226 | }
227 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/options/Txt2ImageOptions.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.options;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import com.fasterxml.jackson.annotation.JsonInclude;
5 | import com.fasterxml.jackson.annotation.JsonProperty;
6 | import io.github.robothy.sdwebui.sdk.enums.HiResUpscaler;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import lombok.AllArgsConstructor;
10 | import lombok.Builder;
11 | import lombok.Data;
12 | import lombok.NoArgsConstructor;
13 |
14 | import java.util.Map;
15 |
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | @JsonIgnoreProperties(ignoreUnknown = true)
21 | @JsonInclude(JsonInclude.Include.NON_NULL)
22 | public class Txt2ImageOptions {
23 |
24 |
25 | @Builder.Default
26 | @JsonProperty("enable_hr")
27 | private boolean enableHr = false;
28 |
29 | @Builder.Default
30 | @JsonProperty("denoising_strength")
31 | private double denoisingStrength = 0.7;
32 |
33 | @Builder.Default
34 | @JsonProperty("firstphase_width")
35 | private int firstphaseWidth = 0;
36 |
37 | @Builder.Default
38 | @JsonProperty("firstphase_height")
39 | private int firstphaseHeight = 0;
40 |
41 | @Builder.Default
42 | @JsonProperty("hr_scale")
43 | private int hrScale = 2;
44 |
45 | @Builder.Default
46 | @JsonProperty("hr_upscaler")
47 | private HiResUpscaler hrUpscaler = HiResUpscaler.Latent;
48 |
49 | @Builder.Default
50 | @JsonProperty("hr_second_pass_steps")
51 | private int hrSecondPassSteps = 0;
52 |
53 | @Builder.Default
54 | @JsonProperty("hr_resize_x")
55 | private int hrResizeX = 0;
56 |
57 | @Builder.Default
58 | @JsonProperty("hr_resize_y")
59 | private int hrResizeY = 0;
60 |
61 | @Builder.Default
62 | @JsonProperty("prompt")
63 | private String prompt = "";
64 |
65 | @Builder.Default
66 | @JsonProperty("styles")
67 | private List styles = new ArrayList<>();
68 |
69 | @Builder.Default
70 | @JsonProperty("seed")
71 | private long seed = -1L;
72 |
73 | @Builder.Default
74 | @JsonProperty("subseed")
75 | private long subseed = -1L;
76 |
77 | @Builder.Default
78 | @JsonProperty("subseed_strength")
79 | private double subseedStrength = 0.0;
80 |
81 | @Builder.Default
82 | @JsonProperty("seed_resize_from_h")
83 | private int seedResizeFromH = 0;
84 |
85 | @Builder.Default
86 | @JsonProperty("seed_resize_from_w")
87 | private int seedResizeFromW = 0;
88 |
89 | @Builder.Default
90 | @JsonProperty("sampler_name")
91 | private String samplerName = "DPM++ 2M Karras";
92 |
93 | @Builder.Default
94 | @JsonProperty("batch_size")
95 | private int batchSize = 1;
96 |
97 | @Builder.Default
98 | @JsonProperty("n_iter")
99 | private int nIter = 1;
100 |
101 | @Builder.Default
102 | @JsonProperty("steps")
103 | private Integer steps = null;
104 |
105 | @Builder.Default
106 | @JsonProperty("cfg_scale")
107 | private double cfgScale = 7.0;
108 |
109 | @Builder.Default
110 | @JsonProperty("width")
111 | private int width = 512;
112 |
113 | @Builder.Default
114 | @JsonProperty("height")
115 | private int height = 512;
116 |
117 | @Builder.Default
118 | @JsonProperty("restore_faces")
119 | private boolean restoreFaces = false;
120 |
121 | @Builder.Default
122 | @JsonProperty("tiling")
123 | private boolean tiling = false;
124 |
125 | @Builder.Default
126 | @JsonProperty("do_not_save_samples")
127 | private boolean doNotSaveSamples = false;
128 |
129 | @Builder.Default
130 | @JsonProperty("do_not_save_grid")
131 | private boolean doNotSaveGrid = false;
132 |
133 | @Builder.Default
134 | @JsonProperty("negative_prompt")
135 | private String negativePrompt = "";
136 |
137 | @Builder.Default
138 | @JsonProperty("eta")
139 | private double eta = 1.0;
140 |
141 | @Builder.Default
142 | @JsonProperty("s_churn")
143 | private int sChurn = 0;
144 |
145 | @Builder.Default
146 | @JsonProperty("s_tmax")
147 | private int sTmax = 0;
148 |
149 | @Builder.Default
150 | @JsonProperty("s_tmin")
151 | private int sTmin = 0;
152 |
153 | @Builder.Default
154 | @JsonProperty("s_noise")
155 | private int sNoise = 1;
156 |
157 | @Builder.Default
158 | @JsonProperty("override_settings")
159 | private Map overrideSettings = null;
160 |
161 | @Builder.Default
162 | @JsonProperty("override_settings_restore_afterwards")
163 | private boolean overrideSettingsRestoreAfterwards = true;
164 |
165 | @Builder.Default
166 | @JsonProperty("script_args")
167 | private List scriptArgs = new ArrayList<>();
168 |
169 | @Builder.Default
170 | @JsonProperty("script_name")
171 | private String scriptName = null;
172 |
173 | @Builder.Default
174 | @JsonProperty("send_images")
175 | private boolean sendImages = true;
176 |
177 | @Builder.Default
178 | @JsonProperty("save_images")
179 | private boolean saveImages = false;
180 |
181 | @Builder.Default
182 | @JsonProperty("alwayson_scripts")
183 | private Map alwaysonScripts = null;
184 |
185 | @Builder.Default
186 | @JsonProperty("sampler_index")
187 | @Deprecated
188 | private String samplerIndex = null;
189 |
190 | @Builder.Default
191 | @JsonProperty("use_deprecated_controlnet")
192 | private boolean useDeprecatedControlnet = false;
193 |
194 | }
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/results/ExtraImageResult.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.Data;
5 |
6 | @Data
7 | public class ExtraImageResult {
8 | /**
9 | * HTML info,A series of HTML tags containing the process info.
10 | */
11 | @JsonProperty("html_info")
12 | private String htmlInfo;
13 | /**
14 | * Image,The generated image in base64 format.
15 | */
16 | @JsonProperty("image")
17 | private String image;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/results/FaceRestorer.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public class FaceRestorer {
8 |
9 | @JsonProperty("name")
10 | private String name;
11 |
12 | @JsonProperty("cmd_dir")
13 | private String cmdDir;
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/results/Image2ImageResult.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import io.github.robothy.sdwebui.sdk.models.options.Image2ImageOptions;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | @Data
11 | @NoArgsConstructor
12 | public class Image2ImageResult {
13 |
14 | @JsonProperty("images")
15 | private List images;
16 |
17 | @JsonProperty("parameters")
18 | private Image2ImageOptions parameters;
19 |
20 | @JsonProperty("info")
21 | private String info;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/results/SdModel.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public class SdModel {
8 |
9 | @JsonProperty("title")
10 | private String title;
11 |
12 | @JsonProperty("model_name")
13 | private String modelName;
14 |
15 | @JsonProperty("hash")
16 | private String hash;
17 |
18 | @JsonProperty("sha256")
19 | private String sha256;
20 |
21 | @JsonProperty("filename")
22 | private String filename;
23 |
24 | @JsonProperty("config")
25 | private String config;
26 |
27 | }
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/models/results/Txt2ImgResult.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import io.github.robothy.sdwebui.sdk.models.options.Txt2ImageOptions;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.util.List;
10 |
11 | @Data
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class Txt2ImgResult {
15 |
16 | @JsonProperty("images")
17 | private List images;
18 |
19 | @JsonProperty("parameters")
20 | private Txt2ImageOptions parameters;
21 |
22 | @JsonProperty("info")
23 | private String info;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/CacheableSystemInfoFetcher.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
5 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanFactory;
6 | import io.github.robothy.sdwebui.sdk.SystemInfoFetcher;
7 | import io.github.robothy.sdwebui.sdk.models.SystemInfo;
8 | import org.apache.hc.client5.http.classic.HttpClient;
9 | import org.apache.hc.client5.http.classic.methods.HttpGet;
10 | import org.apache.hc.core5.http.ClassicHttpResponse;
11 |
12 | import java.io.IOException;
13 |
14 | public class CacheableSystemInfoFetcher implements SystemInfoFetcher, SdWebuiBeanFactory {
15 |
16 | private static final String PATH = "/internal/sysinfo";
17 |
18 | private volatile SystemInfo cachedSystemInfo;
19 |
20 | private final String endpoint;
21 |
22 | private final SdWebuiBeanContainer serviceContainer;
23 |
24 | public CacheableSystemInfoFetcher(String endpoint, SdWebuiBeanContainer serviceContainer) {
25 | this.endpoint = endpoint;
26 | this.serviceContainer = serviceContainer;
27 | }
28 |
29 | @Override
30 | public SystemInfo systemInfo() {
31 | fetchSystemInfoIfAbsent();
32 | return cachedSystemInfo;
33 | }
34 |
35 | @Override
36 | public SystemInfo getBean(SdWebuiBeanContainer beanContainer) {
37 | return systemInfo();
38 | }
39 |
40 | void fetchSystemInfoIfAbsent() {
41 | if (cachedSystemInfo == null) {
42 | synchronized (this) {
43 | if (cachedSystemInfo == null) {
44 | cachedSystemInfo = fetchSystemInfo();
45 | }
46 | }
47 | }
48 | }
49 |
50 | SystemInfo fetchSystemInfo() {
51 | try {
52 | return this.serviceContainer.getBean(HttpClient.class)
53 | .execute(new HttpGet(endpoint + PATH), this::parseSystemInfo);
54 | } catch (IOException e) {
55 | throw new RuntimeException(e);
56 | }
57 | }
58 |
59 | SystemInfo parseSystemInfo(ClassicHttpResponse response) {
60 | try {
61 | return this.serviceContainer.getBean(ObjectMapper.class).readValue(response.getEntity().getContent(), SystemInfo.class);
62 | } catch (IOException e) {
63 | throw new RuntimeException(e);
64 | }
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/CommonGetService.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
4 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
5 | import io.github.robothy.sdwebui.sdk.utils.SdWebuiResponseUtils;
6 | import java.io.IOException;
7 | import org.apache.hc.client5.http.classic.HttpClient;
8 | import org.apache.hc.client5.http.classic.methods.HttpGet;
9 |
10 | final class CommonGetService {
11 |
12 | private final SdWebuiBeanContainer container;
13 |
14 | public CommonGetService(SdWebuiBeanContainer container) {
15 | this.container = container;
16 | }
17 |
18 | public T getData(String path, Class clazz) {
19 | HttpClient client = this.container.getBean(HttpClient.class);
20 | SdWebuiOptions sdWebuiOptions = this.container.getBean(SdWebuiOptions.class);
21 | try {
22 | return client.execute(new HttpGet(sdWebuiOptions.getEndpoint() + path),
23 | response -> SdWebuiResponseUtils.parseResponse(response, clazz));
24 | } catch (IOException e) {
25 | throw new RuntimeException(e);
26 | }
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/DefaultExtraImageService.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import io.github.robothy.sdwebui.sdk.ExtraImage;
6 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
7 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
8 | import io.github.robothy.sdwebui.sdk.models.options.ExtraImageOptions;
9 | import io.github.robothy.sdwebui.sdk.models.results.ExtraImageResult;
10 | import io.github.robothy.sdwebui.sdk.utils.SdWebuiResponseUtils;
11 | import org.apache.hc.client5.http.classic.HttpClient;
12 | import org.apache.hc.client5.http.classic.methods.HttpPost;
13 | import org.apache.hc.core5.http.ClassicHttpRequest;
14 | import org.apache.hc.core5.http.ClassicHttpResponse;
15 | import org.apache.hc.core5.http.HttpEntity;
16 | import org.apache.hc.core5.http.io.entity.StringEntity;
17 |
18 | import java.io.IOException;
19 | import java.nio.charset.StandardCharsets;
20 |
21 | public class DefaultExtraImageService implements ExtraImage {
22 |
23 | private static final String ExtraImage_PATH = "/sdapi/v1/extra-single-image";
24 |
25 | private final SdWebuiBeanContainer beanContainer;
26 |
27 | public DefaultExtraImageService(SdWebuiBeanContainer beanContainer) {
28 | this.beanContainer = beanContainer;
29 | }
30 |
31 | @Override
32 | public ExtraImageResult extraImage(ExtraImageOptions options) {
33 | HttpClient httpClient = this.beanContainer.getBean(HttpClient.class);
34 | ClassicHttpRequest extraImageRequest = buildTxt2ImageRequest(options);
35 | try {
36 | return httpClient.execute(extraImageRequest, this::parseExtraImageResult);
37 | } catch (Exception e) {
38 | throw new RuntimeException(e);
39 | }
40 | }
41 |
42 | ClassicHttpRequest buildTxt2ImageRequest(ExtraImageOptions options) {
43 | SdWebuiOptions sdWebuiOptions = this.beanContainer.getBean(SdWebuiOptions.class);
44 | HttpPost httpPost = new HttpPost(sdWebuiOptions.getEndpoint() + ExtraImage_PATH);
45 | HttpEntity entity = buildExtraImageRequestEntity(options);
46 | httpPost.setEntity(entity);
47 | httpPost.addHeader("Content-Type", "application/json");
48 | return httpPost;
49 | }
50 |
51 | HttpEntity buildExtraImageRequestEntity(ExtraImageOptions options) {
52 | try {
53 | String payload = this.beanContainer.getBean(ObjectMapper.class)
54 | .writeValueAsString(options);
55 | return new StringEntity(payload,StandardCharsets.UTF_8);
56 | } catch (JsonProcessingException e) {
57 | throw new RuntimeException(e);
58 | }
59 | }
60 |
61 | ExtraImageResult parseExtraImageResult(ClassicHttpResponse response) {
62 |
63 | SdWebuiResponseUtils.checkResponseStatus(response);
64 |
65 | try {
66 | return this.beanContainer.getBean(ObjectMapper.class)
67 | .readValue(response.getEntity().getContent(), ExtraImageResult.class);
68 | } catch (IOException e) {
69 | throw new RuntimeException(e);
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/DefaultGetFaceRestorersService.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import io.github.robothy.sdwebui.sdk.GetFaceRestorers;
4 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
5 | import io.github.robothy.sdwebui.sdk.models.results.FaceRestorer;
6 |
7 | import java.util.Arrays;
8 | import java.util.List;
9 |
10 | public class DefaultGetFaceRestorersService implements GetFaceRestorers {
11 |
12 | private final SdWebuiBeanContainer container;
13 |
14 | public DefaultGetFaceRestorersService(SdWebuiBeanContainer container) {
15 | this.container = container;
16 | }
17 |
18 | @Override
19 | public List getFaceRestorers() {
20 | return Arrays.asList(container.getBean(CommonGetService.class).getData("/sdapi/v1/face-restorers", FaceRestorer[].class));
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/DefaultGetSdModelService.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import io.github.robothy.sdwebui.sdk.GetSdModels;
4 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
5 | import io.github.robothy.sdwebui.sdk.models.results.SdModel;
6 |
7 | import java.util.Arrays;
8 | import java.util.List;
9 |
10 | public class DefaultGetSdModelService implements GetSdModels {
11 |
12 | private final SdWebuiBeanContainer container;
13 |
14 | public DefaultGetSdModelService(SdWebuiBeanContainer container) {
15 | this.container = container;
16 | }
17 |
18 | @Override
19 | public List getSdModels() {
20 | return Arrays.asList(this.container.getBean(CommonGetService.class).getData("/sdapi/v1/sd-models", SdModel[].class));
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/DefaultImage2ImageService.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import io.github.robothy.sdwebui.sdk.Image2Image;
4 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
5 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
6 | import io.github.robothy.sdwebui.sdk.models.SystemInfo;
7 | import io.github.robothy.sdwebui.sdk.models.options.Image2ImageOptions;
8 | import io.github.robothy.sdwebui.sdk.models.results.Image2ImageResult;
9 | import io.github.robothy.sdwebui.sdk.utils.JsonUtils;
10 | import io.github.robothy.sdwebui.sdk.utils.SdWebuiResponseUtils;
11 | import org.apache.hc.client5.http.classic.HttpClient;
12 | import org.apache.hc.client5.http.classic.methods.HttpPost;
13 | import org.apache.hc.core5.http.ClassicHttpRequest;
14 | import org.apache.hc.core5.http.ClassicHttpResponse;
15 | import org.apache.hc.core5.http.HttpHeaders;
16 | import org.apache.hc.core5.http.io.entity.StringEntity;
17 |
18 | import java.io.IOException;
19 | import java.nio.charset.StandardCharsets;
20 |
21 | public class DefaultImage2ImageService implements Image2Image {
22 |
23 | private static final String IMG2IMG_PATH = "/sdapi/v1/img2img";
24 |
25 | private final SdWebuiBeanContainer container;
26 |
27 | public DefaultImage2ImageService(SdWebuiBeanContainer container) {
28 | this.container = container;
29 | }
30 |
31 | @Override
32 | public Image2ImageResult img2img(Image2ImageOptions options) {
33 | HttpClient httpClient = container.getBean(HttpClient.class);
34 | try {
35 | return httpClient.execute(buildRequest(options), this::parseResponse);
36 | } catch (IOException e) {
37 | throw new RuntimeException(e);
38 | }
39 | }
40 |
41 | ClassicHttpRequest buildRequest(Image2ImageOptions options) {
42 | String url = container.getBean(SdWebuiOptions.class).getEndpoint() + IMG2IMG_PATH;
43 | ClassicHttpRequest request = new HttpPost(url);
44 | request.setEntity(new StringEntity(JsonUtils.toJson(options), StandardCharsets.UTF_8));
45 | request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");
46 | return request;
47 | }
48 |
49 | Image2ImageResult parseResponse(ClassicHttpResponse response) {
50 | SdWebuiResponseUtils.checkResponseStatus(response);
51 | try {
52 | return JsonUtils.fromJson(response.getEntity().getContent(), Image2ImageResult.class);
53 | } catch (IOException e) {
54 | throw new RuntimeException(e);
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/DefaultSdWebuiBeanContainer.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import io.github.robothy.sdwebui.sdk.*;
5 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
6 | import io.github.robothy.sdwebui.sdk.models.SystemInfo;
7 | import org.apache.hc.client5.http.classic.HttpClient;
8 | import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
9 | import org.apache.hc.client5.http.impl.classic.HttpClients;
10 |
11 | import java.util.HashMap;
12 | import java.util.Map;
13 |
14 | public class DefaultSdWebuiBeanContainer implements SdWebuiBeanContainer {
15 |
16 | private final Map, Object> services;
17 |
18 | private final SdWebuiOptions sdWebuiOptions;
19 |
20 | public DefaultSdWebuiBeanContainer(SdWebuiOptions options) {
21 | this.services = new HashMap<>();
22 | this.sdWebuiOptions = options;
23 | init();
24 | }
25 |
26 | @SuppressWarnings("unchecked")
27 | @Override
28 | public T getBean(Class serviceClass) {
29 | T instance = (T) this.services.get(serviceClass);
30 | if (instance == null) {
31 | throw new RuntimeException("No service or service factory found for " + serviceClass);
32 | }
33 |
34 | if (instance instanceof SdWebuiBeanFactory) {
35 | return ((SdWebuiBeanFactory) instance).getBean(this);
36 | }
37 |
38 | return instance;
39 | }
40 |
41 | @Override
42 | public void register(Class> serviceClass, Object service) {
43 | this.services.put(serviceClass, service);
44 | }
45 |
46 | private void init() {
47 | CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
48 | register(SdWebuiOptions.class, sdWebuiOptions);
49 | register(ObjectMapper.class, new ObjectMapper());
50 | register(HttpClient.class, closeableHttpClient);
51 | register(SystemInfo.class, new CacheableSystemInfoFetcher(sdWebuiOptions.getEndpoint(), this));
52 | register(Txt2Image.class, new DefaultTxt2ImageService(this));
53 | register(Image2Image.class, new DefaultImage2ImageService(this));
54 | register(CommonGetService.class, new CommonGetService(this));
55 | register(GetSdModels.class, new DefaultGetSdModelService(this));
56 | register(GetFaceRestorers.class, new DefaultGetFaceRestorersService(this));
57 | register(ExtraImage.class, new DefaultExtraImageService(this));
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/DefaultTxt2ImageService.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
6 | import io.github.robothy.sdwebui.sdk.Txt2Image;
7 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
8 | import io.github.robothy.sdwebui.sdk.models.SystemInfo;
9 | import io.github.robothy.sdwebui.sdk.models.options.Txt2ImageOptions;
10 | import io.github.robothy.sdwebui.sdk.models.results.Txt2ImgResult;
11 | import io.github.robothy.sdwebui.sdk.utils.SdWebuiResponseUtils;
12 | import org.apache.hc.client5.http.classic.HttpClient;
13 | import org.apache.hc.client5.http.classic.methods.HttpPost;
14 | import org.apache.hc.core5.http.ClassicHttpRequest;
15 | import org.apache.hc.core5.http.ClassicHttpResponse;
16 | import org.apache.hc.core5.http.HttpEntity;
17 | import org.apache.hc.core5.http.io.entity.StringEntity;
18 |
19 | import java.io.IOException;
20 | import java.nio.charset.StandardCharsets;
21 |
22 | public class DefaultTxt2ImageService implements Txt2Image {
23 |
24 | private static final String TXT2IMG_PATH = "/sdapi/v1/txt2img";
25 |
26 | private final SdWebuiBeanContainer beanContainer;
27 |
28 | public DefaultTxt2ImageService(SdWebuiBeanContainer beanContainer) {
29 | this.beanContainer = beanContainer;
30 | }
31 |
32 | @Override
33 | public Txt2ImgResult txt2Img(Txt2ImageOptions options) {
34 | HttpClient httpClient = this.beanContainer.getBean(HttpClient.class);
35 | ClassicHttpRequest txt2ImgRequest = buildTxt2ImageRequest(options);
36 | try {
37 | return httpClient.execute(txt2ImgRequest, this::parseTxt2ImageResult);
38 | } catch (Exception e) {
39 | throw new RuntimeException(e);
40 | }
41 | }
42 |
43 | ClassicHttpRequest buildTxt2ImageRequest(Txt2ImageOptions options) {
44 | SdWebuiOptions sdWebuiOptions = this.beanContainer.getBean(SdWebuiOptions.class);
45 | HttpPost httpPost = new HttpPost(sdWebuiOptions.getEndpoint() + TXT2IMG_PATH);
46 | HttpEntity entity = buildTxt2ImageRequestEntity(options);
47 | httpPost.setEntity(entity);
48 | httpPost.addHeader("Content-Type", "application/json");
49 | return httpPost;
50 | }
51 |
52 | HttpEntity buildTxt2ImageRequestEntity(Txt2ImageOptions options) {
53 | try {
54 | String payload = this.beanContainer.getBean(ObjectMapper.class)
55 | .writeValueAsString(options);
56 | return new StringEntity(payload,StandardCharsets.UTF_8);
57 | } catch (JsonProcessingException e) {
58 | throw new RuntimeException(e);
59 | }
60 | }
61 |
62 | Txt2ImgResult parseTxt2ImageResult(ClassicHttpResponse response) {
63 |
64 | SdWebuiResponseUtils.checkResponseStatus(response);
65 |
66 | try {
67 | return this.beanContainer.getBean(ObjectMapper.class)
68 | .readValue(response.getEntity().getContent(), Txt2ImgResult.class);
69 | } catch (IOException e) {
70 | throw new RuntimeException(e);
71 | }
72 |
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/services/SdWebuiInvocationHandler.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.services;
2 |
3 | import io.github.robothy.sdwebui.sdk.SdWebuiBeanContainer;
4 |
5 | import io.github.robothy.sdwebui.sdk.models.SdWebuiOptions;
6 | import java.lang.reflect.InvocationHandler;
7 | import java.lang.reflect.Method;
8 |
9 | public final class SdWebuiInvocationHandler implements InvocationHandler {
10 |
11 | private final SdWebuiBeanContainer serviceContainer;
12 |
13 | public SdWebuiInvocationHandler(SdWebuiOptions options) {
14 | this.serviceContainer = SdWebuiBeanContainer.create(options);
15 | }
16 |
17 | @Override
18 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
19 | Class> clazz = method.getDeclaringClass();
20 | Object service = serviceContainer.getBean(clazz);
21 | return method.invoke(service, args);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/utils/JsonUtils.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.utils;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 |
9 | public class JsonUtils {
10 |
11 | private static final ObjectMapper objectMapper = new ObjectMapper();
12 |
13 | public static String toJson(Object object) {
14 | try {
15 | return objectMapper.writeValueAsString(object);
16 | } catch (JsonProcessingException e) {
17 | throw new RuntimeException(e);
18 | }
19 | }
20 |
21 | public static T fromJson(String json, Class clazz) {
22 | try {
23 | return objectMapper.readValue(json, clazz);
24 | } catch (JsonProcessingException e) {
25 | throw new RuntimeException(e);
26 | }
27 | }
28 |
29 | public static T fromJson(InputStream inputStream, Class clazz) {
30 | try {
31 | return objectMapper.readValue(inputStream, clazz);
32 | } catch (IOException e) {
33 | throw new RuntimeException(e);
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/github/robothy/sdwebui/sdk/utils/SdWebuiResponseUtils.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.utils;
2 |
3 | import io.github.robothy.sdwebui.sdk.exceptions.SdWebuiBadRequestException;
4 | import io.github.robothy.sdwebui.sdk.exceptions.SdWebuiServerValidationException;
5 | import org.apache.hc.core5.http.ClassicHttpResponse;
6 | import org.apache.hc.core5.http.HttpStatus;
7 |
8 | public class SdWebuiResponseUtils {
9 |
10 | public static void checkResponseStatus(ClassicHttpResponse response) {
11 | if (response.getCode() == HttpStatus.SC_OK) {
12 | return;
13 | }
14 |
15 | try {
16 | if (response.getCode() == HttpStatus.SC_UNPROCESSABLE_ENTITY) {
17 | JsonUtils.fromJson(response.getEntity().getContent(), SdWebuiServerValidationException.class);
18 | }
19 |
20 | throw JsonUtils.fromJson(response.getEntity().getContent(), SdWebuiBadRequestException.class);
21 | } catch (Exception e) {
22 | throw new RuntimeException(e);
23 | }
24 |
25 | }
26 |
27 | public static T parseResponse(ClassicHttpResponse response, Class clazz) {
28 | checkResponseStatus(response);
29 | try {
30 | return JsonUtils.fromJson(response.getEntity().getContent(), clazz);
31 | } catch (Exception e) {
32 | throw new RuntimeException(e);
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/GetFaceRestorersTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import io.github.robothy.sdwebui.sdk.models.results.FaceRestorer;
4 | import org.junit.jupiter.api.Test;
5 | import org.junit.jupiter.api.extension.ExtendWith;
6 | import org.mockserver.client.MockServerClient;
7 | import org.mockserver.junit.jupiter.MockServerExtension;
8 | import org.mockserver.model.HttpRequest;
9 | import org.mockserver.model.HttpResponse;
10 |
11 | import java.util.List;
12 |
13 | import static org.junit.jupiter.api.Assertions.*;
14 |
15 | @ExtendWith(MockServerExtension.class)
16 | class GetFaceRestorersTest {
17 |
18 | @Test
19 | void getFaceRestorers(MockServerClient client) {
20 | client.when(new HttpRequest().withMethod("GET").withPath("/sdapi/v1/face-restorers"))
21 | .respond(new HttpResponse().withStatusCode(200).withBody("[\n" +
22 | " {\n" +
23 | " \"name\": \"CodeFormer\",\n" +
24 | " \"cmd_dir\": \"C:\\\\Users\\\\admin\\\\PythonProjects\\\\stable-diffusion-webui\\\\models\\\\Codeformer\"\n" +
25 | " },\n" +
26 | " {\n" +
27 | " \"name\": \"GFPGAN\",\n" +
28 | " \"cmd_dir\": null\n" +
29 | " }\n" +
30 | "]"));
31 |
32 | List faceRestorers = SdWebui.create("http://localhost:" + client.getPort())
33 | .getFaceRestorers();
34 | assertEquals(2, faceRestorers.size());
35 | assertEquals("CodeFormer", faceRestorers.get(0).getName());
36 | assertEquals("C:\\Users\\admin\\PythonProjects\\stable-diffusion-webui\\models\\Codeformer", faceRestorers.get(0).getCmdDir());
37 | assertEquals("GFPGAN", faceRestorers.get(1).getName());
38 | assertNull(faceRestorers.get(1).getCmdDir());
39 | }
40 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/MockSdServer.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk;
2 |
3 | import org.junit.jupiter.api.extension.AfterEachCallback;
4 | import org.junit.jupiter.api.extension.BeforeAllCallback;
5 | import org.junit.jupiter.api.extension.BeforeEachCallback;
6 | import org.junit.jupiter.api.extension.ExtensionContext;
7 | import org.mockserver.client.MockServerClient;
8 | import org.mockserver.netty.MockServer;
9 |
10 | import java.net.http.HttpRequest;
11 | import java.util.List;
12 | import java.util.function.Predicate;
13 |
14 | public class MockSdServer implements BeforeAllCallback, BeforeEachCallback, AfterEachCallback {
15 |
16 | private int port;
17 |
18 | public int getPort() {
19 | return port;
20 | }
21 |
22 | @Override
23 | public void afterEach(ExtensionContext context) throws Exception {
24 |
25 | }
26 |
27 | @Override
28 | public void beforeAll(ExtensionContext context) throws Exception {
29 |
30 | }
31 |
32 | @Override
33 | public void beforeEach(ExtensionContext context) throws Exception {
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/SystemInfoTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models;
2 |
3 | import static org.junit.jupiter.api.Assertions.*;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import org.junit.jupiter.api.Test;
7 |
8 | class SystemInfoTest {
9 |
10 | @Test
11 | void testSerialization() throws JsonProcessingException {
12 | SystemInfo systemInfo = new SystemInfo();
13 | systemInfo.setPlatform("Linux");
14 | systemInfo.setPythonVersion("3.8.5");
15 | systemInfo.setSdwebuiVersion("0.0.1");
16 | ObjectMapper objectMapper = new ObjectMapper();
17 | assertEquals(systemInfo, objectMapper
18 | .readValue(objectMapper.writeValueAsString(systemInfo), SystemInfo.class));
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/options/ExtraImageOptionsTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.options;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import static org.junit.jupiter.api.Assertions.assertEquals;
8 |
9 | public class ExtraImageOptionsTest {
10 |
11 | @Test
12 | void testSerialization() throws JsonProcessingException{
13 | ExtraImageOptions options = ExtraImageOptions.builder()
14 | .image("")
15 | .codeformerWeight(0.1)
16 | .upscalingResizeW(1L)
17 | .upscalingResizeH(2L)
18 | .codeformerVisibility(0.2)
19 | .extrasUpscaler2Visibility(0.3)
20 | .gfpganVisibility(0.4)
21 | .showExtrasResults(true)
22 | .upscaleFirst(true)
23 | .upscaler2("upscaler2")
24 | .upscalingCrop(true)
25 | .upscalingResize(0.0)
26 | .upscaler1("upscaler1")
27 | .resizeMode(0L)
28 | .build();
29 | ObjectMapper objectMapper = new ObjectMapper();
30 | ExtraImageOptions deserializedTxt2ImageOptions =
31 | objectMapper.readValue(objectMapper.writeValueAsString(options), ExtraImageOptions.class);
32 | assertEquals(options, deserializedTxt2ImageOptions);
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/options/Image2ImageOptionsTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.options;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 | import java.util.List;
10 |
11 | import static org.junit.jupiter.api.Assertions.*;
12 |
13 | class Image2ImageOptionsTest {
14 |
15 | @Test
16 | void testSerialization() throws JsonProcessingException {
17 | Image2ImageOptions options = Image2ImageOptions.builder()
18 | .prompt("prompt")
19 | .negativePrompt("negativePrompt")
20 | .styles(new ArrayList<>())
21 | .seed(-1)
22 | .subseed(-1)
23 | .subseedStrength(0)
24 | .seedResizeFromH(-1)
25 | .seedResizeFromW(-1)
26 | .samplerName("string")
27 | .batchSize(1)
28 | .nIter(1)
29 | .steps(50)
30 | .cfgScale(7)
31 | .width(512)
32 | .height(512)
33 | .restoreFaces(true)
34 | .tiling(true)
35 | .doNotSaveSamples(false)
36 | .doNotSaveGrid(false)
37 | .eta(0)
38 | .denoisingStrength(0.75)
39 | .sMinUncond(0)
40 | .sChurn(0)
41 | .sTmax(0)
42 | .sTmin(0)
43 | .sNoise(0)
44 | .overrideSettings(Collections.emptyMap())
45 | .overrideSettingsRestoreAfterwards(false)
46 | .refinerCheckpoint("checkpoint")
47 | .refinerSwitchAt(0)
48 | .disableExtraNetworks(false)
49 | .comments(Collections.emptyMap())
50 | .initImages(new ArrayList<>())
51 | .resizeMode(0)
52 | .imageCfgScale(0)
53 | .mask("mask")
54 | .maskBlurX(0)
55 | .maskBlurY(0)
56 | .maskBlur(0)
57 | .inpaintingFill(0)
58 | .inpaintFullRes(false)
59 | .inpaintingFullResPadding(0)
60 | .inpaintingMaskInvert(0)
61 | .initialNoiseMultiplier(0)
62 | .latentMask("latentMask")
63 | .samplerIndex("sampler")
64 | .includeInitImages(false)
65 | .scriptName("Script")
66 | .scriptArgs(new String[]{})
67 | .sendImages(true)
68 | .saveImages(false)
69 | .alwaysonScripts(Collections.emptyMap())
70 | .build();
71 |
72 | ObjectMapper mapper = new ObjectMapper();
73 | String json = mapper.writeValueAsString(options);
74 | Image2ImageOptions deserializedOptions = mapper.readValue(json, Image2ImageOptions.class);
75 | assertEquals(options, deserializedOptions);
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/options/Txt2ImageOptionsTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.options;
2 |
3 | import static org.junit.jupiter.api.Assertions.*;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import io.github.robothy.sdwebui.sdk.enums.HiResUpscaler;
7 | import java.util.List;
8 | import java.util.Map;
9 | import org.junit.jupiter.api.Test;
10 |
11 | class Txt2ImageOptionsTest {
12 |
13 | @Test
14 | void testSerialization() throws JsonProcessingException {
15 | Txt2ImageOptions txt2ImageOptions = Txt2ImageOptions.builder()
16 | .alwaysonScripts(Map.of("s1", "v1"))
17 | .batchSize(2)
18 | .eta(0.1)
19 | .denoisingStrength(0.2)
20 | .firstphaseHeight(3)
21 | .firstphaseWidth(4)
22 | .hrResizeX(5)
23 | .hrResizeY(6)
24 | .hrScale(7)
25 | .hrSecondPassSteps(8)
26 | .hrUpscaler(HiResUpscaler.Latent)
27 | .height(9)
28 | .width(10)
29 | .doNotSaveGrid(true)
30 | .enableHr(true)
31 | .prompt("prompt")
32 | .nIter(11)
33 | .doNotSaveSamples(true)
34 | .negativePrompt("negativePrompt")
35 | .saveImages(true)
36 | .overrideSettings(Map.of("s1", "v1"))
37 | .cfgScale(12)
38 | .sChurn(13)
39 | .samplerName("samplerName")
40 | .samplerIndex("14")
41 | .sendImages(true)
42 | .scriptName("scriptName")
43 | .scriptArgs(List.of("arg1", "arg2"))
44 | .seed(15)
45 | .seedResizeFromH(16)
46 | .seedResizeFromW(17)
47 | .steps(18)
48 | .sTmax(19)
49 | .sNoise(20)
50 | .sTmin(10)
51 | .subseed(21)
52 | .styles(List.of("style1", "style2"))
53 | .restoreFaces(true)
54 | .tiling(true)
55 | .subseedStrength(0.3)
56 | .useDeprecatedControlnet(true)
57 | .overrideSettingsRestoreAfterwards(true)
58 | .build();
59 |
60 | ObjectMapper objectMapper = new ObjectMapper();
61 | Txt2ImageOptions deserializedTxt2ImageOptions =
62 | objectMapper.readValue(objectMapper.writeValueAsString(txt2ImageOptions), Txt2ImageOptions.class);
63 | assertEquals(txt2ImageOptions, deserializedTxt2ImageOptions);
64 | }
65 |
66 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/results/FaceRestorerTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import io.github.robothy.sdwebui.sdk.utils.JsonUtils;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static org.junit.jupiter.api.Assertions.*;
7 |
8 | class FaceRestorerTest {
9 |
10 | @Test
11 | void testSerialization() {
12 | String faceRestorersJson = "[\n" +
13 | " {\n" +
14 | " \"name\": \"CodeFormer\",\n" +
15 | " \"cmd_dir\": \"C:\\\\Users\\\\admin\\\\PythonProjects\\\\stable-diffusion-webui\\\\models\\\\Codeformer\"\n" +
16 | " },\n" +
17 | " {\n" +
18 | " \"name\": \"GFPGAN\",\n" +
19 | " \"cmd_dir\": null\n" +
20 | " }\n" +
21 | "]";
22 |
23 | FaceRestorer[] faceRestorers = JsonUtils.fromJson(faceRestorersJson, FaceRestorer[].class);
24 | assertEquals(2, faceRestorers.length);
25 | assertEquals("CodeFormer", faceRestorers[0].getName());
26 | assertEquals("C:\\Users\\admin\\PythonProjects\\stable-diffusion-webui\\models\\Codeformer", faceRestorers[0].getCmdDir());
27 | assertEquals("GFPGAN", faceRestorers[1].getName());
28 | assertNull(faceRestorers[1].getCmdDir());
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/results/Image2ImageResultTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import io.github.robothy.sdwebui.sdk.models.options.Image2ImageOptions;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import java.util.List;
8 |
9 | import static org.junit.jupiter.api.Assertions.*;
10 |
11 | class Image2ImageResultTest {
12 |
13 | @Test
14 | void testSerialization() {
15 | Image2ImageResult result = new Image2ImageResult();
16 | result.setImages(List.of("image1", "image2"));
17 | result.setParameters(Image2ImageOptions.builder()
18 | .prompt("prompt")
19 | .build());
20 | result.setInfo("info");
21 |
22 | ObjectMapper objectMapper = new ObjectMapper();
23 | assertEquals(result, objectMapper.convertValue(objectMapper.convertValue(result, Object.class), Image2ImageResult.class));
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/results/SdModelTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import io.github.robothy.sdwebui.sdk.SdWebui;
6 | import org.junit.jupiter.api.Test;
7 | import org.junit.jupiter.api.extension.ExtendWith;
8 | import org.mockserver.client.MockServerClient;
9 | import org.mockserver.junit.jupiter.MockServerExtension;
10 | import org.mockserver.model.HttpRequest;
11 | import org.mockserver.model.HttpResponse;
12 |
13 | import java.util.List;
14 |
15 | import static org.junit.jupiter.api.Assertions.*;
16 |
17 | @ExtendWith(MockServerExtension.class)
18 | class SdModelTest {
19 |
20 | private static final String JSON = "{\n" +
21 | " \"title\": \"v1-5-pruned-emaonly.ckpt [cc6cb27103]\",\n" +
22 | " \"model_name\": \"v1-5-pruned-emaonly\",\n" +
23 | " \"hash\": \"cc6cb27103\",\n" +
24 | " \"sha256\": \"cc6cb27103417325ff94f52b7a5d2dde45a7515b25c255d8e396c90014281516\",\n" +
25 | " \"filename\": \"C:\\\\Users\\\\admin\\\\PythonProjects\\\\stable-diffusion-webui\\\\models\\\\Stable-diffusion\\\\v1-5-pruned-emaonly.ckpt\",\n" +
26 | " \"config\": null\n" +
27 | "}";
28 |
29 | @Test
30 | void testSerialization() throws JsonProcessingException {
31 | SdModel sdModel = new ObjectMapper().readValue(JSON, SdModel.class);
32 | assertEquals("v1-5-pruned-emaonly.ckpt [cc6cb27103]", sdModel.getTitle());
33 | assertEquals("v1-5-pruned-emaonly", sdModel.getModelName());
34 | assertEquals("cc6cb27103", sdModel.getHash());
35 | assertEquals("cc6cb27103417325ff94f52b7a5d2dde45a7515b25c255d8e396c90014281516", sdModel.getSha256());
36 | assertEquals("C:\\Users\\admin\\PythonProjects\\stable-diffusion-webui\\models\\Stable-diffusion\\v1-5-pruned-emaonly.ckpt", sdModel.getFilename());
37 | assertNull(sdModel.getConfig());
38 | }
39 |
40 | @Test
41 | void getGetSdModels(MockServerClient client) {
42 | client.when(new HttpRequest().withMethod("GET").withPath("/sdapi/v1/sd-models"))
43 | .respond(new HttpResponse().withStatusCode(200).withBody(" [" +
44 | "{\n" +
45 | " \"title\": \"MoyouArtificial_v10502g.safetensors [b6c1edcbe9]\",\n" +
46 | " \"model_name\": \"MoyouArtificial_v10502g\",\n" +
47 | " \"hash\": \"b6c1edcbe9\",\n" +
48 | " \"sha256\": \"b6c1edcbe9ef9fa3d38c3787d351211a775e6254b832234d97042800f33345d1\",\n" +
49 | " \"filename\": \"C:\\\\Users\\\\admin\\\\PythonProjects\\\\stable-diffusion-webui\\\\models\\\\Stable-diffusion\\\\MoyouArtificial_v10502g.safetensors\",\n" +
50 | " \"config\": null\n" +
51 | " },\n" +
52 | " {\n" +
53 | " \"title\": \"v1-5-pruned-emaonly.ckpt [cc6cb27103]\",\n" +
54 | " \"model_name\": \"v1-5-pruned-emaonly\",\n" +
55 | " \"hash\": \"cc6cb27103\",\n" +
56 | " \"sha256\": \"cc6cb27103417325ff94f52b7a5d2dde45a7515b25c255d8e396c90014281516\",\n" +
57 | " \"filename\": \"C:\\\\Users\\\\admin\\\\PythonProjects\\\\stable-diffusion-webui\\\\models\\\\Stable-diffusion\\\\v1-5-pruned-emaonly.ckpt\",\n" +
58 | " \"config\": null\n" +
59 | " }\n" +
60 | "]"));
61 | List sdModels = SdWebui.create("http://localhost:" + client.remoteAddress().getPort()).getSdModels();
62 | assertEquals(2, sdModels.size());
63 | assertEquals("MoyouArtificial_v10502g.safetensors [b6c1edcbe9]", sdModels.get(0).getTitle());
64 | assertEquals("v1-5-pruned-emaonly.ckpt [cc6cb27103]", sdModels.get(1).getTitle());
65 | assertEquals("MoyouArtificial_v10502g", sdModels.get(0).getModelName());
66 | assertEquals("v1-5-pruned-emaonly", sdModels.get(1).getModelName());
67 | assertEquals("b6c1edcbe9", sdModels.get(0).getHash());
68 | assertEquals("cc6cb27103", sdModels.get(1).getHash());
69 | assertEquals("b6c1edcbe9ef9fa3d38c3787d351211a775e6254b832234d97042800f33345d1", sdModels.get(0).getSha256());
70 | assertEquals("cc6cb27103417325ff94f52b7a5d2dde45a7515b25c255d8e396c90014281516", sdModels.get(1).getSha256());
71 | assertEquals("C:\\Users\\admin\\PythonProjects\\stable-diffusion-webui\\models\\Stable-diffusion\\MoyouArtificial_v10502g.safetensors", sdModels.get(0).getFilename());
72 | assertEquals("C:\\Users\\admin\\PythonProjects\\stable-diffusion-webui\\models\\Stable-diffusion\\v1-5-pruned-emaonly.ckpt", sdModels.get(1).getFilename());
73 | assertNull(sdModels.get(0).getConfig());
74 | assertNull(sdModels.get(1).getConfig());
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/robothy/sdwebui/sdk/models/results/Txt2ImgResultTest.java:
--------------------------------------------------------------------------------
1 | package io.github.robothy.sdwebui.sdk.models.results;
2 |
3 | import static org.junit.jupiter.api.Assertions.*;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import io.github.robothy.sdwebui.sdk.models.options.Txt2ImageOptions;
7 | import java.util.List;
8 | import org.junit.jupiter.api.Test;
9 |
10 | class Txt2ImgResultTest {
11 |
12 | @Test
13 | void testSerialization() throws JsonProcessingException {
14 | Txt2ImgResult txt2ImgResult = new Txt2ImgResult();
15 | txt2ImgResult.setImages(List.of("image1", "image2"));
16 | txt2ImgResult.setInfo("info");
17 | txt2ImgResult.setParameters(Txt2ImageOptions.builder()
18 | .prompt("1dog")
19 | .build());
20 |
21 | ObjectMapper objectMapper = new ObjectMapper();
22 | assertEquals(txt2ImgResult, objectMapper.readValue(objectMapper
23 | .writeValueAsString(txt2ImgResult), Txt2ImgResult.class));
24 | }
25 |
26 | }
--------------------------------------------------------------------------------