264 lines
6.6 KiB
Bash
264 lines
6.6 KiB
Bash
#!/bin/bash
|
|
|
|
# PaddleOCR Document Parser Script
|
|
# Supports both sync and async modes
|
|
|
|
set -e
|
|
|
|
# Default values
|
|
file_type="image"
|
|
output_file=""
|
|
verbose="false"
|
|
async_mode="false"
|
|
|
|
# Function to display usage
|
|
usage() {
|
|
cat << EOF
|
|
Usage: $0 [OPTIONS] INPUT_FILE_PATH_OR_URL
|
|
|
|
Parse documents using PaddleOCR API
|
|
|
|
OPTIONS:
|
|
-t, --type TYPE File type (image, pdf) [default: image]
|
|
-o, --output FILE Output file [default: stdout]
|
|
-v, --verbose Verbose output
|
|
--async Use async mode (for large files/PDFs)
|
|
-h, --help Show this help message
|
|
|
|
ENVIRONMENT:
|
|
PADDLEOCR_ACCESS_TOKEN Required: API access token
|
|
PADDLEOCR_API_URL Required: Sync mode endpoint URL
|
|
PADDLEOCR_JOB_URL Required for async: Async endpoint URL
|
|
PADDLEOCR_MODEL Optional: Model name [default: PaddleOCR-VL-1.5]
|
|
|
|
SETUP:
|
|
1. Visit https://www.paddleocr.com to get API credentials
|
|
2. Set environment variables:
|
|
export PADDLEOCR_ACCESS_TOKEN="your_token"
|
|
export PADDLEOCR_API_URL="https://your-endpoint/layout-parsing"
|
|
|
|
EXAMPLES:
|
|
# Sync mode (default)
|
|
$0 document.jpg
|
|
$0 -t pdf document.pdf
|
|
$0 -o result.json document.jpg
|
|
|
|
# Async mode (for large files)
|
|
$0 --async large-document.pdf
|
|
|
|
EOF
|
|
}
|
|
|
|
# Parse command line arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-t|--type)
|
|
file_type="$2"
|
|
shift 2
|
|
;;
|
|
-o|--output)
|
|
output_file="$2"
|
|
shift 2
|
|
;;
|
|
-v|--verbose)
|
|
verbose="true"
|
|
shift
|
|
;;
|
|
--async)
|
|
async_mode="true"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
-*)
|
|
echo "Unknown option: $1"
|
|
usage
|
|
exit 1
|
|
;;
|
|
*)
|
|
input_file="$1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Validate input
|
|
if [[ -z "$input_file" ]]; then
|
|
echo "Error: Input file path or URL is required"
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
# Check required environment variables
|
|
if [[ -z "$PADDLEOCR_ACCESS_TOKEN" ]]; then
|
|
echo "Error: PADDLEOCR_ACCESS_TOKEN environment variable is required"
|
|
echo "Get it from: https://www.paddleocr.com"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "$PADDLEOCR_API_URL" ]]; then
|
|
echo "Error: PADDLEOCR_API_URL environment variable is required"
|
|
echo "Set it to your PaddleOCR API endpoint"
|
|
echo "Example: export PADDLEOCR_API_URL=\"https://your-endpoint.aistudio-app.com/layout-parsing\""
|
|
exit 1
|
|
fi
|
|
|
|
# Set optional defaults
|
|
PADDLEOCR_MODEL="${PADDLEOCR_MODEL:-PaddleOCR-VL-1.5}"
|
|
|
|
# Check if input is a URL or local file
|
|
if [[ "$input_file" =~ ^https?:// ]]; then
|
|
is_url="true"
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Input is a URL: $input_file" >&2
|
|
fi
|
|
else
|
|
is_url="false"
|
|
if [[ ! -f "$input_file" ]]; then
|
|
echo "Error: Input file not found: $input_file"
|
|
exit 1
|
|
fi
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Input is a local file: $input_file" >&2
|
|
fi
|
|
fi
|
|
|
|
# Use Python script for async mode
|
|
if [[ "$async_mode" == "true" ]]; then
|
|
if [[ -z "$PADDLEOCR_JOB_URL" ]]; then
|
|
echo "Error: PADDLEOCR_JOB_URL environment variable is required for async mode"
|
|
echo "Example: export PADDLEOCR_JOB_URL=\"https://your-endpoint.aistudio-app.com/api/v2/ocr/jobs\""
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Using async mode with model: $PADDLEOCR_MODEL" >&2
|
|
fi
|
|
|
|
# Get script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Run Python async parser
|
|
if [[ -n "$output_file" ]]; then
|
|
python3 "$SCRIPT_DIR/paddleocr_parse.py" --async-mode -o "$output_file" "$input_file"
|
|
else
|
|
python3 "$SCRIPT_DIR/paddleocr_parse.py" --async-mode "$input_file"
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
# Sync mode (bash implementation)
|
|
|
|
# Validate file type
|
|
case "$file_type" in
|
|
image|img) file_type_code=1 ;;
|
|
pdf) file_type_code=0 ;;
|
|
*)
|
|
echo "Error: Invalid file type '$file_type'. Supported: image, pdf"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Build payload - directly use URL or encode file
|
|
if [[ "$is_url" == "true" ]]; then
|
|
# Use URL directly in payload
|
|
payload=$(cat <<EOF
|
|
{
|
|
"file": "$input_file",
|
|
"fileType": $file_type_code,
|
|
"useDocOrientationClassify": false,
|
|
"useDocUnwarping": false
|
|
}
|
|
EOF
|
|
)
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Using URL directly in API request" >&2
|
|
fi
|
|
else
|
|
# Encode local file to base64
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Encoding $input_file to base64..." >&2
|
|
fi
|
|
|
|
file_base64=$(cat "$input_file" | base64 | tr -d '\n')
|
|
|
|
payload=$(cat <<EOF
|
|
{
|
|
"file": "$file_base64",
|
|
"fileType": $file_type_code,
|
|
"useDocOrientationClassify": false,
|
|
"useDocUnwarping": false
|
|
}
|
|
EOF
|
|
)
|
|
fi
|
|
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Making API request to: $PADDLEOCR_API_URL" >&2
|
|
echo "Payload size: ${#payload} bytes" >&2
|
|
fi
|
|
|
|
# Make API request
|
|
# Use temporary file to avoid "Argument list too long" error for large payloads
|
|
payload_file=$(mktemp)
|
|
echo "$payload" > "$payload_file"
|
|
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Request payload saved to temporary file: $payload_file" >&2
|
|
fi
|
|
|
|
# Use trap to ensure temporary file cleanup on script exit
|
|
cleanup() {
|
|
if [[ -f "$payload_file" ]]; then
|
|
rm -f "$payload_file"
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Cleaned up temporary file: $payload_file" >&2
|
|
fi
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
response=$(curl -s -X POST "$PADDLEOCR_API_URL" \
|
|
-m 600 \
|
|
--fail-with-body \
|
|
-H "Authorization: token $PADDLEOCR_ACCESS_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d @"$payload_file")
|
|
|
|
# Check for curl errors
|
|
curl_exit_code=$?
|
|
if [[ $curl_exit_code -ne 0 ]]; then
|
|
echo "Error: Curl request failed with code $curl_exit_code"
|
|
exit 1
|
|
fi
|
|
|
|
# Check response for errors using jq
|
|
if ! echo "$response" | jq -e . >/dev/null 2>&1; then
|
|
echo "Error: Invalid JSON response from API"
|
|
exit 1
|
|
fi
|
|
|
|
error_code=$(echo "$response" | jq -r '.errorCode // empty')
|
|
error_msg=$(echo "$response" | jq -r '.errorMsg // empty')
|
|
|
|
if [[ -n "$error_code" && "$error_code" != "0" ]]; then
|
|
echo "API Error ($error_code): $error_msg"
|
|
exit 1
|
|
fi
|
|
|
|
# Extract and process result
|
|
if [[ -n "$output_file" ]]; then
|
|
echo "$response" > "$output_file"
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Output saved to: $output_file" >&2
|
|
fi
|
|
else
|
|
echo "$response"
|
|
fi
|
|
|
|
if [[ "$verbose" == "true" ]]; then
|
|
echo "Processing completed successfully" >&2
|
|
fi
|