DocumentOCR1 / README.md
PrathameshRaut's picture
Update README.md
673b3ab verified
|
Raw
History Blame Contribute Delete
13.8 kB
metadata
title: GLM-OCR REST API
emoji: 📄
colorFrom: blue
colorTo: indigo
sdk: docker
sdk_version: latest
app_file: app.py
pinned: false

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference

GLM-OCR REST API

A high-performance OCR API built with FastAPI and GLM-4V for extracting text, tables, and formulas from documents.

Features

Multi-format Support

  • Images: JPG, JPEG, PNG, GIF, BMP, WebP
  • Documents: PDF, DOCX
  • Automatic conversion to images for processing

🎯 Extraction Types (in order: Table → Text → Formula)

  • Table Recognition: Extract structured table data
  • Text Recognition: Extract all text content
  • Formula Recognition: Extract mathematical formulas

🚀 Advanced Features

  • Batch processing (up to 10 files)
  • Structured information extraction with JSON schema
  • Page-by-page processing for multi-page documents
  • CORS enabled for web integration

🔗 Interactive API Documentation

Once deployed, access the interactive Swagger UI to test all endpoints:

Swagger UI (Recommended)

  • Local: http://localhost:7860/docs
  • Deployed Space: https://huggingface.co/spaces/your-username/glm-ocr-api/api/docs

ReDoc (Alternative)

  • Local: http://localhost:7860/redoc
  • Deployed Space: https://huggingface.co/spaces/your-username/glm-ocr-api/api/redoc

The Swagger UI allows you to:

  • ✅ Browse all available endpoints
  • ✅ View request/response schemas
  • ✅ Test endpoints directly in browser
  • ✅ Download OpenAPI specification

Note: This application uses the new Hugging Face router endpoint (https://router.huggingface.co). The old api-inference.huggingface.co endpoint is deprecated.

Setup

Prerequisites

  • Python 3.8+
  • Hugging Face API Token (for GLM-OCR model access)

Installation

  1. Clone the repository
git clone <your-repo-url>
cd <repo-name>
  1. Install dependencies
pip install -r requirements.txt
  1. Configure environment
# Copy the example env file
cp .env.example .env

# Edit .env and add your Hugging Face token
# HF_API_TOKEN=your_token_here
  1. Run the server
python app.py

The API will be available at: http://localhost:7860

API Documentation

Base URL

http://localhost:7860

Endpoints

1. Health Check

Check if the API is running.

Endpoint:

GET /health

Response:

{
  "status": "healthy",
  "timestamp": "2024-01-15T10:30:45.123456",
  "model": "PrathameshRaut/DocumentOCR"
}

2. Extract Text/Tables/Formulas

Extract all content from a document (table, text, formula in order).

Endpoint:

POST /api/ocr/extract

Request:

  • Content-Type: multipart/form-data
  • Parameter: file (UploadFile)

Supported Formats:

  • Images: .jpg, .jpeg, .png, .gif, .bmp, .webp
  • PDFs: .pdf
  • Documents: .docx, .doc

cURL Example:

curl -X POST "http://localhost:7860/api/ocr/extract" \
  -F "file=@path/to/your/document.pdf"

Python Example:

import requests

url = "http://localhost:7860/api/ocr/extract"
files = {"file": open("document.pdf", "rb")}

response = requests.post(url, files=files)
data = response.json()

# Process results
for page in data["pages"]:
    print(f"Page {page['page_number']}:")
    print(f"Tables: {page['table']}")
    print(f"Text: {page['text']}")
    print(f"Formulas: {page['formula']}")

Response Example:

{
  "filename": "document.pdf",
  "file_type": ".pdf",
  "total_pages": 1,
  "extraction_timestamp": "2024-01-15T10:30:45.123456",
  "pages": [
    {
      "page_number": 1,
      "table": "Extracted table content here...",
      "text": "Extracted text content here...",
      "formula": "Extracted formula content here..."
    }
  ]
}

3. Extract Structured Information

Extract information based on a custom JSON schema.

Endpoint:

POST /api/ocr/extract-structured

Request:

  • Content-Type: multipart/form-data
  • Parameters:
    • file (UploadFile): Document to process
    • schema (string): JSON schema defining what to extract

Schema Example:

{
  "id_number": "",
  "name": "",
  "date_of_birth": "",
  "address": {
    "street": "",
    "city": "",
    "state": "",
    "zip_code": ""
  }
}

cURL Example:

SCHEMA='{"id_number":"","name":"","date_of_birth":""}'

curl -X POST "http://localhost:7860/api/ocr/extract-structured" \
  -F "file=@path/to/id_card.jpg" \
  -F "schema=$SCHEMA"

Python Example:

import requests
import json

url = "http://localhost:7860/api/ocr/extract-structured"

schema = {
    "id_number": "",
    "name": "",
    "date_of_birth": "",
    "address": {
        "street": "",
        "city": "",
        "state": ""
    }
}

files = {"file": open("id_card.jpg", "rb")}
data = {"schema": json.dumps(schema)}

response = requests.post(url, files=files, data=data)
result = response.json()

# Access extracted structured data
for page in result["pages"]:
    print(page["extracted_data"])

Response Example:

{
  "filename": "id_card.jpg",
  "file_type": ".jpg",
  "total_pages": 1,
  "extraction_timestamp": "2024-01-15T10:30:45.123456",
  "pages": [
    {
      "page_number": 1,
      "extracted_data": {
        "id_number": "12345678",
        "name": "John Doe",
        "date_of_birth": "1990-01-15",
        "address": {
          "street": "123 Main St",
          "city": "New York",
          "state": "NY"
        }
      }
    }
  ]
}

4. Batch Processing

Process multiple files at once (up to 10 files per request).

Endpoint:

POST /api/ocr/batch

Request:

  • Content-Type: multipart/form-data
  • Parameter: files (List[UploadFile])

cURL Example:

curl -X POST "http://localhost:7860/api/ocr/batch" \
  -F "files=@document1.pdf" \
  -F "files=@document2.jpg" \
  -F "files=@document3.docx"

Python Example:

import requests

url = "http://localhost:7860/api/ocr/batch"

files = [
    ("files", open("document1.pdf", "rb")),
    ("files", open("document2.jpg", "rb")),
    ("files", open("document3.docx", "rb"))
]

response = requests.post(url, files=files)
batch_results = response.json()

# Process results for each file
for file_result in batch_results["results"]:
    print(f"File: {file_result['filename']}")
    print(f"Status: {file_result['status']}")
    if file_result['status'] == 'success':
        for page in file_result['pages']:
            print(f"  Page {page['page_number']}:")
            print(f"    Table: {page['table']}")
            print(f"    Text: {page['text']}")
            print(f"    Formula: {page['formula']}")

Response Example:

{
  "batch_timestamp": "2024-01-15T10:30:45.123456",
  "total_files": 3,
  "results": [
    {
      "filename": "document1.pdf",
      "file_type": ".pdf",
      "status": "success",
      "total_pages": 2,
      "pages": [
        {
          "page_number": 1,
          "table": "...",
          "text": "...",
          "formula": "..."
        }
      ]
    },
    {
      "filename": "document2.jpg",
      "status": "error",
      "error": "Unsupported file type"
    }
  ]
}

5. API Information

Get details about the API and supported formats.

Endpoint:

GET /api/info

Response:

{
  "api_name": "GLM-OCR API",
  "version": "1.0.0",
  "model": "PrathameshRaut/DocumentOCR",
  "supported_formats": {
    "images": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"],
    "documents": [".docx", ".doc"],
    "pdfs": [".pdf"]
  },
  "endpoints": {
    "extract": "/api/ocr/extract",
    "extract_structured": "/api/ocr/extract-structured",
    "batch": "/api/ocr/batch",
    "health": "/health",
    "info": "/api/info"
  },
  "extraction_order": ["table", "text", "formula"]
}

Extraction Order

The API extracts content in the following order for each page:

  1. Table - Structured table data
  2. Text - All text content
  3. Formula - Mathematical formulas

This order is maintained in all responses.


JavaScript/Frontend Integration

Fetch Example

async function extractOCR(file) {
  const formData = new FormData();
  formData.append('file', file);
  
  const response = await fetch('http://localhost:7860/api/ocr/extract', {
    method: 'POST',
    body: formData
  });
  
  const data = await response.json();
  return data;
}

// Usage
document.getElementById('fileInput').addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const result = await extractOCR(file);
  console.log(result);
});

Axios Example

import axios from 'axios';

async function extractOCR(file) {
  const formData = new FormData();
  formData.append('file', file);
  
  try {
    const response = await axios.post(
      'http://localhost:7860/api/ocr/extract',
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    );
    return response.data;
  } catch (error) {
    console.error('OCR extraction failed:', error);
  }
}

Error Handling

The API returns appropriate HTTP status codes:

  • 200 - Successful extraction
  • 400 - Bad request (invalid file, unsupported format, etc.)
  • 500 - Server error

Error Response Example:

{
  "detail": "Unsupported file type. Supported: .jpg, .jpeg, .png, .gif, .bmp, .webp, .pdf, .docx, .doc"
}

🔧 Troubleshooting & Debugging

Issue: Empty extraction results (all fields are "")

Solution:

  1. Test model connection:
curl http://localhost:7860/debug/test-model

This will test if your HF_API_TOKEN is set correctly and show the actual model response format.

  1. Check HF_API_TOKEN:
# Local development
echo $HF_API_TOKEN

# Should not be empty. If empty, set it:
export HF_API_TOKEN="your_actual_token_here"
  1. View debug logs: The API prints [DEBUG] messages that show:
  • Actual model response status codes
  • Response JSON structure
  • Error messages from the model

Look for these logs to understand what the model is returning.

  1. Verify token has model access:

Issue: Model endpoint not responding

Solution:

  1. Check the endpoint is correct:
https://api-inference.huggingface.co/models/PrathameshRaut/DocumentOCR
  1. Test with curl:
curl -X POST "https://api-inference.huggingface.co/models/PrathameshRaut/DocumentOCR" \
  -H "Authorization: Bearer YOUR_HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"image": "data:image/png;base64,...", "text": "Extract text"}}'
  1. Possible reasons:
    • Model is not deployed/not available
    • Token doesn't have access to this model
    • Model requires a specific request format

Issue: Timeout during extraction

Solution:

  1. Increase timeout in client code:
response = requests.post(
    "http://localhost:7860/api/ocr/extract",
    files=files,
    timeout=180  # Increased from default 120
)
  1. File size:
    • Large PDFs (100+ pages) take longer
    • Keep files under 50MB
    • Try with a smaller test file first

Issue: "HF_API_TOKEN not set"

Local development:

export HF_API_TOKEN="hf_xxxxxxxxxxxx"
python app.py

Hugging Face Space:

  1. Go to Space Settings
  2. Click "Secrets"
  3. Add secret:

Debug Endpoint

Use this endpoint to test and debug:

curl http://localhost:7860/debug/test-model

Response shows:

  • If HF_API_TOKEN is set
  • Test extraction result
  • Actual model response format
  • Debugging suggestions

This is very helpful to understand what the model is returning.


Deployment on Hugging Face Spaces

  1. Create a new Space on Hugging Face

  2. Choose "Docker" as the runtime (or "Python" with requirements.txt)

  3. Upload these files:

    • app.py
    • requirements.txt
    • .env.example
  4. In Space settings, add your secret:

    • Add HF_API_TOKEN with your Hugging Face API token
  5. The Space will auto-deploy and be accessible at:

    • https://huggingface.co/spaces/your-username/your-space-name

Performance Tips

  • For large PDFs: Process page-by-page using the single extract endpoint
  • For many files: Use batch processing for efficiency
  • For production: Use appropriate timeout values in client code

Troubleshooting

Issue: "CUDA out of memory"

  • The model might need GPU. Ensure your Space has GPU enabled.

Issue: "HF_API_TOKEN not found"

  • Make sure to set the environment variable in Space secrets

Issue: Slow extraction

  • Model inference time depends on document complexity
  • PDF extraction is slower than image extraction
  • For large batches, consider increasing timeout values

Model Information

Model: PrathameshRaut/DocumentOCR

  • Built on GLM-4V
  • Supports document parsing and information extraction
  • Recognizes text, tables, and formulas

License

MIT License - Feel free to use and modify as needed.


Support

For issues or questions:

  1. Check the troubleshooting section
  2. Review error messages in API responses
  3. Check Hugging Face model documentation

Version History

v1.0.0

  • Initial release
  • Support for image, PDF, and DOCX files
  • Table, text, and formula extraction
  • Batch processing
  • Structured information extraction