From 6d32fa67a5790ed794c093e50dac3b9f15c30671 Mon Sep 17 00:00:00 2001 From: D-K-P <8297864+D-K-P@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:29:16 +0000 Subject: [PATCH] Added fal AI example --- .../examples/fal-ai-image-to-cartoon.mdx | 100 ++++++++++++++++++ docs/guides/introduction.mdx | 1 + docs/mint.json | 76 +++---------- 3 files changed, 117 insertions(+), 60 deletions(-) create mode 100644 docs/guides/examples/fal-ai-image-to-cartoon.mdx diff --git a/docs/guides/examples/fal-ai-image-to-cartoon.mdx b/docs/guides/examples/fal-ai-image-to-cartoon.mdx new file mode 100644 index 0000000000..12794e42c5 --- /dev/null +++ b/docs/guides/examples/fal-ai-image-to-cartoon.mdx @@ -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": "", // Replace with the URL of the image you want to convert to a cartoon +"fileName": "" // Replace with the name you want to save the file as in Cloudflare R2 +``` diff --git a/docs/guides/introduction.mdx b/docs/guides/introduction.mdx index 4e8afe399c..88dab5d3aa 100644 --- a/docs/guides/introduction.mdx +++ b/docs/guides/introduction.mdx @@ -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. | diff --git a/docs/mint.json b/docs/mint.json index 03278df9da..ddbfd905df 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -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" } -} \ No newline at end of file +}