Integrating Laravel with Python FastAPI for Image OCR
Modern web applications increasingly need to extract text from images — receipts, scanned documents, ID cards, and more. Laravel is excellent at handling HTTP requests, queuing jobs, and managing user-facing logic, but Python's ecosystem dominates when it comes to OCR libraries. The solution? Run a Python OCR service as a standalone API using FastAPI, then call it from Laravel over HTTP.
This tutorial from Laravel Daily demonstrates exactly that pattern in a focused 22-minute video, complete with a GitHub repository you can clone and explore.
Why FastAPI as the OCR Bridge?
FastAPI is a modern, high-performance Python web framework that makes it trivial to expose any Python function — including OCR processing — as a REST endpoint. Key reasons to choose it for this pattern:
- Speed: FastAPI is built on Starlette and uses async I/O, making it fast enough for real-time image processing requests.
- Auto-generated docs: Swagger UI is available out of the box, so you can test your OCR endpoint before wiring up Laravel.
- Simple deployment: The FastAPI service can run as a separate process or container alongside your Laravel app.
How Laravel Calls the FastAPI Service
The general flow looks like this:
- A user uploads an image through the Laravel frontend.
- Laravel stores the image and dispatches an HTTP request to the FastAPI service.
- FastAPI receives the image, runs the OCR script (e.g., using Tesseract or a similar library), and returns the extracted text as JSON.
- Laravel receives the response and stores or displays the result.
A minimal Laravel HTTP call to the FastAPI endpoint might look like this:
use Illuminate\Support\Facades\Http;
$response = Http::attach(
'file',
file_get_contents($imagePath),
'image.png'
)->post('http://localhost:8000/ocr');
$extractedText = $response->json('text');
On the Python side, a minimal FastAPI endpoint that accepts the uploaded file and runs OCR could be structured as:
from fastapi import FastAPI, UploadFile, File
import pytesseract
from PIL import Image
import io
app = FastAPI()
@app.post("/ocr")
async def run_ocr(file: UploadFile = File(...)):
contents = await file.read()
image = Image.open(io.BytesIO(contents))
text = pytesseract.image_to_string(image)
return {"text": text}
Note: The exact implementation details are covered in the premium video. The snippets above illustrate the general pattern.
Architecture Considerations
When running two separate services (Laravel + FastAPI), keep these points in mind:
- Networking: Both services need to be able to reach each other. In a Docker Compose setup, use service names as hostnames.
- Error handling: Always handle cases where the FastAPI service is unavailable — wrap your
Http::post()call in a try/catch and check$response->successful(). - Security: If the FastAPI service is internal only, bind it to
localhostor a private network and never expose it publicly without authentication. - Timeouts: OCR on large images can be slow. Set an appropriate timeout on the Laravel
Httpclient:Http::timeout(30)->attach(...).
Key Takeaways
- Laravel's
Httpfacade makes it straightforward to send multipart file uploads to any external API. - FastAPI is a lightweight, production-ready choice for wrapping Python ML or OCR scripts as HTTP services.
- Separating concerns — Laravel handles the web layer, Python handles the heavy processing — keeps both codebases clean.
- The pattern is reusable: swap OCR for any other Python capability (image classification, NLP, PDF parsing).
- A repository is included with the tutorial, giving you a working starting point.
Full tutorial (video + repository) available at: https://laraveldaily.com/post/laravel-python-fastapi-image-ocr-demo