Hello Artisans,
Adding AI to your web apps can really boost how well they work and how users like them. A great way to achieve this is by combining Cloudflare Workers AI with Laravel Livewire. This post will guide you on how to set up and use Cloudflare Workers AI in a Laravel Livewire application to make a smart and changing web application.
In this blog post, we will see an example where you can upload an image and convert that image to text using the Cloudflare Workers AI model Image to Text using @cf/llava-hf/llava-1.5-7b-hf
, and then analyze the sentiment of that text using another Cloudflare Workers AI model, @cf/huggingface/distilbert-sst-2-int8
.
Using these powerful AI models and Livewire's reactive components, we'll build a seamless workflow that transforms and analyzes user-uploaded images in real-time.
What is Cloudflare Workers AI?
Cloudflare Workers is a serverless platform. This gives you fast response times and high performance. Cloudflare has now added AI features to Workers and we will use those Workers AI using REST API.
What is Laravel Livewire?
Laravel Livewire is a framework that works with all parts of Laravel. It helps you make dynamic interfaces easy, while still using Laravel. With Livewire, you can build reactive dynamic interfaces using clear expressive PHP code.
Prerequisites
Before we start, make sure you have the following:
- A Laravel 11 application set up
- Composer installed
- NPM installed
- Cloudflare account
Step 1: Setting Up Cloudflare Workers
1. Sign in to Cloudflare: If you don't have an account, you must create one.
2. Generate an API Key: Go to the API Tokens section under My Profile. Generate a new API key with appropriate permissions to access Workers AI functionalities. (use a template for Workers AI). or Visit this link Create API Token.
3. Get Account ID: to use Workers AI REST API to make API calls.
Step 2: Setup env variables
- Add this to your
.env
file.
CLOUDFLARE_API_KEY=
CLOUDFLARE_ACCOUNT_ID=
- Create a new config file
cloudflare.php
to use these env variables.
<?php
return [
'api_key' => env('CLOUDFLARE_API_KEY'),
'account_id' => env('CLOUDFLARE_ACCOUNT_ID'),
'url' => 'https://api.cloudflare.com/client/v4/accounts/'
];
Step 3: Setting Up Laravel Livewire
Next, let's set up a Laravel Livewire component that interacts with our Cloudflare Worker.
1. Install Livewire:
composer require livewire/livewire
2. Publish Livewire Assets:
php artisan livewire:publish
- Create a template layout
PHP artisan livewire:layout
4. Create a Livewire Component:
php artisan make:livewire upload-image
It will create a two file one is blade file and another one is class file.
- Open
upload-image.blade.php
file and add the below code.
<div class="h-screen p-10">
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<script src="https://unpkg.com/alpinejs@2.x.x/dist/alpine.min.js" defer></script>
<div class="border border-pink-700 h-full flex flex-col justify-between relative m-auto w-1/2 m-auto">
<div class="text-center">
@if (session()->get('image_url'))
<div class="mt-6">
<img src="{{ session()->get('image_url') }}" alt="Uploaded Image"
class="w-2/6 h-auto mx-auto rounded-lg shadow-lg">
</div>
@endif
@if (session()->get('text'))
<h1 class="text-center italic font-bold m-4">Text generated from an image</h1>
<div class="text-justify px-6 mt-2">
<p class="py-4">{{ session()->get('text') }}</p>
<h2 class="italic font-bold">Sentiment analysis of text generated by an image</h2>
<p class="py-2">
<b>{{ session()->get('sentiments')['result'][0]['label'] }}</b> -
{{ session()->get('sentiments')['result'][0]['score'] }}
</p>
<p class="py-2">
<b>{{ session()->get('sentiments')['result'][1]['label'] }}</b> -
{{ session()->get('sentiments')['result'][1]['score'] }}
</p>
</div>
@endif
</div>
<div class="absolute bottom-0 w-full p-6 bg-gray-50 border-t border-gray-200">
<form class="space-y-3 text-center" method="post" enctype="multipart/form-data"
wire:submit.prevent="uploadImage">
<div x-data="{ selectedFile: '' }">
<div
class="relative w-full h-10 border border-gray-300 rounded-lg overflow-hidden pl-3 pr-1 flex items-center">
<input type="file" name="file" id="file-upload" wire:model="file"
class="w-1/2 h-full opacity-0 cursor-pointer absolute top-0 left-0 right-0" accept="image/*"
@change="selectedFile = $event.target.files[0]? $event.target.files[0].name : ''; $wire.deleteExistingImage()">
<label for="file-upload"
class="text-gray-500 font-medium truncate w-full h-full flex items-center">
<span x-text="selectedFile || 'No file selected'"></span>
</label>
<button type="submit"
class="bg-blue-500 text-white font-bold rounded-lg px-3 py-1 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-400">
Upload
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
window.onload = function() {
@php
if (session()->get('image_url')) {
$imagePath = storage_path('app/public/' . basename(session()->get('image_url')));
if (file_exists($imagePath)) {
unlink($imagePath);
}
session()->forget('image_url');
}
@endphp
};
</script>
- Open a class file
UploadImage.php
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Http;
class UploadImage extends Component
{
use WithFileUploads;
public $file = "";
public $image_url;
public function render()
{
return view('livewire.upload-image');
}
public function uploadImage()
{
$this->validate([
'file' => 'image|max:1024', // 1MB Max
]);
$image = $this->file;
$imagePath = $image->store('images', 'public');
$this->image_url = '/storage/' . $imagePath;
// We are using session to store this data
session()->put('image_url', $this->image_url);
$info = $this->createTextFromImg($this->file);
$sentiments = $this->sentimentAnalysis($info['result']['description']);
return redirect()->back()->with(['text' => $info['result']['description'], 'sentiments' => $sentiments]);
}
public function sentimentAnalysis($text)
{
try {
$authorizationToken = config('cloudflare.api_key');
$accountId = config('cloudflare.account_id');
$url = 'https://api.cloudflare.com/client/v4/accounts/' . $accountId . '/ai/run/@cf/huggingface/distilbert-sst-2-int8';
$response = Http::withToken(
$authorizationToken
)
->post($url, [
'text' => $text
]);
return json_decode($response->getBody(), true);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function createTextFromImg($img)
{
try {
if (!empty($img)) {
$imageData = file_get_contents($img->getRealPath());
$imageArray = unpack('C*', $imageData);
// Prepare input for the AI service
$input = [
'image' => array_values($imageArray),
'prompt' => 'Generate a caption for this image by extracting all the details.',
'max_tokens' => 512,
];
$authorizationToken = config('cloudflare.api_key');
$accountId = config('cloudflare.account_id');
$baseURL = config('cloudflare.url');
$url = $baseURL . $accountId . '/ai/run/@cf/llava-hf/llava-1.5-7b-hf';
$response = Http::withToken(
$authorizationToken
)
->post($url, $input);
if ($response->successful()) {
return $response->json();
} else {
return ['error' => 'Failed to get response from AI service'];
}
}
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function deleteExistingImage()
{
if (session()->get('image_url')) {
$imagePath = storage_path('app/public/' . basename(session()->get('image_url')));
if (file_exists($imagePath)) {
unlink($imagePath);
}
session()->forget('image_url');
}
}
}
-
WithFileUploads
trait helps developers manage file uploads in Livewire components. This trait makes it easier to upload files by taking care of file storage and checking. It allows developers to handle file uploads in real-time without refreshing the page.
Output:
Here is the link for Github.
Documentation
Add env variables
CLOUDFLARE_API_KEY=
CLOUDFLARE_ACCOUNT_ID=
Install Livewire:
composer require livewire/livewire
Publish Livewire Assets:
php artisan livewire:publish
Create a template layout
PHP artisan livewire:layout
Create a Livewire Component:
php artisan make:livewire upload-image
Conclusion
In summary, combining Cloudflare Workers AI with Laravel Livewire allows us to enhance our web applications smarter and interactive with trends in AI stuff.
Using models like @cf/llava-hf/llava-1.5-7b-hf
to turn images into text and @cf/huggingface/distilbert-sst-2-int8
to figure out how people feel by analyzing their sentiments, developers can build seamless application. It's a good place to start if you want to create new apps that people find easy to use. Check out this strong combo and see what cool stuff you can make next!
Happy Coding!!
🦄 ❤️
Top comments (1)
Very useful information. Thanks for writing 🙌