paddleocr-text-recognition
>-
Works with
Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: paddleocr-text-recognition
description: >-
license: Apache-2.0
---
# PaddleOCR Text Recognition Skill
## When to Use This Skill
**Trigger keywords (routing)**: Bilingual trigger terms (Chinese and English) are listed in the YAML `description` above—use that field for discovery and routing.
**Use this skill for**:
- Extract text from images (screenshots, photos, scans)
- Extract text from PDFs or document images when the goal is **line/box-level text**, not recovering table grids, formulas, or full reading-order layout
- Extract text from URLs or local files that point to images/PDFs
**Do not use for**:
- Plain text files, code files, or markdown documents that can be read directly as text
- Documents with tables, formulas, charts, or complex layouts — use Document Parsing instead
- Tasks that do not involve image-to-text conversion
## Installation
Scripts declare their dependencies inline ([PEP 723](https://peps.python.org/pep-0723/)). No separate install step is needed — [uv](https://docs.astral.sh/uv/) resolves dependencies automatically:
```bash
uv run scripts/ocr_caller.py --help
```
## How to Use This Skill
> **Working directory**: All `uv run scripts/...` commands below should be run from this skill's root directory (the directory containing this SKILL.md file).
### Basic Workflow
1. **Identify the input source**:
- User provides URL: Use the `--file-url` parameter
- User provides local file path: Use the `--file-path` parameter
2. **Execute OCR**:
```bash
uv run scripts/ocr_caller.py --file-url "URL provided by user" --pretty
```
Or for local files:
```bash
uv run scripts/ocr_caller.py --file-path "file path" --pretty
```
> **Performance note**: Parsing time scales with document complexity. Single-page images typically complete in 1-3 seconds; large PDFs (50+ pages) may take several minutes. Allow adequate time before assuming a timeout.
**Default behavior: save raw JSON to a temp file**:
- If `--output` is omitted, the script saves automatically under the system temp directory
- Default path pattern: `<system-temp>/paddleocr/text-recognition/results/result_<timestamp>_<id>.json`
- If `--output` is provided, it overrides the default temp-file destination
- If `--stdout` is provided, JSON is printed to stdout and no file is saved
- In save mode, the script prints the absolute saved path on stderr: `Result saved to: /absolute/path/...`
- In default/custom save mode, read and parse the saved JSON file before responding
- Use `--stdout` only when you explicitly want to skip file persistence
3. **Parse JSON response**:
- In default/custom save mode, load JSON from the saved file path shown by the script
- Check the `ok` field: `true` means success, `false` means error
- Extract text: `text` field contains all recognized text
- If `--stdout` is used, parse the stdout JSON directly
- Handle errors: If `ok` is false, display `error.message`
4. **Present results to user**:
- Display extracted text in a readable format
- If the text is empty, the image may contain no text
- In save mode, always tell the user the saved file path and that full raw JSON is available there
### What to Do After Extraction
Common next steps once you have the recognized text:
- **Save to file**: Write the `text` field to a `.txt` or `.md` file
- **Search the content**: Search the saved output file for keywords
- **Feed to another pipeline**: The `text` field is clean plain text, ready for downstream processing
- **Poor results**: See "Tips for Better Results" below before retrying
### Complete Output Display
Always display the COMPLETE recognized text to the user. The user typically needs the full content for downstream use — truncation silently loses data they may not notice is missing.
- Display the entire `text` field, no matter how long
- Do not use phrases like "Here's a summary" or "The text begins with..."
- Do not truncate with "..." unless the text truly exceeds reasonable display limits (>10,000 chars)
**Example - Correct**:
```
User: "Extract the text from this image"
Agent: I've extracted the text from the image. Here's the complete content:
[Display the entire text here]
```
**Example - Incorrect**:
```
User: "Extract the text from this image"
Agent: I found some text in the image. Here's a preview:
"The quick brown fox..." (truncated)
```
### Understanding the Output
The script returns a JSON envelope with `ok`, `text`, `result`, and `error` fields. Use `text` for the recognized content; `result` contains the raw API response for debugging.
For the full schema and field-level details, see `references/output_schema.md`.
> Raw result location (default): the temp-file path printed by the script on stderr
### Alternative: paddleocr CLI
This mirror keeps the bundled `scripts/ocr_caller.py` as the default path. The upstream PaddleOCR project (since [PR #18090](https://github.com/PaddlePaddle/PaddleOCR/pull/18090), 2026-06-03) also ships an official CLI that calls the same API directly. If the `paddleocr` package is installed, you can use it as a drop-in alternative — no `uv run` or local scripts required.
**Install** (one-time):
```bash
pip install "paddleocr>=3.7.0"
```
**Environment**: the CLI only needs `PADDLEOCR_ACCESS_TOKEN`. It resolves the API endpoint internally, so `PADDLEOCR_OCR_API_URL` is **not** required when using the CLI (the URL is still required by the script).
**Basic OCR**:
```bash
# From URL
paddleocr api --model_type ocr --file_url "https://example.com/image.png"
# From local file
paddleocr api --model_type ocr --file_path "./document.pdf"
```
**Common options**:
```bash
# Specific model
paddleocr api --model_type ocr --model PP-OCRv5 --file_path "./report.pdf"
# Disable preprocessing (faster, for flat/well-oriented images)
paddleocr api --model_type ocr --file_path "./document.pdf" \
--use_doc_unwarping False --use_doc_orientation_classify False
# Page ranges
paddleocr api --model_type ocr --file_path "./large.pdf" --page_ranges "1-5,10,15-20"
# Save result to file
paddleocr api --model_type ocr --file_url "https://..." --output result.json
```
**CLI output format** — **different from the script envelope**:
```json
{
"jobId": "job-xxx",
"pages": [
{
"prunedResult": {
"rec_texts": ["Line 1", "Line 2"],
"rec_scores": [0.98, 0.95]
},
"ocrImageUrl": "https://..."
}
]
}
```
The CLI prints `{jobId, pages:[...]}` to stdout. It does **not** wrap the response in the script's `{ok, text, result, error}` envelope, does not auto-save to a temp file, and does not concatenate `text` for you. If you switch paths, update your parsing logic accordingly.
**Scripts vs CLI** — at a glance:
| | Scripts (default) | `paddleocr` CLI (alternative) |
| --- | --- | --- |
| Install | `uv` resolves PEP 723 inline deps | `pip install "paddleocr>=3.7.0"` |
| Required env | `PADDLEOCR_OCR_API_URL` + `PADDLEOCR_ACCESS_TOKEN` | `PADDLEOCR_ACCESS_TOKEN` only |
| Entry | `uv run scripts/ocr_caller.py ...` | `paddleocr api --model_type ocr ...` |
| Output | `{ok, text, result, error}` envelope, auto-saved to temp file | `{jobId, pages:[...]}` to stdout |
| Result location | Path printed on stderr (or `--output`/`--stdout`) | stdout (or `--output`) |
| Best for | Skills runtimes, offline-friendly, no extra install | Already have `paddleocr` installed, want the upstream-canonical flow |
Run `paddleocr api --help` for the full option list.
### Usage Examples
**Example 1: URL OCR**
```bash
uv run scripts/ocr_caller.py --file-url "https://example.com/invoice.jpg" --pretty
```
**Example 2: Local File OCR**
```bash
uv run scripts/ocr_caller.py --file-path "./document.pdf" --pretty
```
**Example 3: OCR With Explicit File Type**
```bash
uv run scripts/ocr_caller.py --file-url "https://example.com/input" --file-type 1 --pretty
```
- `--file-type 0`: PDF
- `--file-type 1`: image
- If omitted, the type is auto-detected from the file extension. For local files, a recognized extension (`.pdf`, `.png`, `.jpg`, `.jpeg`, `.bmp`, `.tiff`, `.tif`, `.webp`) is required; otherwise pass `--file-type` explicitly. For URLs with unrecognized extensions, the service attempts inference.
**Example 4: Print JSON Without Saving**
```bash
uv run scripts/ocr_caller.py --file-url "https://example.com/input" --stdout --pretty
```
### First-Time Configuration
**When API is not configured**, the script outputs:
```json
{
"ok": false,
"text": "",
"result": null,
"error": {
"code": "CONFIG_ERROR",
"message": "PADDLEOCR_OCR_API_URL not configured. Get your API at: https://paddleocr.com"
}
}
```
**Configuration workflow**:
1. **Show the exact error message** to the user.
2. **Guide the user to obtain credentials**: Visit the [PaddleOCR website](https://www.paddleocr.com), click **API**, select the `PP-OCRv5` model, select the language, then copy the `API_URL` and `Token`. They map to these environment variables:
- `PADDLEOCR_OCR_API_URL` — full endpoint URL ending with `/ocr`
- `PADDLEOCR_ACCESS_TOKEN` — 40-character alphanumeric string
Optionally configure `PADDLEOCR_OCR_TIMEOUT` for request timeout. Recommend using the host application's standard configuration method rather than pasting credentials in chat.
3. **Apply credentials** — one of:
- **User configured via the host UI**: ask the user to confirm, then retry.
- **User pastes credentials in chat**: warn that they may be stored in conversation history, help the user persist them using the host's standard configuration method, then retry.
### Error Handling
All errors return JSON with `ok: false`. Show the error message and stop — do not fall back to your own vision capabilities. Identify the issue from `error.code` and `error.message`:
**Authentication failed (403)** — `error.message` contains "Authentication failed"
- Token is invalid, reconfigure with correct credentials
**Quota exceeded (429)** — `error.message` contains "API rate limit exceeded"
- Daily API quota exhausted, inform user to wait or upgrade
**Unsupported format** — `error.message` contains "Unsupported file format"
- File format not supported, convert to PDF/PNG/JPG
**No text detected**:
- `text` field is empty
- Image may be blank, corrupted, or contain no text
### Tips for Better Results
If recognition quality is poor:
- **Low resolution**: Provide a higher resolution image (≥300 DPI works well for most printed text)
- **Noisy background**: A cleaner scan or screenshot typically yields better results than a phone photo
- **Check confidence**: The raw JSON (`result.result.ocrResults[n].prunedResult.rec_scores`) shows per-line confidence scores — low values identify uncertain regions worth reviewing
## Reference Documentation
- `references/output_schema.md` — Full output schema, field descriptions, and command examples
> **Note**: Model version, capabilities, and supported file formats are determined by your API endpoint (`PADDLEOCR_OCR_API_URL`) and its official API documentation.
## Testing the Skill
To verify the skill is working properly:
```bash
uv run scripts/smoke_test.py
uv run scripts/smoke_test.py --skip-api-test
uv run scripts/smoke_test.py --test-url "https://..."
```
The first form tests configuration and API connectivity. `--skip-api-test` checks configuration only. `--test-url` overrides the default sample image URL.More General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
1.5M
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
972.7k
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
828.8k

