Added fal AI example (#1439)
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: "Convert an image to a cartoon using fal AI"
|
||||
sidebarTitle: "fal AI image to cartoon"
|
||||
description: "This example demonstrates how to convert an image to a cartoon using fal AI with Trigger.dev."
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Fal AI is a platform that provides access to advanced AI models for tasks such as image generation, text summarization, and hyperparameter tuning.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A project with [Trigger.dev initialized](/quick-start)
|
||||
- A [fal AI](https://fal.ai/) account
|
||||
- A [Cloudflare](https://developers.cloudflare.com/r2/) account and bucket
|
||||
|
||||
## Task code
|
||||
|
||||
This task converts an image to a cartoon using fal AI, and uploads the result to Cloudflare R2.
|
||||
|
||||
```ts trigger/fal-ai-image-to-cartoon.ts
|
||||
import { logger, task } from "@trigger.dev/sdk/v3";
|
||||
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
||||
import * as fal from "@fal-ai/serverless-client";
|
||||
import fetch from "node-fetch";
|
||||
import { z } from "zod";
|
||||
|
||||
// Initialize fal.ai client
|
||||
fal.config({
|
||||
credentials: process.env.FAL_KEY, // Get this from your fal AI dashboard
|
||||
});
|
||||
|
||||
// Initialize S3-compatible client for Cloudflare R2
|
||||
const s3Client = new S3Client({
|
||||
// How to authenticate to R2: https://developers.cloudflare.com/r2/api/s3/tokens/
|
||||
region: "auto",
|
||||
endpoint: process.env.R2_ENDPOINT,
|
||||
credentials: {
|
||||
accessKeyId: process.env.R2_ACCESS_KEY_ID ?? "",
|
||||
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY ?? "",
|
||||
},
|
||||
});
|
||||
|
||||
export const FalResult = z.object({
|
||||
images: z.tuple([z.object({ url: z.string() })]),
|
||||
});
|
||||
|
||||
export const falAiImageToCartoon = task({
|
||||
id: "fal-ai-image-to-cartoon",
|
||||
run: async (payload: { imageUrl: string; fileName: string }) => {
|
||||
logger.log("Converting image to cartoon", payload);
|
||||
|
||||
// Convert image to cartoon using fal.ai
|
||||
const result = await fal.subscribe("fal-ai/flux/dev/image-to-image", {
|
||||
input: {
|
||||
prompt: "Turn the image into a cartoon in the style of a Pixar character",
|
||||
image_url: payload.imageUrl,
|
||||
},
|
||||
onQueueUpdate: (update) => {
|
||||
logger.info("Fal.ai processing update", { update });
|
||||
},
|
||||
});
|
||||
|
||||
const $result = FalResult.parse(result);
|
||||
const [{ url: cartoonImageUrl }] = $result.images;
|
||||
|
||||
// Download the cartoon image
|
||||
const imageResponse = await fetch(cartoonImageUrl);
|
||||
const imageBuffer = await imageResponse.arrayBuffer().then(Buffer.from);
|
||||
|
||||
// Upload to Cloudflare R2
|
||||
const r2Key = `cartoons/${payload.fileName}`;
|
||||
const uploadParams = {
|
||||
Bucket: process.env.R2_BUCKET, // Create a bucket in your Cloudflare dashboard
|
||||
Key: r2Key,
|
||||
Body: imageBuffer,
|
||||
ContentType: "image/png",
|
||||
};
|
||||
|
||||
logger.log("Uploading cartoon to R2", { key: r2Key });
|
||||
await s3Client.send(new PutObjectCommand(uploadParams));
|
||||
|
||||
logger.log("Cartoon uploaded to R2", { key: r2Key });
|
||||
|
||||
return {
|
||||
originalUrl: payload.imageUrl,
|
||||
cartoonUrl: `File uploaded to storage at: ${r2Key}`,
|
||||
};
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Testing your task
|
||||
|
||||
You can test your task by triggering it from the Trigger.dev dashboard.
|
||||
|
||||
```json
|
||||
"imageUrl": "<image-url>", // Replace with the URL of the image you want to convert to a cartoon
|
||||
"fileName": "<file-name>" // Replace with the name you want to save the file as in Cloudflare R2
|
||||
```
|
||||
@@ -41,6 +41,7 @@ Tasks you can copy and paste to get started with Trigger.dev. They can all be ex
|
||||
| :---------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [DALL·E 3 image generation](/guides/examples/dall-e3-generate-image) | Use OpenAI's GPT-4o and DALL·E 3 to generate an image and text. |
|
||||
| [Deepgram audio transcription](/guides/examples/deepgram-transcribe-audio) | Transcribe audio using Deepgram's speech recognition API. |
|
||||
| [fal AI image to cartoon](/guides/examples/fal-ai-image-to-cartoon) | Convert an image to a cartoon using fal AI, and upload the result to Cloudflare R2. |
|
||||
| [FFmpeg video processing](/guides/examples/ffmpeg-video-processing) | Use FFmpeg to process a video in various ways and save it to Cloudflare R2. |
|
||||
| [Firecrawl URL crawl](/guides/examples/firecrawl-url-crawl) | Learn how to use Firecrawl to crawl a URL and return LLM-ready markdown. |
|
||||
| [OpenAI with retrying](/guides/examples/open-ai-with-retrying) | Create a reusable OpenAI task with custom retry options. |
|
||||
|
||||
+16
-60
@@ -1,10 +1,7 @@
|
||||
{
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "Trigger.dev",
|
||||
"openapi": [
|
||||
"/openapi.yml",
|
||||
"/v3-openapi.yaml"
|
||||
],
|
||||
"openapi": ["/openapi.yml", "/v3-openapi.yaml"],
|
||||
"api": {
|
||||
"playground": {
|
||||
"mode": "simple"
|
||||
@@ -122,43 +119,27 @@
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Getting Started",
|
||||
"pages": [
|
||||
"introduction",
|
||||
"quick-start",
|
||||
"how-it-works",
|
||||
"upgrading-beta",
|
||||
"limits"
|
||||
]
|
||||
"pages": ["introduction", "quick-start", "how-it-works", "upgrading-beta", "limits"]
|
||||
},
|
||||
{
|
||||
"group": "Fundamentals",
|
||||
"pages": [
|
||||
{
|
||||
"group": "Tasks",
|
||||
"pages": [
|
||||
"tasks/overview",
|
||||
"tasks/schemaTask",
|
||||
"tasks/scheduled"
|
||||
]
|
||||
"pages": ["tasks/overview", "tasks/schemaTask", "tasks/scheduled"]
|
||||
},
|
||||
"triggering",
|
||||
"runs",
|
||||
"apikeys",
|
||||
{
|
||||
"group": "Configuration",
|
||||
"pages": [
|
||||
"config/config-file",
|
||||
"config/extensions/overview"
|
||||
]
|
||||
"pages": ["config/config-file", "config/extensions/overview"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Development",
|
||||
"pages": [
|
||||
"cli-dev",
|
||||
"run-tests"
|
||||
]
|
||||
"pages": ["cli-dev", "run-tests"]
|
||||
},
|
||||
{
|
||||
"group": "Deployment",
|
||||
@@ -168,9 +149,7 @@
|
||||
"github-actions",
|
||||
{
|
||||
"group": "Deployment integrations",
|
||||
"pages": [
|
||||
"vercel-integration"
|
||||
]
|
||||
"pages": ["vercel-integration"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -182,13 +161,7 @@
|
||||
"errors-retrying",
|
||||
{
|
||||
"group": "Wait",
|
||||
"pages": [
|
||||
"wait",
|
||||
"wait-for",
|
||||
"wait-until",
|
||||
"wait-for-event",
|
||||
"wait-for-request"
|
||||
]
|
||||
"pages": ["wait", "wait-for", "wait-until", "wait-for-event", "wait-for-request"]
|
||||
},
|
||||
"queue-concurrency",
|
||||
"versioning",
|
||||
@@ -204,10 +177,7 @@
|
||||
},
|
||||
{
|
||||
"group": "Frontend usage",
|
||||
"pages": [
|
||||
"frontend/overview",
|
||||
"frontend/react-hooks"
|
||||
]
|
||||
"pages": ["frontend/overview", "frontend/react-hooks"]
|
||||
},
|
||||
{
|
||||
"group": "Realtime API",
|
||||
@@ -225,10 +195,7 @@
|
||||
"management/overview",
|
||||
{
|
||||
"group": "Tasks API",
|
||||
"pages": [
|
||||
"management/tasks/trigger",
|
||||
"management/tasks/batch-trigger"
|
||||
]
|
||||
"pages": ["management/tasks/trigger", "management/tasks/batch-trigger"]
|
||||
},
|
||||
{
|
||||
"group": "Runs API",
|
||||
@@ -267,9 +234,7 @@
|
||||
},
|
||||
{
|
||||
"group": "Projects API",
|
||||
"pages": [
|
||||
"management/projects/runs"
|
||||
]
|
||||
"pages": ["management/projects/runs"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -315,17 +280,11 @@
|
||||
},
|
||||
{
|
||||
"group": "Help",
|
||||
"pages": [
|
||||
"community",
|
||||
"help-slack",
|
||||
"help-email"
|
||||
]
|
||||
"pages": ["community", "help-slack", "help-email"]
|
||||
},
|
||||
{
|
||||
"group": "",
|
||||
"pages": [
|
||||
"guides/introduction"
|
||||
]
|
||||
"pages": ["guides/introduction"]
|
||||
},
|
||||
{
|
||||
"group": "Frameworks",
|
||||
@@ -369,6 +328,7 @@
|
||||
"pages": [
|
||||
"guides/examples/dall-e3-generate-image",
|
||||
"guides/examples/deepgram-transcribe-audio",
|
||||
"guides/examples/fal-ai-image-to-cartoon",
|
||||
"guides/examples/ffmpeg-video-processing",
|
||||
"guides/examples/firecrawl-url-crawl",
|
||||
"guides/examples/open-ai-with-retrying",
|
||||
@@ -386,15 +346,11 @@
|
||||
},
|
||||
{
|
||||
"group": "Dashboard",
|
||||
"pages": [
|
||||
"guides/dashboard/creating-a-project"
|
||||
]
|
||||
"pages": ["guides/dashboard/creating-a-project"]
|
||||
},
|
||||
{
|
||||
"group": "Migrations",
|
||||
"pages": [
|
||||
"guides/use-cases/upgrading-from-v2"
|
||||
]
|
||||
"pages": ["guides/use-cases/upgrading-from-v2"]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
@@ -402,4 +358,4 @@
|
||||
"github": "https://github.com/triggerdotdev",
|
||||
"linkedin": "https://www.linkedin.com/company/triggerdotdev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user