Skip to content

Latest commit

 

History

53 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LeapOCR Go SDK

Go Reference Go Report Card License: MIT

Official Go SDK for LeapOCR - Transform documents into structured data using AI-powered OCR.

Overview

LeapOCR provides enterprise-grade document processing with AI-powered data extraction. This SDK offers a Go-native interface for seamless integration into your applications.

Installation

go get github.com/leapocr/leapocr-go

Quick Start

Prerequisites

Basic Example

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/leapocr/leapocr-go"
)

func main() {
    // Initialize the SDK with your API key
    client, err := ocr.New(os.Getenv("LEAPOCR_API_KEY"))
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Submit a document for processing
    job, err := client.ProcessURL(ctx,
        "https://example.com/document.pdf",
        ocr.WithFormat(ocr.FormatStructured),
        ocr.WithModel(ocr.ModelStandardV2),
        ocr.WithSchema(map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "title": map[string]interface{}{"type": "string"},
            },
            "required": []interface{}{"title"},
        }),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Wait for processing to complete
    result, err := client.WaitUntilDone(ctx, job.ID)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Extracted data: %+v\n", result.Data)

    // Optional: Delete the job to remove sensitive data
    if err := client.DeleteJob(ctx, job.ID); err != nil {
        log.Printf("Failed to delete job: %v", err)
    }
}

Key Features

  • Idiomatic Go API - Clean, type-safe interface following Go best practices
  • Multiple Processing Formats - Structured data extraction or markdown output
  • Flexible Model Selection - Choose from standard, pro, or custom AI models
  • Custom Schema Support - Define extraction schemas for your specific use case
  • Built-in Retry Logic - Automatic handling of transient failures
  • Context Support - Full context.Context integration for timeouts and cancellation
  • Direct File Upload - Efficient multipart uploads for local files
  • Webhook Verification Helper - Verify incoming X-R2-Signature headers with the raw request body

Processing Models

Use WithModel() to specify a model, or WithModelString() for custom models. Defaults to ModelStandardV2.

Usage Examples

Processing from URL

ctx := context.Background()

job, err := client.ProcessURL(ctx,
    "https://example.com/invoice.pdf",
    ocr.WithFormat(ocr.FormatStructured),
    ocr.WithModel(ocr.ModelStandardV2),
    ocr.WithSchema(map[string]interface{}{
        "type": "object",
        "properties": map[string]interface{}{
            "invoice_number": map[string]interface{}{"type": "string"},
            "invoice_date":   map[string]interface{}{"type": "string"},
            "total_amount":   map[string]interface{}{"type": "number"},
        },
        "required": []interface{}{"invoice_number", "total_amount"},
    }),
)
if err != nil {
    log.Fatal(err)
}

result, err := client.WaitUntilDone(ctx, job.ID)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Processing completed in %v\n", result.Duration)
fmt.Printf("Credits used: %d\n", result.Credits)
fmt.Printf("Data: %+v\n", result.Data)

Processing Local Files

file, err := os.Open("invoice.pdf")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

job, err := client.ProcessFile(ctx, file, "invoice.pdf",
    ocr.WithFormat(ocr.FormatStructured),
    ocr.WithModel(ocr.ModelProV2),
    ocr.WithSchema(map[string]interface{}{
        "invoice_number": "string",
        "total_amount":   "number",
        "invoice_date":   "string",
        "vendor_name":    "string",
    }),
)

Using Templates

Use pre-configured templates for common document types:

// Use an existing template by slug
job, err := client.ProcessFile(ctx, file, "invoice.pdf",
    ocr.WithTemplateSlug("invoice-template"),
)

Custom Schema Extraction

Define custom extraction schemas for specific use cases:

schema := map[string]interface{}{
    "type": "object",
    "properties": map[string]interface{}{
        "patient_name": map[string]interface{}{"type": "string"},
        "date_of_birth": map[string]interface{}{"type": "string"},
        "medications": map[string]interface{}{
            "type": "array",
            "items": map[string]interface{}{
                "type": "object",
                "properties": map[string]interface{}{
                    "name": map[string]interface{}{"type": "string"},
                    "dosage": map[string]interface{}{"type": "string"},
                },
            },
        },
    },
}

job, err := client.ProcessFile(ctx, file, "medical-record.pdf",
    ocr.WithFormat(ocr.FormatStructured),
    ocr.WithSchema(schema),
)

Output Formats

Format Description Use Case
FormatStructured Single JSON object Extract specific fields across entire document
FormatMarkdown Text per page Convert document to readable text

Monitoring Job Progress

// Poll for status updates
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()

for {
    status, err := client.GetJobStatus(ctx, job.ID)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Status: %s (%.1f%% complete)\n", status.Status, status.Progress)

    if status.Status == "completed" {
        result, _ := client.GetJobResult(ctx, job.ID)
        fmt.Println("Processing complete!")
        break
    }

    <-ticker.C
}

Deleting Jobs

Delete jobs to remove sensitive data and free up storage. Jobs and their associated files are automatically deleted after 7 days, but you can delete them immediately after processing:

// Process and delete immediately after retrieving results
result, err := client.WaitUntilDone(ctx, job.ID)
if err != nil {
    log.Fatal(err)
}

// Use the result
fmt.Printf("Extracted data: %+v\n", result.Data)

// Delete the job (redacts content and marks as deleted)
err = client.DeleteJob(ctx, job.ID)
if err != nil {
    log.Printf("Failed to delete job: %v", err)
}

For more examples, see the examples/ directory.

Configuration

Custom Configuration

config := &ocr.Config{
    APIKey:     "your-api-key",
    BaseURL:    "https://api.leapocr.com",
    HTTPClient: &http.Client{Timeout: 60 * time.Second},
    UserAgent:  "my-app/1.0",
    Timeout:    30 * time.Second,
}

client, err := ocr.NewSDK(config)

Environment Variables

export LEAPOCR_API_KEY="your-api-key"
export OCR_BASE_URL="https://api.leapocr.com"  # optional

Error Handling

The SDK provides typed errors for robust error handling:

result, err := client.WaitUntilDone(ctx, job.ID)
if err != nil {
    if sdkErr, ok := err.(*ocr.SDKError); ok {
        switch sdkErr.Type {
        case ocr.ErrorTypeAuth:
            log.Fatal("Authentication failed - check your API key")
        case ocr.ErrorTypeValidation:
            log.Printf("Validation error: %s", sdkErr.Message)
        case ocr.ErrorTypeNetwork:
            if sdkErr.IsRetryable() {
                // Retry the operation
            }
        case ocr.ErrorTypeProcessing:
            log.Printf("Processing failed: %s", sdkErr.Message)
        }
    }
}

Error Types

  • ErrorTypeInvalidConfig - Configuration errors
  • ErrorTypeAuth - Authentication failures
  • ErrorTypeValidation - Input validation errors
  • ErrorTypeNetwork - Network/connectivity issues (retryable)
  • ErrorTypeProcessing - Document processing errors
  • ErrorTypeTimeout - Operation timeouts

Webhook Signature Verification

Use VerifyWebhookSignature with the raw request body exactly as received. LeapOCR sends customer webhooks with X-Webhook-Signature and X-Webhook-Timestamp, and signs timestamp + "." + rawBody with your webhook secret.

package main

import (
    "encoding/json"
    "io"
    "net/http"
    "os"

    ocr "github.com/leapocr/leapocr-go"
)

func webhookHandler(w http.ResponseWriter, r *http.Request) {
    body, err := io.ReadAll(r.Body)
    if err != nil {
        http.Error(w, "failed to read request body", http.StatusBadRequest)
        return
    }

    if !ocr.VerifyWebhookSignature(
        body,
        r.Header.Get("X-Webhook-Signature"),
        r.Header.Get("X-Webhook-Timestamp"),
        os.Getenv("LEAPOCR_WEBHOOK_SECRET"),
    ) {
        http.Error(w, "invalid signature", http.StatusUnauthorized)
        return
    }

    var payload map[string]any
    if err := json.Unmarshal(body, &payload); err != nil {
        http.Error(w, "invalid JSON", http.StatusBadRequest)
        return
    }

    w.WriteHeader(http.StatusOK)
}

Do not verify against re-serialized JSON. Use the original body bytes and the timestamp header from the HTTP request.

API Reference

Full API documentation is available at pkg.go.dev/github.com/leapocr/leapocr-go.

Core Methods

// Initialize SDK
New(apiKey string) (*SDK, error)
NewSDK(config *Config) (*SDK, error)

// Process documents
ProcessURL(ctx context.Context, url string, opts ...ProcessingOption) (*Job, error)
ProcessFile(ctx context.Context, file io.Reader, filename string, opts ...ProcessingOption) (*Job, error)

// Job management
GetJobStatus(ctx context.Context, jobID string) (*JobStatus, error)
GetJobResult(ctx context.Context, jobID string) (*OCRResult, error)
WaitUntilDone(ctx context.Context, jobID string) (*OCRResult, error)
DeleteJob(ctx context.Context, jobID string) error

Processing Options

WithFormat(format Format)                 // Set output format
WithModel(model Model)                    // Set OCR model
WithModelString(model string)             // Set custom model
WithSchema(schema map[string]interface{}) // Define extraction schema
WithInstructions(instructions string)     // Add processing instructions
WithTemplateSlug(templateSlug string)     // Use existing template

Development

Prerequisites

Setup

# Clone the repository
git clone https://github.com/leapocr/leapocr-go.git
cd leapocr-go

# Install dependencies
make install

# Run tests
make test

Common Tasks

make build              # Build the SDK
make test               # Run unit tests
make test-coverage      # Generate coverage report
make test-integration   # Run integration tests (requires API key)
make lint               # Run linters
make format             # Format code
make examples           # Build examples

Code Generation

The SDK is partially generated from the OpenAPI specification:

make generate           # Regenerate client from OpenAPI spec
make clean              # Remove generated files

Contributing

We welcome contributions! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

See CONTRIBUTING.md for detailed guidelines.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support & Resources


Version: 0.0.5

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages