mirror of
https://github.com/supabase/supabase.git
synced 2026-05-22 17:00:43 +08:00
93 lines
3.8 KiB
Plaintext
93 lines
3.8 KiB
Plaintext
---
|
|
title: 'Generate image captions using Hugging Face'
|
|
description: 'Use the Hugging Face Inference API to make calls to 100,000+ Machine Learning models from Supabase Edge Functions.'
|
|
subtitle: 'Use the Hugging Face Inference API to make calls to 100,000+ Machine Learning models from Supabase Edge Functions.'
|
|
video: 'https://www.youtube.com/v/OgnYxRkxEUw'
|
|
tocVideo: 'OgnYxRkxEUw'
|
|
---
|
|
|
|
We can combine Hugging Face with [Supabase Storage](/storage) and [Database Webhooks](/docs/guides/database/webhooks) to automatically caption for any image we upload to a storage bucket.
|
|
|
|
## About Hugging Face
|
|
|
|
[Hugging Face](https://huggingface.co/) is the collaboration platform for the machine learning community.
|
|
|
|
[Huggingface.js](https://huggingface.co/docs/huggingface.js/index) provides a convenient way to make calls to 100,000+ Machine Learning models, making it easy to incorporate AI functionality into your [Supabase Edge Functions](/edge-functions).
|
|
|
|
## Setup
|
|
|
|
- Open your Supabase project dashboard or [create a new project](/dashboard/projects).
|
|
- [Create a new bucket](/dashboard/project/_/storage/buckets) called `images`.
|
|
- Generate TypeScript types from remote Database.
|
|
- Create a new Database table called `image_caption`.
|
|
- Create `id` column of type `uuid` which references `storage.objects.id`.
|
|
- Create a `caption` column of type `text`.
|
|
- Regenerate TypeScript types to include new `image_caption` table.
|
|
- Deploy the function to Supabase: `supabase functions deploy huggingface-image-captioning`.
|
|
- Create the Database Webhook in the [Supabase Dashboard](/dashboard/project/_/database/hooks) to trigger the `huggingface-image-captioning` function anytime a record is added to the `storage.objects` table.
|
|
|
|
## Generate TypeScript types
|
|
|
|
To generate the types.ts file for the storage and public schemas, run the following command in the terminal:
|
|
|
|
```bash
|
|
supabase gen types typescript --project-id=your-project-ref --schema=storage,public > supabase/functions/huggingface-image-captioning/types.ts
|
|
```
|
|
|
|
## Code
|
|
|
|
Find the complete code on [GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/huggingface-image-captioning).
|
|
|
|
```ts
|
|
import { HfInference } from 'https://esm.sh/@huggingface/inference@2.3.2'
|
|
import { createClient } from 'npm:@supabase/supabase-js@2'
|
|
|
|
import { Database } from './types.ts'
|
|
|
|
console.log('Hello from `huggingface-image-captioning` function!')
|
|
|
|
const hf = new HfInference(Deno.env.get('HUGGINGFACE_ACCESS_TOKEN'))
|
|
|
|
type SoRecord = Database['storage']['Tables']['objects']['Row']
|
|
interface WebhookPayload {
|
|
type: 'INSERT' | 'UPDATE' | 'DELETE'
|
|
table: string
|
|
record: SoRecord
|
|
schema: 'public'
|
|
old_record: null | SoRecord
|
|
}
|
|
|
|
Deno.serve(async (req) => {
|
|
const payload: WebhookPayload = await req.json()
|
|
const soRecord = payload.record
|
|
const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)
|
|
const supabaseAdminClient = createClient<Database>(
|
|
// Supabase API URL - env var exported by default when deployed.
|
|
Deno.env.get('SUPABASE_URL') ?? '',
|
|
// Supabase API SECRET KEY - env var exported by default when deployed.
|
|
Deno.env.get(SUPABASE_SECRET_KEYS['default']) ?? ''
|
|
)
|
|
|
|
// Construct image url from storage
|
|
const { data, error } = await supabaseAdminClient.storage
|
|
.from(soRecord.bucket_id!)
|
|
.createSignedUrl(soRecord.path_tokens!.join('/'), 60)
|
|
if (error) throw error
|
|
const { signedUrl } = data
|
|
|
|
// Run image captioning with Huggingface
|
|
const imgDesc = await hf.imageToText({
|
|
data: await (await fetch(signedUrl)).blob(),
|
|
model: 'nlpconnect/vit-gpt2-image-captioning',
|
|
})
|
|
|
|
// Store image caption in Database table
|
|
await supabaseAdminClient
|
|
.from('image_caption')
|
|
.insert({ id: soRecord.id!, caption: imgDesc.generated_text })
|
|
.throwOnError()
|
|
|
|
return new Response('ok')
|
|
})
|
|
```
|