Docling/.actor/README.md
Václav Vančura 772487f9c9
feat(actor): Docling Actor on Apify infrastructure (#875)
* fix: Improve OCR results, stricten criteria before dropping bitmap areas  (#719)

fix: Properly care for all bitmap elements in OCR

Signed-off-by: Christoph Auer <cau@zurich.ibm.com>
Signed-off-by: Adam Kliment <adam@netmilk.net>

* chore: bump version to 2.15.1 [skip ci]

* Actor: Initial implementation

Signed-off-by: Václav Vančura <commit@vancura.dev>
Signed-off-by: Adam Kliment <adam@netmilk.net>

* Actor: .dockerignore update

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding the Actor badge

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Moving the badge where it belongs

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Documentation update

Signed-off-by: Václav Vančura <commit@vancura.dev>
Signed-off-by: Adam Kliment <adam@netmilk.net>

* Actor: Switching Docker to python:3.11-slim-bookworm

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Enhance Docker security with proper user permissions

- Set proper ownership and permissions for runtime directory.
- Switch to non-root user for enhanced security.
- Use `--chown` flag in COPY commands to maintain correct file ownership.
- Ensure all files and directories are owned by `appuser`.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Optimize Dockerfile with security and size improvements

- Combine RUN commands to reduce image layers and overall size.
- Add non-root user `appuser` for improved security.
- Use `--no-install-recommends` flag to minimize installed packages.
- Install only necessary dependencies in a single RUN command.
- Maintain proper cleanup of package lists and caches.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Add Docker image metadata labels

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Update dependencies with fixed versions

Upgrade pip and npm to latest versions, pin docling to 2.15.1 and apify-cli to 2.7.1 for better stability and reproducibility. This change helps prevent unexpected behavior from dependency updates and ensures consistent builds across environments.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Fix apify-cli version problem

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Create Apify user home directory in Docker setup

Add and configure `/home/appuser/.apify` directory with proper permissions for the appuser in the Docker container. This ensures the Apify SDK has a writable home directory for storing its configuration and temporary files.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Update Docker configuration for improved security

- Add `ACTOR_PATH_IN_DOCKER_CONTEXT` argument to ignore the Apify-tooling related warning.
- Improve readability with consistent formatting and spacing in RUN commands.
- Enhance security by properly setting up appuser home directory and permissions.
- Streamline directory structure and ownership for runtime operations.
- Remove redundant `.apify` directory creation as it's handled by the CLI.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Improve shell script robustness and error handling

The shell script has been enhanced with better error handling, input validation, and cleanup procedures. Key improvements include:

- Added proper quoting around variables to prevent word splitting.
- Improved error messages and logging functionality.
- Implemented a cleanup trap to ensure temporary files are removed.
- Enhanced validation of input parameters and output formats.
- Added better handling of the log file and its storage.
- Improved command execution with proper evaluation.
- Added comments for better code readability and maintenance.
- Fixed potential security issues with proper variable expansion.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Improve script logging and error handling

- Initialize log file at `/tmp/docling.log` and redirect all output to it
- Remove exit on error trap, now only logs error line numbers
- Use temporary directory for timestamp file
- Capture Docling exit code and handle errors more gracefully
- Update log file references to use `LOG_FILE` variable
- Remove local log file during cleanup

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Updating Docling to 2.17.0

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding README

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: README update

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Enhance Dockerfile with additional utilities and env vars

- Add installation of `time` and `procps` packages for better resource monitoring.
- Set environment variables `PYTHONUNBUFFERED`, `MALLOC_ARENA_MAX`, and `EASYOCR_DOWNLOAD_CACHE` for improved performance.
- Create a cache directory for EasyOCR to optimize storage usage.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: README update

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding the Apify FirstPromoter integration

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding the "Run on Apify" button

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Fixing example PDF document URLs

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Documentation update

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding input document URL validation

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Fix quoting in `DOC_CONVERT_CMD` variable

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Documentation update

Removing the dollar signs due to what we discovered at https://cirosantilli.com/markdown-style-guide/#dollar-signs-in-shell-code

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Add specific error codes for better error handling

- `ERR_INVALID_INPUT` for missing document URL
- `ERR_URL_INACCESSIBLE` for inaccessible URLs
- `ERR_DOCLING_FAILED` for Docling command failures
- `ERR_OUTPUT_MISSING` for missing or empty output files
- `ERR_STORAGE_FAILED` for failures in storing the output document

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Enhance error handling and data logging

- Add `apify pushData` calls to log errors when the document URL is missing or inaccessible.
- Introduce dataset record creation with processing results, including a success status and output file URL.
- Modify completion message to indicate successful processing and provide a link to the results.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Normalize key-value store terminology

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Enhance `README.md` with output details

Added detailed information about the Actor's output storage to the `README.md`. This includes specifying where processed documents, processing logs, and dataset records are stored.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding CHANGELOG.md

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Adding dataset schema

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Update README with output URL details

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Fix the Apify call syntax and final result URL message

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Add section on Actors to README

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Replace Docling CLI with docling-serve API

This commit transitions the Actor from using the full Docling CLI package to the more lightweight docling-serve API. Key changes include:

- Redesign Dockerfile to use docling-serve as base image
- Update actor.sh to communicate with API instead of running CLI commands
- Improve content type handling for various output formats
- Update input schema to align with API parameters
- Reduce Docker image size from ~6GB to ~600MB
- Update documentation and changelog to reflect architectural changes

The image size reduction will make the Actor more cost-effective for users while maintaining all existing functionality including OCR capabilities.

Issue: No official docling-serve Docker image is currently available, which will be addressed in a future commit.
Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Overhaul the implementation using official docling-serve image

This commit completely revamps the Actor implementation with two major improvements:

1) CRITICAL CHANGE: Switch to official docling-serve image
   * Now using quay.io/ds4sd/docling-serve-cpu:latest as base image
   * Eliminates need for custom docling installation
   * Ensures compatibility with latest docling-serve features
   * Provides more reliable and consistent document processing

2) Fix Apify Actor KVS storage issues:
   * Standardize key names to follow Apify conventions:
     - Change "OUTPUT_RESULT" to "OUTPUT"
     - Change "DOCLING_LOG" to "LOG"
   * Add proper multi-stage Docker build:
     - First stage builds dependencies including apify-cli
     - Second stage uses official image and adds only necessary tools
   * Fix permission issues in Docker container:
     - Set up proper user and directory permissions
     - Create writable directories for temporary files and models
     - Configure environment variables for proper execution

3) Solve EACCES permission errors during CLI version checks:
   * Create temporary HOME directory with proper write permissions
   * Set APIFY_DISABLE_VERSION_CHECK=1 environment variable
   * Add NODE_OPTIONS="--no-warnings" to suppress update checks
   * Support --no-update-notifier CLI flag when available

4) Improve code organization and reliability:
   * Create reusable upload_to_kvs() function for all KVS operations
   * Ensure log files are uploaded before tools directory is removed
   * Set proper MIME types based on output format
   * Add detailed error reporting and proper cleanup
   * Display final output URLs for easy verification

This major refactoring significantly improves reliability and maintainability by leveraging the official docling-serve image while solving persistent permission and storage issues. The Actor now properly follows Apify standards while providing a more robust document processing pipeline.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Refactor `actor.sh` and add `docling_processor.py`

Refactor the `actor.sh` script to modularize functions for finding the Apify CLI, setting up a temporary environment, and cleaning it up. Introduce a new function, `get_actor_input()`, to handle input detection more robustly. Replace inline Python conversion logic with an external script, `docling_processor.py`, for processing documents via the docling-serve API.

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Update CHANGELOG and README for Docker and API changes

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Removing obsolete actor.json keys

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Fixed input getter

Signed-off-by: Adam Kliment <adam@netmilk.net>

* Actor: Always output a zip

Signed-off-by: Adam Kliment <adam@netmilk.net>

* Actor: Resolving conflicts with main

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Resolving conflicts with main (pass 2)

Signed-off-by: Václav Vančura <commit@vancura.dev>

* Actor: Updated main Readme and Actor Readme

Signed-off-by: Adam Kliment <adam@netmilk.net>

---------

Signed-off-by: Christoph Auer <cau@zurich.ibm.com>
Signed-off-by: Adam Kliment <adam@netmilk.net>
Signed-off-by: Václav Vančura <commit@vancura.dev>
Co-authored-by: Christoph Auer <60343111+cau-git@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Adam Kliment <adam@netmilk.net>
2025-03-18 10:17:44 +01:00

9.6 KiB

Docling Actor on Apify

Docling Actor

This Actor (specification v1) wraps the Docling project to provide serverless document processing in the cloud. It can process complex documents (PDF, DOCX, images) and convert them into structured formats (Markdown, JSON, HTML, Text, or DocTags) with optional OCR support.

What are Actors?

Actors are serverless microservices running on the Apify Platform. They are based on the Actor SDK and can be found in the Apify Store. Learn more about Actors in the Apify Whitepaper.

Table of Contents

  1. Features
  2. Usage
  3. Input Parameters
  4. Output
  5. Performance & Resources
  6. Troubleshooting
  7. Local Development
  8. Architecture
  9. License
  10. Acknowledgments
  11. Security Considerations

Features

  • Leverages the official docling-serve-cpu Docker image for efficient document processing
  • Processes multiple document formats:
    • PDF documents (scanned or digital)
    • Microsoft Office files (DOCX, XLSX, PPTX)
    • Images (PNG, JPG, TIFF)
    • Other text-based formats
  • Provides OCR capabilities for scanned documents
  • Exports to multiple formats:
    • Markdown
    • JSON
    • HTML
    • Plain Text
    • DocTags (structured format)
  • No local setup needed—just provide input via a simple JSON config

Usage

Using Apify Console

  1. Go to the Apify Actor page.
  2. Click "Run".
  3. In the input form, fill in:
    • The URL of the document.
    • Output format (md, json, html, text, or doctags).
    • OCR boolean toggle.
  4. The Actor will run and produce its outputs in the default key-value store under the key OUTPUT.

Using Apify API

curl --request POST \
  --url "https://api.apify.com/v2/acts/vancura~docling/run" \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --data '{
  "options": {
    "to_formats": ["md", "json", "html", "text", "doctags"]
  },
  "http_sources": [
    {"url": "https://vancura.dev/assets/actor-test/facial-hairstyles-and-filtering-facepiece-respirators.pdf"},
    {"url": "https://arxiv.org/pdf/2408.09869"}
  ]
}'

Using Apify CLI

apify call vancura/docling --input='{
  "options": {
    "to_formats": ["md", "json", "html", "text", "doctags"]
  },
  "http_sources": [
    {"url": "https://vancura.dev/assets/actor-test/facial-hairstyles-and-filtering-facepiece-respirators.pdf"},
    {"url": "https://arxiv.org/pdf/2408.09869"}
  ]
}'

Input Parameters

The Actor accepts a JSON schema matching the file .actor/input_schema.json. Below is a summary of the fields:

Field Type Required Default Description
http_sources object Yes None https://github.com/DS4SD/docling-serve?tab=readme-ov-file#url-endpoint
options object No None https://github.com/DS4SD/docling-serve?tab=readme-ov-file#common-parameters

Example Input

{
  "options": {
    "to_formats": ["md", "json", "html", "text", "doctags"]
  },
  "http_sources": [
    {"url": "https://vancura.dev/assets/actor-test/facial-hairstyles-and-filtering-facepiece-respirators.pdf"},
    {"url": "https://arxiv.org/pdf/2408.09869"}
  ]
}

Output

The Actor provides three types of outputs:

  1. Processed Documents in a ZIP - The Actor will provide the direct URL to your result in the run log, looking like:

    You can find your results at: 'https://api.apify.com/v2/key-value-stores/[YOUR_STORE_ID]/records/OUTPUT'
    
  2. Processing Log - Available in the key-value store as DOCLING_LOG

  3. Dataset Record - Contains processing metadata with:

    • Direct link to the processed output zip file
    • Processing status

You can access the results in several ways:

  1. Direct URL (shown in Actor run logs):
https://api.apify.com/v2/key-value-stores/[STORE_ID]/records/OUTPUT
  1. Programmatically via Apify CLI:
apify key-value-stores get-value OUTPUT
  1. Dataset - Check the "Dataset" tab in the Actor run details to see processing metadata

Example Outputs

Markdown (md)

# Document Title

## Section 1
Content of section 1...

## Section 2
Content of section 2...

JSON

{
    "title": "Document Title",
    "sections": [
        {
            "level": 1,
            "title": "Section 1",
            "content": "Content of section 1..."
        }
    ]
}

HTML

<h1>Document Title</h1>
<h2>Section 1</h2>
<p>Content of section 1...</p>

Processing Logs (DOCLING_LOG)

The Actor maintains detailed processing logs including:

  • API request and response details
  • Processing steps and timing
  • Error messages and stack traces
  • Input validation results

Access logs via:

apify key-value-stores get-record DOCLING_LOG

Performance & Resources

  • Docker Image Size: ~4GB
  • Memory Requirements:
    • Minimum: 2 GB RAM
    • Recommended: 4 GB RAM for large or complex documents
  • Processing Time:
    • Simple documents: 15-30 seconds
    • Complex PDFs with OCR: 1-3 minutes
    • Large documents (100+ pages): 3-10 minutes

Troubleshooting

Common issues and solutions:

  1. Document URL Not Accessible

    • Ensure the URL is publicly accessible
    • Check if the document requires authentication
    • Verify the URL leads directly to the document
  2. OCR Processing Fails

    • Verify the document is not password-protected
    • Check if the image quality is sufficient
    • Try processing with OCR disabled
  3. API Response Issues

    • Check the logs for detailed error messages
    • Ensure the document format is supported
    • Verify the URL is correctly formatted
  4. Output Format Issues

    • Verify the output format is supported
    • Check if the document structure is compatible
    • Review the DOCLING_LOG for specific errors

Error Handling

The Actor implements comprehensive error handling:

  • Detailed error messages in DOCLING_LOG
  • Proper exit codes for different failure scenarios
  • Automatic cleanup on failure
  • Dataset records with processing status

Local Development

If you wish to develop or modify this Actor locally:

  1. Clone the repository.

  2. Ensure Docker is installed.

  3. The Actor files are located in the .actor directory:

    • Dockerfile - Defines the container environment
    • actor.json - Actor configuration and metadata
    • actor.sh - Main execution script that starts the docling-serve API and orchestrates document processing
    • input_schema.json - Input parameter definitions
    • dataset_schema.json - Dataset output format definition
    • CHANGELOG.md - Change log documenting all notable changes
    • README.md - This documentation
  4. Run the Actor locally using:

    apify run
    

Actor Structure

.actor/
├── Dockerfile           # Container definition
├── actor.json           # Actor metadata
├── actor.sh             # Execution script (also starts docling-serve API)
├── input_schema.json    # Input parameters
├── dataset_schema.json  # Dataset output format definition
├── docling_processor.py # Python script for API communication
├── CHANGELOG.md         # Version history and changes
└── README.md            # This documentation

Architecture

This Actor uses a lightweight architecture based on the official quay.io/ds4sd/docling-serve-cpu Docker image:

  • Base Image: quay.io/ds4sd/docling-serve-cpu:latest (~4GB)
  • Multi-Stage Build: Uses a multi-stage Docker build to include only necessary tools
  • API Communication: Uses the RESTful API provided by docling-serve
  • Request Flow:
    1. The actor script starts the docling-serve API on port 5001
    2. Performs health checks to ensure the API is running
    3. Processes the input parameters
    4. Creates a JSON payload for the docling-serve API with proper format:
      {
        "options": {
          "to_formats": ["md"],
          "do_ocr": true
        },
        "http_sources": [{"url": "https://example.com/document.pdf"}]
      }
      
    5. Makes a POST request to the /v1alpha/convert/source endpoint
    6. Processes the response and stores it in the key-value store
  • Dependencies:
    • Node.js for Apify CLI
    • Essential tools (curl, jq, etc.) copied from build stage
  • Security: Runs as a non-root user for enhanced security

License

This wrapper project is under the MIT License, matching the original Docling license. See LICENSE for details.

Acknowledgments

Security Considerations

  • Actor runs under a non-root user for enhanced security
  • Input URLs are validated before processing
  • Temporary files are securely managed and cleaned up
  • Process isolation through Docker containerization
  • Secure handling of processing artifacts