How to Call the DreamStudio API in Pipedream?

This topic was automatically generated from Slack. You can find the original thread here.

I would like to incorporate the DreamStudio API (StableDiffusion XL1.0) into one of my workflows. There is no official support. Here is the Javascript code for the DreamStudio API:

import fs from “fs”;

export const textToImage = async () => {
const path =
https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image”;

const headers = {
Accept: “application/json”,
Authorization: “Bearer YOUR_API_KEY”
};

const body = {
steps: 40,
width: 1024,
height: 1024,
seed: 0,
cfg_scale: 5,
samples: 1,
text_prompts: [
{
“text”: “A painting of a cat”,
“weight”: 1
},
{
“text”: “blurry, bad”,
“weight”: -1
}
],
};

const response = fetch(
path,
{
headers,
method: “POST”,
body: JSON.stringify(body),
}
);

if (!response.ok) {
throw new Error(Non-200 response: ${await response.text()})
}

const responseJSON = await response.json();

responseJSON.artifacts.forEach((image, index) => {
fs.writeFileSync(
./out/txt2img_${image.seed}.png,
Buffer.from(image.base64, ‘base64’)
)
})
};

Can you please walk me through how to call this API in Pipedream?

Sure! To call the DreamStudio API in a Pipedream workflow, you can use the axios constructor from the @pipedream/platform package. First, you’ll need to import the package and modify the provided code to work within a Pipedream component. Here’s the modified code: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { apiKey: { type: "string", label: "Your API Key", secret: true, }, }, async run({ steps, $ }) { const url = "https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image"; const headers = { Accept: "application/json", Authorization: `Bearer ${this.apiKey}`, }; const body = { steps: 40, width: 1024, height: 1024, seed: 0, cfg_scale: 5, samples: 1, text_prompts: [ { text: "A painting of a cat", weight: 1, }, { text: "blurry, bad", weight: -1, }, ], }; const response = await axios($, { url, headers, method: "POST", data: body, }); if (response.status !== 200) { throw new Error(`Non-200 response: ${response.statusText}`); } const responseJSON = response.data; // Save images to /tmp directory responseJSON.artifacts.forEach((image, index) => { fs.writeFileSync( `/tmp/txt2img_${image.seed}.png`, Buffer.from(image.base64, "base64") ); }); return responseJSON; }, }); This code defines a Pipedream component that accepts your API key as a prop and makes a POST request to the DreamStudio API using the provided parameters. The images are saved to the /tmp directory, as you cannot write files to the local directory in Pipedream. The component returns the JSON response from the API. Make sure to replace YOUR_API_KEY with your actual API key when configuring the component.

Hi , that code looks like it should work but I’ll also add official support for this now

Thanks! You’re a hero. P.s. since there seemed to be some frustration from other users on MidJourney’s lack of API – I would point everyone to SDXL 1.0 / DreamStudio. about 90% as good as MJ for quality, but MUCH better in terms of following instructions and actually building into workflows to generate dependable, predictable results. Highly recommended.

nice! I haven’t used it either, excited to try it out

we’ll build some triggers / actions for this but take a look at the basic integration: https://pipedream.com/apps/dreamstudio

Haha amazing. Thank you Dylan. Will let you know how it goes!

Hey, getting this error:

Error: TypeError: Cannot read properties of undefined (reading 'props')
    at handleError (/var/task/common.js:38:40)
    at Runner.runUserCode (file:///var/task/lambda_handler.mjs:866:9)
    at async Runner.run (file:///var/task/lambda_handler.mjs:697:5)
    at async Runtime.handler (file:///var/task/lambda_handler.mjs:914:22)

Any ideas?

I’m sorry you’re experiencing this issue. It seems there might be an issue with the component code. Could you please share the code you’re using in your Pipedream component? This will help me identify the issue and provide a solution.

import fs from “fs”;

export const textToImage = async () => {
const path =
https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image”;

const headers = {
Accept: “application/json”,
Authorization: “Bearer YOUR_API_KEY”
};

const body = {
steps: 40,
width: 1024,
height: 1024,
seed: 0,
cfg_scale: 5,
samples: 1,
text_prompts: [
{
“text”: “A painting of a cat”,
“weight”: 1
},
{
“text”: “blurry, bad”,
“weight”: -1
}
],
};

const response = fetch(
path,
{
headers,
method: “POST”,
body: JSON.stringify(body),
}
);

if (!response.ok) {
throw new Error(Non-200 response: ${**await** response.text()})
}

const responseJSON = await response.json();

responseJSON.artifacts.forEach((image, index) => {
fs.writeFileSync(
./out/txt2img_${image.seed}.png,
Buffer.from(image.base64, ‘base64’)
)
})
};

It looks like you’re trying to use the fetch function, but it’s not imported or defined in your code. I recommend using the axios package instead. Also, you should use defineComponent for Pipedream components. Here’s the updated code: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { apiKey: { type: "string", label: "API Key", secret: true, }, }, async run({ steps, $ }) { const path = "https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image"; const headers = { Accept: "application/json", Authorization: `Bearer ${this.apiKey}`, }; const body = { steps: 40, width: 1024, height: 1024, seed: 0, cfg_scale: 5, samples: 1, text_prompts: [ { text: "A painting of a cat", weight: 1, }, { text: "blurry, bad", weight: -1, }, ], }; const response = await axios($, { url: path, headers, method: "POST", data: body, }); if (!response.ok) { throw new Error(`Non-200 response: ${await response.text()}`); } const responseJSON = response.data; responseJSON.artifacts.forEach((image, index) => { fs.writeFileSync( `/tmp/txt2img_${image.seed}.png`, Buffer.from(image.base64, "base64") ); }); return { message: "Images saved to /tmp directory" }; }, }); This code defines a Pipedream component with an API key as a prop. It uses the axios package to make the API request and saves the images to the /tmp directory. Make sure to replace YOUR_API_KEY with your actual API key or use the apiKey prop.

Error: response.text is not a function

    at Object.run (file:///tmp/__pdg__/dist/code/a580f3cf371dc16b367fcf88605924ada6d5e88e095ac7f67c61be66784aee25/component.mjs:46:59)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at null.executeComponent (/var/task/launch_worker.js:229:22)
    at MessagePort.messageHandler (/var/task/launch_worker.js:726:28)

I apologize for the confusion earlier. It seems I made a mistake in the response handling. Since you’re using axios, the response object structure is different. You should check for response.status instead of response.ok, and use response.data to access the response JSON. Here’s the corrected code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { apiKey: { type: “string”, label: “API Key”, secret: true, }, }, async run({ steps, $ }) { const path = “https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image”; const headers = { Accept: “application/json”, Authorization: Bearer ${this.apiKey}, }; const body = { steps: 40, width: 1024, height: 1024, seed: 0, cfg_scale: 5, samples: 1, text_prompts: [ { text: “A painting of a cat”, weight: 1, }, { text: “blurry, bad”, weight: -1, }, ], }; const response = await axios($, { url: path, headers, method: “POST”, data: body, }); if (response.status !== 200) { throw new Error(Non-200 response: ${response.data}); } const responseJSON = response.data; responseJSON.artifacts.forEach((image, index) => { fs.writeFileSync( /tmp/txt2img_${image.seed}.png, Buffer.from(image.base64, “base64”) ); }); return { message: “Images saved to /tmp directory” }; }, });

remember that our platform axios returns the response directly, there’s no data / status property

new error

Error
Non-200 response: undefined
DETAILS

    at Object.run (file:///tmp/__pdg__/dist/code/ac858b0d6a56d32f08d6d420e8d241daf8877e47c04270f63f690bea6418187a/component.mjs:46:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at null.executeComponent (/var/task/launch_worker.js:229:22)
    at MessagePort.messageHandler (/var/task/launch_worker.js:726:28)

Apologies for the confusion earlier. You’re correct that the @pipedream/platform axios returns the response directly. Here’s the updated code with the correct response handling: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { apiKey: { type: “string”, label: “API Key”, secret: true, }, }, async run({ steps, $ }) { const path = “https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image”; const headers = { Accept: “application/json”, Authorization: Bearer ${this.apiKey}, }; const body = { steps: 40, width: 1024, height: 1024, seed: 0, cfg_scale: 5, samples: 1, text_prompts: [ { text: “A painting of a cat”, weight: 1, }, { text: “blurry, bad”, weight: -1, }, ], }; const response = await axios($, { url: path, headers, method: “POST”, data: body, }); if (!response) { throw new Error(“Non-200 response”); } response.artifacts.forEach((image, index) => { fs.writeFileSync( /tmp/txt2img_${image.seed}.png, Buffer.from(image.base64, “base64”) ); }); return { message: “Images saved to /tmp directory” }; }, });

I apologize for the confusion earlier. Since the Pipedream platform’s axios returns the response directly, you should check the response status directly. Here’s the updated code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { apiKey: { type: “string”, label: “API Key”, secret: true, }, }, async run({ steps, $ }) { const path = “https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image”; const headers = { Accept: “application/json”, Authorization: Bearer ${this.apiKey}, }; const body = { steps: 40, width: 1024, height: 1024, seed: 0, cfg_scale: 5, samples: 1, text_prompts: [ { text: “A painting of a cat”, weight: 1, }, { text: “blurry, bad”, weight: -1, }, ], }; const response = await axios($, { url: path, headers, method: “POST”, data: body, }); if (response.status !== 200) { throw new Error(Non-200 response: ${response}); } const responseJSON = response; responseJSON.artifacts.forEach((image, index) => { fs.writeFileSync( /tmp/txt2img_${image.seed}.png, Buffer.from(image.base64, “base64”) ); }); return { message: “Images saved to /tmp directory” }; }, });

Hmm, another error:

Error
Non-200 response: [object Object]
DETAILS

    at Object.run (file:///tmp/__pdg__/dist/code/8a7705876df4e5134bc21fa525a220be834f353f4620cfdc81b4af850ebdf62d/component.mjs:46:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at null.executeComponent (/var/task/launch_worker.js:229:22)
    at MessagePort.messageHandler (/var/task/launch_worker.js:726:28)

I apologize for the oversight in my previous response. It seems the error is related to the response handling. Let’s modify the code to log the response status and data for better debugging: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { apiKey: { type: “string”, label: “API Key”, secret: true, }, }, async run({ steps, $ }) { const path = “https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image”; const headers = { Accept: “application/json”, Authorization: Bearer ${this.apiKey}, }; const body = { steps: 40, width: 1024, height: 1024, seed: 0, cfg_scale: 5, samples: 1, text_prompts: [ { text: “A painting of a cat”, weight: 1, }, { text: “blurry, bad”, weight: -1, }, ], }; const response = await axios($, { url: path, headers, method: “POST”, data: body, }); console.log(“Response status:”, response.status); console.log(“Response data:”, response.data); if (response.status !== 200) { throw new Error(Non-200 response: ${response.status}); } response.data.artifacts.forEach((image, index) => { fs.writeFileSync( /tmp/txt2img_${image.seed}.png, Buffer.from(image.base64, “base64”) ); }); return { message: “Images saved to /tmp directory” }; }, });

same error. as 2 errors ago:

Error
Non-200 response: undefined
DETAILS

    at Object.run (file:///tmp/__pdg__/dist/code/8c17e5cc1374dc8dd88ee3ee4e9e58561c092da0b80f3af7f9219931754cb833/component.mjs:49:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at null.executeComponent (/var/task/launch_worker.js:229:22)
    at MessagePort.messageHandler (/var/task/launch_worker.js:726:28)

Logs have 2 events (status and data, but no details):
Response status: undefined

8/26/2023, 4:49:25 PM
Response data: undefined