Skip to main content

Fullstack integration

The JavaScript Client library simplify the integration of workflows in web applications by providing utilities to stream deployments results to the browser, while preserving your credentials and workflow informations private.

We recommend implementing the following flow:

To stream progress and results, you can use the Client#runStream method which takes the same parameters as Client#run but return progress state as an AsyncGenerator.

import {Client} from "@ikomia/ikclient";

const client = new Client({
url: "https://your.scale.endpoint.url",
});

const stream = await client.runStream({
image: "https://production-media.paperswithcode.com/datasets/Foggy_Cityscapes-0000003414-fb7dc023.jpg",
taskName: "infer_mmlab_segmentation",
});

for await (const progress of stream) {
console.log(progress);

if (progress.results) {
// Do something with the results
console.log(progress.results.getOutputs());
}
}

You can then serialize and deserialize the generator using one of our provided utilities to stream the results to the browser:

Using these utilities, you can easily integrate your deployment into a fullstack web application with many modern frameworks and technologies:

Implementing the backend endpoint

Implement a route that calls your deployment and streams the results using Server-sent events. We can use the toReadableStream utility to serialize the generator into a readable stream and pipe it to the response:

import {Readable} from 'node:stream';

import express from 'express';
import {Client} from '@ikomia/ikclient';
import {toReadableStream} from '@ikomia/ikclient/proxy/server';

const app = express();

const imageGenerator = new Client({
url: process.env.ENDPOINT_URL,
});

app.get('/api/generate-image', async (req, res) => {
// Add your own logic here (e.g. authentication, rate limiting, billing, etc.)
const prompt = req.query.prompt;

if (!prompt) {
res.status(400).send('Missing prompt');
return;
}

const stream = imageGenerator.runStream({
parameters: {prompt}
});

// Set status and headers for Server-sent events
res.status(200);
res.setHeader('Content-Type', 'text/event-stream');

// Stream the results
Readable.fromWeb(toReadableStream(stream)).pipe(res);
});

app.listen(3000, () => {
console.log('Express server initialized');
});

Since you are responsible of implementing your backend endpoint, you can easily incorporate your own logic to authenticate users, rate limit requests, add billing or any other custom constraints.

Implementing the client-side code

Just fetch your endpoint and process the results using the processStreamingResponse utility:

import {processStreamingResponse} from '@ikomia/ikclient/proxy/browser';
import {ImageIO} from '@ikomia/ikclient/io';

const prompt = 'A puppy playing in the snow';

const response = await fetch(`/api/generate-image?prompt=${prompt}`);
const results = await processStreamingResponse(response);

// Get the output image
const resultImage = results.getOutput<ImageIO>(0);