Skip to content

Commit 9199042

Browse files
committed
Support webhooks when creating predictions
1 parent 8394541 commit 9199042

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,33 @@ console.log(prediction.status); // "starting"
7575
From there, you can fetch the current status of the prediction using
7676
`await prediction.load()` or `await replicate.prediction(prediction.id).load()`.
7777

78+
You can also provide webhook configuration to have Replicate send POST requests
79+
to your service when certain events occur:
80+
81+
```js
82+
import replicate from "replicate";
83+
84+
await replicate
85+
.model(
86+
"stability-ai/stable-diffusion:db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf"
87+
)
88+
.createPrediction(
89+
{
90+
prompt: "painting of a cat by andy warhol",
91+
},
92+
{
93+
webhook: {
94+
// See https://replicate.com/docs/reference/http#create-prediction--webhook
95+
url: "https://your.host/webhook",
96+
97+
// Optional
98+
// See https://replicate.com/docs/reference/http#create-prediction--webhook_events_filter
99+
events: ["output", "completed"],
100+
},
101+
}
102+
);
103+
```
104+
78105
## Contributing
79106

80107
While we'd love to accept contributions to this library, please open an issue

lib/Model.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,27 @@ export default class Model extends ReplicateObject {
122122
return prediction;
123123
}
124124

125-
async createPrediction(input) {
125+
async createPrediction(input, { webhook = {} } = {}) {
126126
// This is here and not on `Prediction` because conceptually, a prediction
127127
// from a model "belongs" to the model. It's an odd feature of the API that
128128
// the prediction creation isn't an action on the model (or that it doesn't
129129
// actually use the model information, only the version), but we don't need
130130
// to expose that to users of this library.
131+
132+
let webhookUrl;
133+
let webhookEvents;
134+
if (typeof webhook === "string") {
135+
webhookUrl = webhook;
136+
} else {
137+
webhookUrl = webhook.url;
138+
webhookEvents = webhook.events;
139+
}
140+
131141
const predictionData = await this.client.request("POST /v1/predictions", {
132142
version: this.version,
133143
input,
144+
webhook: webhookUrl,
145+
webhook_events_filter: webhookEvents,
134146
});
135147

136148
return new Prediction(predictionData, this);

lib/Model.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,4 +276,46 @@ describe("createPrediction()", () => {
276276
input: { text: "test text" },
277277
});
278278
});
279+
280+
it("supports webhook string", async () => {
281+
jest.spyOn(client, "request").mockResolvedValue({
282+
id: "testprediction",
283+
status: PredictionStatus.SUCCEEDED,
284+
});
285+
286+
await model.createPrediction(
287+
{ text: "test text" },
288+
{ webhook: "http://test.host/webhook" }
289+
);
290+
291+
expect(client.request).toHaveBeenCalledWith("POST /v1/predictions", {
292+
version: "testversion",
293+
input: { text: "test text" },
294+
webhook: "http://test.host/webhook",
295+
});
296+
});
297+
298+
it("supports webhook object", async () => {
299+
jest.spyOn(client, "request").mockResolvedValue({
300+
id: "testprediction",
301+
status: PredictionStatus.SUCCEEDED,
302+
});
303+
304+
await model.createPrediction(
305+
{ text: "test text" },
306+
{
307+
webhook: {
308+
url: "http://test.host/webhook",
309+
events: ["output", "completed"],
310+
},
311+
}
312+
);
313+
314+
expect(client.request).toHaveBeenCalledWith("POST /v1/predictions", {
315+
version: "testversion",
316+
input: { text: "test text" },
317+
webhook: "http://test.host/webhook",
318+
webhook_events_filter: ["output", "completed"],
319+
});
320+
});
279321
});

0 commit comments

Comments
 (0)