ocr-software 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ocr_software-0.1.1/INSTALL.txt +106 -0
- ocr_software-0.1.1/PKG-INFO +123 -0
- ocr_software-0.1.1/README.md +106 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software/__init__.py +1 -1
- ocr_software-0.1.1/ocr_software.egg-info/PKG-INFO +123 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/pyproject.toml +2 -2
- {ocr_software-0.1.0 → ocr_software-0.1.1}/tests/test_release_files.py +2 -0
- ocr_software-0.1.0/INSTALL.txt +0 -71
- ocr_software-0.1.0/PKG-INFO +0 -88
- ocr_software-0.1.0/README.md +0 -71
- ocr_software-0.1.0/ocr_software.egg-info/PKG-INFO +0 -88
- {ocr_software-0.1.0 → ocr_software-0.1.1}/LICENSE +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software/__main__.py +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software/advice.py +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software/cli.py +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software/client.py +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software.egg-info/SOURCES.txt +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software.egg-info/dependency_links.txt +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software.egg-info/entry_points.txt +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software.egg-info/requires.txt +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/ocr_software.egg-info/top_level.txt +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/setup.cfg +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/tests/test_advice.py +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/tests/test_cli.py +0 -0
- {ocr_software-0.1.0 → ocr_software-0.1.1}/tests/test_client.py +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# ocr-software
|
|
2
|
+
|
|
3
|
+
Python client and command line for the [ocr-software.com](https://ocr-software.com/) OCR API. MIT, standard library only, Python 3.9 or newer.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pipx install ocr-software # command line only, in its own environment
|
|
9
|
+
pip install ocr-software # client library, inside a venv
|
|
10
|
+
uvx ocr-software --version # run once without installing (uv)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
First call (list the pipelines, then read one file):
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
ocr-software --list-pipelines
|
|
17
|
+
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Settings
|
|
21
|
+
|
|
22
|
+
Environment variables; the command line flag wins.
|
|
23
|
+
|
|
24
|
+
| Variable | Meaning |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `OCR_SOFTWARE_API_KEY` | API key (starts with `ocr_`). `OCR_KEY` is read too, it is the name used in the API docs. |
|
|
27
|
+
| `OCR_SOFTWARE_BASE_URL` | Default `https://api.ocr-software.com`; own server e.g. `http://127.0.0.1:8080` (also `--base-url`). `OCR_BASE_URL` is read too. |
|
|
28
|
+
| `OCR_SOFTWARE_ALLOWED_DIR` | Optional: read documents only from below this folder (symlinks and `..` do not escape). |
|
|
29
|
+
|
|
30
|
+
The key is never printed and never part of an error message. Without `--pipeline` the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; `--list-pipelines` marks it. In Python: `client.ocr(path, client.default_pipeline())`.
|
|
31
|
+
|
|
32
|
+
## Command line
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
ocr-software --list-pipelines # available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
36
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run # page count and price in euros, nothing runs, nothing is billed
|
|
37
|
+
ocr-software scan.pdf # text to stdout, with the default pipeline (named on stderr)
|
|
38
|
+
ocr-software scan.pdf --pipeline NAME@VERSION # text to stdout
|
|
39
|
+
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
40
|
+
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
41
|
+
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf # searchable PDF, -o is required
|
|
42
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
43
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 # your own server
|
|
44
|
+
python -m ocr_software ... # the same command without the script on PATH
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
- `--format text` (default) `| md | json | hocr | pdf`
|
|
49
|
+
- `--dpi 150|200|300` (PDF render resolution)
|
|
50
|
+
- `--timeout SECONDS` (wait for the job, default 3600)
|
|
51
|
+
- `--job-budget MILLICENTS` (cap; ignored where billing is off)
|
|
52
|
+
- `--dry-run`, `--version`
|
|
53
|
+
|
|
54
|
+
Without `-o` the result goes to stdout as UTF-8 (not for pdf). With `-o` the file appears whole or not at all, an existing file is replaced, and the input file itself is refused as output.
|
|
55
|
+
|
|
56
|
+
### Exit codes
|
|
57
|
+
|
|
58
|
+
| Code | Meaning |
|
|
59
|
+
|---|---|
|
|
60
|
+
| 0 | done, every page read |
|
|
61
|
+
| 1 | error from the service or the network (message on stderr with the API error code, for example 401 unauthorized); also an address that does not answer: a typo and an outage look the same, so a script may retry this |
|
|
62
|
+
| 2 | wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https) |
|
|
63
|
+
| 3 | the job is done but a page failed or did not run, or the job stopped early: the result is written anyway, stderr says what is missing and names the job; treat the file as incomplete |
|
|
64
|
+
| 4 | the job did not finish within `--timeout`; it keeps running, stderr names the job |
|
|
65
|
+
|
|
66
|
+
## Python
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from ocr_software import Client, PagesUnread
|
|
70
|
+
client = Client() # key and address from the environment
|
|
71
|
+
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
72
|
+
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
73
|
+
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
74
|
+
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
75
|
+
q = client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
76
|
+
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Price:** the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001). Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits: [fair usage](https://ocr-software.com/legal/fair-usage/); for more volume write to info@ocr-software.com.
|
|
80
|
+
|
|
81
|
+
**Word boxes (json):** `box = [x0, y0, x1, y1]` in pixels of the page image, origin top left; `width`, `height` and `dpi` of the page say which image. In PDF points: pixels * 72 / dpi. Per word, `verified` is true only where a second reader confirmed it (`scan-vlm-ctc@2`); `safe_ok` is always false today. Judge by `confidence` (0 to 1). Every field: [reference](https://ocr-software.com/docs/reference/).
|
|
82
|
+
|
|
83
|
+
**Retries** follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or `Retry-After`). An upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A `Retry-After` over 60 s (`locked_out`) is not waited for. A submit carries an `Idempotency-Key`, so a retry never creates a second job.
|
|
84
|
+
|
|
85
|
+
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
86
|
+
|
|
87
|
+
## Paperless-ngx
|
|
88
|
+
|
|
89
|
+
Pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
#!/bin/sh
|
|
93
|
+
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
with `OCR_SOFTWARE_API_KEY` and `OCR_SOFTWARE_BASE_URL` set in the environment of the Paperless container.
|
|
97
|
+
|
|
98
|
+
## Tests
|
|
99
|
+
|
|
100
|
+
Fake local service, no network, no key:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
python -m venv .venv
|
|
104
|
+
.venv/bin/pip install pytest # Windows: .venv\Scripts\pip install pytest
|
|
105
|
+
.venv/bin/python -m pytest -p no:cacheprovider . # Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .
|
|
106
|
+
```
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ocr-software
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Client and command line for the ocr-software.com OCR API: text, word boxes, layout, searchable PDF.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://ocr-software.com/
|
|
7
|
+
Project-URL: Repository, https://github.com/ocr-software/ocr-software-python
|
|
8
|
+
Keywords: ocr,pdf,searchable-pdf,hocr,markdown,document-ai
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Provides-Extra: test
|
|
15
|
+
Requires-Dist: pytest==9.0.2; extra == "test"
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# ocr-software
|
|
19
|
+
|
|
20
|
+
Python client and command line for the [ocr-software.com](https://ocr-software.com/) OCR API. MIT, standard library only, Python 3.9 or newer.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pipx install ocr-software # command line only, in its own environment
|
|
26
|
+
pip install ocr-software # client library, inside a venv
|
|
27
|
+
uvx ocr-software --version # run once without installing (uv)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
First call (list the pipelines, then read one file):
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
ocr-software --list-pipelines
|
|
34
|
+
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Settings
|
|
38
|
+
|
|
39
|
+
Environment variables; the command line flag wins.
|
|
40
|
+
|
|
41
|
+
| Variable | Meaning |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `OCR_SOFTWARE_API_KEY` | API key (starts with `ocr_`). `OCR_KEY` is read too, it is the name used in the API docs. |
|
|
44
|
+
| `OCR_SOFTWARE_BASE_URL` | Default `https://api.ocr-software.com`; own server e.g. `http://127.0.0.1:8080` (also `--base-url`). `OCR_BASE_URL` is read too. |
|
|
45
|
+
| `OCR_SOFTWARE_ALLOWED_DIR` | Optional: read documents only from below this folder (symlinks and `..` do not escape). |
|
|
46
|
+
|
|
47
|
+
The key is never printed and never part of an error message. Without `--pipeline` the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; `--list-pipelines` marks it. In Python: `client.ocr(path, client.default_pipeline())`.
|
|
48
|
+
|
|
49
|
+
## Command line
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
ocr-software --list-pipelines # available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
53
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run # page count and price in euros, nothing runs, nothing is billed
|
|
54
|
+
ocr-software scan.pdf # text to stdout, with the default pipeline (named on stderr)
|
|
55
|
+
ocr-software scan.pdf --pipeline NAME@VERSION # text to stdout
|
|
56
|
+
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
57
|
+
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
58
|
+
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf # searchable PDF, -o is required
|
|
59
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
60
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 # your own server
|
|
61
|
+
python -m ocr_software ... # the same command without the script on PATH
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Options:
|
|
65
|
+
- `--format text` (default) `| md | json | hocr | pdf`
|
|
66
|
+
- `--dpi 150|200|300` (PDF render resolution)
|
|
67
|
+
- `--timeout SECONDS` (wait for the job, default 3600)
|
|
68
|
+
- `--job-budget MILLICENTS` (cap; ignored where billing is off)
|
|
69
|
+
- `--dry-run`, `--version`
|
|
70
|
+
|
|
71
|
+
Without `-o` the result goes to stdout as UTF-8 (not for pdf). With `-o` the file appears whole or not at all, an existing file is replaced, and the input file itself is refused as output.
|
|
72
|
+
|
|
73
|
+
### Exit codes
|
|
74
|
+
|
|
75
|
+
| Code | Meaning |
|
|
76
|
+
|---|---|
|
|
77
|
+
| 0 | done, every page read |
|
|
78
|
+
| 1 | error from the service or the network (message on stderr with the API error code, for example 401 unauthorized); also an address that does not answer: a typo and an outage look the same, so a script may retry this |
|
|
79
|
+
| 2 | wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https) |
|
|
80
|
+
| 3 | the job is done but a page failed or did not run, or the job stopped early: the result is written anyway, stderr says what is missing and names the job; treat the file as incomplete |
|
|
81
|
+
| 4 | the job did not finish within `--timeout`; it keeps running, stderr names the job |
|
|
82
|
+
|
|
83
|
+
## Python
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from ocr_software import Client, PagesUnread
|
|
87
|
+
client = Client() # key and address from the environment
|
|
88
|
+
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
89
|
+
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
90
|
+
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
91
|
+
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
92
|
+
q = client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
93
|
+
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Price:** the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001). Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits: [fair usage](https://ocr-software.com/legal/fair-usage/); for more volume write to info@ocr-software.com.
|
|
97
|
+
|
|
98
|
+
**Word boxes (json):** `box = [x0, y0, x1, y1]` in pixels of the page image, origin top left; `width`, `height` and `dpi` of the page say which image. In PDF points: pixels * 72 / dpi. Per word, `verified` is true only where a second reader confirmed it (`scan-vlm-ctc@2`); `safe_ok` is always false today. Judge by `confidence` (0 to 1). Every field: [reference](https://ocr-software.com/docs/reference/).
|
|
99
|
+
|
|
100
|
+
**Retries** follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or `Retry-After`). An upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A `Retry-After` over 60 s (`locked_out`) is not waited for. A submit carries an `Idempotency-Key`, so a retry never creates a second job.
|
|
101
|
+
|
|
102
|
+
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
103
|
+
|
|
104
|
+
## Paperless-ngx
|
|
105
|
+
|
|
106
|
+
Pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
#!/bin/sh
|
|
110
|
+
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
with `OCR_SOFTWARE_API_KEY` and `OCR_SOFTWARE_BASE_URL` set in the environment of the Paperless container.
|
|
114
|
+
|
|
115
|
+
## Tests
|
|
116
|
+
|
|
117
|
+
Fake local service, no network, no key:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
python -m venv .venv
|
|
121
|
+
.venv/bin/pip install pytest # Windows: .venv\Scripts\pip install pytest
|
|
122
|
+
.venv/bin/python -m pytest -p no:cacheprovider . # Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .
|
|
123
|
+
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# ocr-software
|
|
2
|
+
|
|
3
|
+
Python client and command line for the [ocr-software.com](https://ocr-software.com/) OCR API. MIT, standard library only, Python 3.9 or newer.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pipx install ocr-software # command line only, in its own environment
|
|
9
|
+
pip install ocr-software # client library, inside a venv
|
|
10
|
+
uvx ocr-software --version # run once without installing (uv)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
First call (list the pipelines, then read one file):
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
ocr-software --list-pipelines
|
|
17
|
+
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Settings
|
|
21
|
+
|
|
22
|
+
Environment variables; the command line flag wins.
|
|
23
|
+
|
|
24
|
+
| Variable | Meaning |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `OCR_SOFTWARE_API_KEY` | API key (starts with `ocr_`). `OCR_KEY` is read too, it is the name used in the API docs. |
|
|
27
|
+
| `OCR_SOFTWARE_BASE_URL` | Default `https://api.ocr-software.com`; own server e.g. `http://127.0.0.1:8080` (also `--base-url`). `OCR_BASE_URL` is read too. |
|
|
28
|
+
| `OCR_SOFTWARE_ALLOWED_DIR` | Optional: read documents only from below this folder (symlinks and `..` do not escape). |
|
|
29
|
+
|
|
30
|
+
The key is never printed and never part of an error message. Without `--pipeline` the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; `--list-pipelines` marks it. In Python: `client.ocr(path, client.default_pipeline())`.
|
|
31
|
+
|
|
32
|
+
## Command line
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
ocr-software --list-pipelines # available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
36
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run # page count and price in euros, nothing runs, nothing is billed
|
|
37
|
+
ocr-software scan.pdf # text to stdout, with the default pipeline (named on stderr)
|
|
38
|
+
ocr-software scan.pdf --pipeline NAME@VERSION # text to stdout
|
|
39
|
+
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
40
|
+
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
41
|
+
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf # searchable PDF, -o is required
|
|
42
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
43
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 # your own server
|
|
44
|
+
python -m ocr_software ... # the same command without the script on PATH
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
- `--format text` (default) `| md | json | hocr | pdf`
|
|
49
|
+
- `--dpi 150|200|300` (PDF render resolution)
|
|
50
|
+
- `--timeout SECONDS` (wait for the job, default 3600)
|
|
51
|
+
- `--job-budget MILLICENTS` (cap; ignored where billing is off)
|
|
52
|
+
- `--dry-run`, `--version`
|
|
53
|
+
|
|
54
|
+
Without `-o` the result goes to stdout as UTF-8 (not for pdf). With `-o` the file appears whole or not at all, an existing file is replaced, and the input file itself is refused as output.
|
|
55
|
+
|
|
56
|
+
### Exit codes
|
|
57
|
+
|
|
58
|
+
| Code | Meaning |
|
|
59
|
+
|---|---|
|
|
60
|
+
| 0 | done, every page read |
|
|
61
|
+
| 1 | error from the service or the network (message on stderr with the API error code, for example 401 unauthorized); also an address that does not answer: a typo and an outage look the same, so a script may retry this |
|
|
62
|
+
| 2 | wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https) |
|
|
63
|
+
| 3 | the job is done but a page failed or did not run, or the job stopped early: the result is written anyway, stderr says what is missing and names the job; treat the file as incomplete |
|
|
64
|
+
| 4 | the job did not finish within `--timeout`; it keeps running, stderr names the job |
|
|
65
|
+
|
|
66
|
+
## Python
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from ocr_software import Client, PagesUnread
|
|
70
|
+
client = Client() # key and address from the environment
|
|
71
|
+
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
72
|
+
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
73
|
+
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
74
|
+
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
75
|
+
q = client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
76
|
+
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Price:** the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001). Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits: [fair usage](https://ocr-software.com/legal/fair-usage/); for more volume write to info@ocr-software.com.
|
|
80
|
+
|
|
81
|
+
**Word boxes (json):** `box = [x0, y0, x1, y1]` in pixels of the page image, origin top left; `width`, `height` and `dpi` of the page say which image. In PDF points: pixels * 72 / dpi. Per word, `verified` is true only where a second reader confirmed it (`scan-vlm-ctc@2`); `safe_ok` is always false today. Judge by `confidence` (0 to 1). Every field: [reference](https://ocr-software.com/docs/reference/).
|
|
82
|
+
|
|
83
|
+
**Retries** follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or `Retry-After`). An upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A `Retry-After` over 60 s (`locked_out`) is not waited for. A submit carries an `Idempotency-Key`, so a retry never creates a second job.
|
|
84
|
+
|
|
85
|
+
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
86
|
+
|
|
87
|
+
## Paperless-ngx
|
|
88
|
+
|
|
89
|
+
Pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
#!/bin/sh
|
|
93
|
+
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
with `OCR_SOFTWARE_API_KEY` and `OCR_SOFTWARE_BASE_URL` set in the environment of the Paperless container.
|
|
97
|
+
|
|
98
|
+
## Tests
|
|
99
|
+
|
|
100
|
+
Fake local service, no network, no key:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
python -m venv .venv
|
|
104
|
+
.venv/bin/pip install pytest # Windows: .venv\Scripts\pip install pytest
|
|
105
|
+
.venv/bin/python -m pytest -p no:cacheprovider . # Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .
|
|
106
|
+
```
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
from .advice import default_pipeline, price_sentence
|
|
3
3
|
from .client import Client, OcrError, PagesUnread, split_pages, unread_message
|
|
4
4
|
|
|
5
|
-
__version__ = "0.1.
|
|
5
|
+
__version__ = "0.1.1"
|
|
6
6
|
__all__ = ["Client", "OcrError", "PagesUnread", "split_pages", "unread_message", "default_pipeline", "price_sentence", "__version__"]
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ocr-software
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Client and command line for the ocr-software.com OCR API: text, word boxes, layout, searchable PDF.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://ocr-software.com/
|
|
7
|
+
Project-URL: Repository, https://github.com/ocr-software/ocr-software-python
|
|
8
|
+
Keywords: ocr,pdf,searchable-pdf,hocr,markdown,document-ai
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Provides-Extra: test
|
|
15
|
+
Requires-Dist: pytest==9.0.2; extra == "test"
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# ocr-software
|
|
19
|
+
|
|
20
|
+
Python client and command line for the [ocr-software.com](https://ocr-software.com/) OCR API. MIT, standard library only, Python 3.9 or newer.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pipx install ocr-software # command line only, in its own environment
|
|
26
|
+
pip install ocr-software # client library, inside a venv
|
|
27
|
+
uvx ocr-software --version # run once without installing (uv)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
First call (list the pipelines, then read one file):
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
ocr-software --list-pipelines
|
|
34
|
+
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Settings
|
|
38
|
+
|
|
39
|
+
Environment variables; the command line flag wins.
|
|
40
|
+
|
|
41
|
+
| Variable | Meaning |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `OCR_SOFTWARE_API_KEY` | API key (starts with `ocr_`). `OCR_KEY` is read too, it is the name used in the API docs. |
|
|
44
|
+
| `OCR_SOFTWARE_BASE_URL` | Default `https://api.ocr-software.com`; own server e.g. `http://127.0.0.1:8080` (also `--base-url`). `OCR_BASE_URL` is read too. |
|
|
45
|
+
| `OCR_SOFTWARE_ALLOWED_DIR` | Optional: read documents only from below this folder (symlinks and `..` do not escape). |
|
|
46
|
+
|
|
47
|
+
The key is never printed and never part of an error message. Without `--pipeline` the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; `--list-pipelines` marks it. In Python: `client.ocr(path, client.default_pipeline())`.
|
|
48
|
+
|
|
49
|
+
## Command line
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
ocr-software --list-pipelines # available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
53
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run # page count and price in euros, nothing runs, nothing is billed
|
|
54
|
+
ocr-software scan.pdf # text to stdout, with the default pipeline (named on stderr)
|
|
55
|
+
ocr-software scan.pdf --pipeline NAME@VERSION # text to stdout
|
|
56
|
+
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
57
|
+
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
58
|
+
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf # searchable PDF, -o is required
|
|
59
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
60
|
+
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 # your own server
|
|
61
|
+
python -m ocr_software ... # the same command without the script on PATH
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Options:
|
|
65
|
+
- `--format text` (default) `| md | json | hocr | pdf`
|
|
66
|
+
- `--dpi 150|200|300` (PDF render resolution)
|
|
67
|
+
- `--timeout SECONDS` (wait for the job, default 3600)
|
|
68
|
+
- `--job-budget MILLICENTS` (cap; ignored where billing is off)
|
|
69
|
+
- `--dry-run`, `--version`
|
|
70
|
+
|
|
71
|
+
Without `-o` the result goes to stdout as UTF-8 (not for pdf). With `-o` the file appears whole or not at all, an existing file is replaced, and the input file itself is refused as output.
|
|
72
|
+
|
|
73
|
+
### Exit codes
|
|
74
|
+
|
|
75
|
+
| Code | Meaning |
|
|
76
|
+
|---|---|
|
|
77
|
+
| 0 | done, every page read |
|
|
78
|
+
| 1 | error from the service or the network (message on stderr with the API error code, for example 401 unauthorized); also an address that does not answer: a typo and an outage look the same, so a script may retry this |
|
|
79
|
+
| 2 | wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https) |
|
|
80
|
+
| 3 | the job is done but a page failed or did not run, or the job stopped early: the result is written anyway, stderr says what is missing and names the job; treat the file as incomplete |
|
|
81
|
+
| 4 | the job did not finish within `--timeout`; it keeps running, stderr names the job |
|
|
82
|
+
|
|
83
|
+
## Python
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from ocr_software import Client, PagesUnread
|
|
87
|
+
client = Client() # key and address from the environment
|
|
88
|
+
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
89
|
+
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
90
|
+
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
91
|
+
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
92
|
+
q = client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
93
|
+
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Price:** the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001). Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits: [fair usage](https://ocr-software.com/legal/fair-usage/); for more volume write to info@ocr-software.com.
|
|
97
|
+
|
|
98
|
+
**Word boxes (json):** `box = [x0, y0, x1, y1]` in pixels of the page image, origin top left; `width`, `height` and `dpi` of the page say which image. In PDF points: pixels * 72 / dpi. Per word, `verified` is true only where a second reader confirmed it (`scan-vlm-ctc@2`); `safe_ok` is always false today. Judge by `confidence` (0 to 1). Every field: [reference](https://ocr-software.com/docs/reference/).
|
|
99
|
+
|
|
100
|
+
**Retries** follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or `Retry-After`). An upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A `Retry-After` over 60 s (`locked_out`) is not waited for. A submit carries an `Idempotency-Key`, so a retry never creates a second job.
|
|
101
|
+
|
|
102
|
+
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
103
|
+
|
|
104
|
+
## Paperless-ngx
|
|
105
|
+
|
|
106
|
+
Pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
#!/bin/sh
|
|
110
|
+
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
with `OCR_SOFTWARE_API_KEY` and `OCR_SOFTWARE_BASE_URL` set in the environment of the Paperless container.
|
|
114
|
+
|
|
115
|
+
## Tests
|
|
116
|
+
|
|
117
|
+
Fake local service, no network, no key:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
python -m venv .venv
|
|
121
|
+
.venv/bin/pip install pytest # Windows: .venv\Scripts\pip install pytest
|
|
122
|
+
.venv/bin/python -m pytest -p no:cacheprovider . # Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .
|
|
123
|
+
```
|
|
@@ -4,9 +4,9 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ocr-software"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "Client and command line for the ocr-software.com OCR API: text, word boxes, layout, searchable PDF."
|
|
9
|
-
readme = {file = "INSTALL.txt", content-type = "text/
|
|
9
|
+
readme = {file = "INSTALL.txt", content-type = "text/markdown"}
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
12
12
|
requires-python = ">=3.9"
|
|
@@ -16,6 +16,8 @@ def test_readme_file_exists_and_no_runtime_dependencies():
|
|
|
16
16
|
pyproject = (ROOT / "pyproject.toml").read_text(encoding="utf-8")
|
|
17
17
|
assert (ROOT / "INSTALL.txt").is_file() and 'file = "INSTALL.txt"' in pyproject
|
|
18
18
|
assert "dependencies = []" in pyproject # standard library only
|
|
19
|
+
# 13.11.2026: as text/plain PyPI showed one fixed-width block whose long lines ran off the page
|
|
20
|
+
assert 'content-type = "text/markdown"' in pyproject
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
def test_readme_that_pypi_shows_has_no_draft_note():
|
ocr_software-0.1.0/INSTALL.txt
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
ocr-software: Python client and command line for the ocr-software.com OCR API (MIT, standard library only, Python 3.9 or newer).
|
|
2
|
-
|
|
3
|
-
Install:
|
|
4
|
-
pipx install ocr-software command line only, in its own environment
|
|
5
|
-
pip install ocr-software client library, inside a venv
|
|
6
|
-
uvx ocr-software --version run once without installing (uv)
|
|
7
|
-
First call (list the pipelines, then read one file):
|
|
8
|
-
ocr-software --list-pipelines
|
|
9
|
-
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
10
|
-
|
|
11
|
-
Settings (environment; the command line flag wins):
|
|
12
|
-
OCR_SOFTWARE_API_KEY API key (starts with ocr_). OCR_KEY is read too, it is the name used in the API docs.
|
|
13
|
-
OCR_SOFTWARE_BASE_URL default https://api.ocr-software.com ; own server e.g. http://127.0.0.1:8080 (also --base-url). OCR_BASE_URL is read too.
|
|
14
|
-
OCR_SOFTWARE_ALLOWED_DIR optional: read documents only from below this folder (symlinks and .. do not escape)
|
|
15
|
-
The key is never printed and never part of an error message. Without --pipeline the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; --list-pipelines marks it. In Python: client.ocr(path, client.default_pipeline()).
|
|
16
|
-
|
|
17
|
-
Command line:
|
|
18
|
-
ocr-software --list-pipelines available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
19
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run page count and price in euros, nothing runs, nothing is billed
|
|
20
|
-
ocr-software scan.pdf text to stdout, with the default pipeline (named on stderr)
|
|
21
|
-
ocr-software scan.pdf --pipeline NAME@VERSION text to stdout
|
|
22
|
-
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
23
|
-
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
24
|
-
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf searchable PDF, -o is required
|
|
25
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
26
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 your own server
|
|
27
|
-
python -m ocr_software ... the same command without the script on PATH
|
|
28
|
-
Options: --format text (default) | md | json | hocr | pdf ; --dpi 150|200|300 (PDF render resolution) ;
|
|
29
|
-
--timeout SECONDS (wait for the job, default 3600) ; --job-budget MILLICENTS (cap; ignored where billing is off) ; --dry-run ; --version
|
|
30
|
-
Without -o the result goes to stdout as UTF-8 (not for pdf). With -o the file appears whole or not at all, an existing
|
|
31
|
-
file is replaced, and the input file itself is refused as output.
|
|
32
|
-
|
|
33
|
-
Exit codes:
|
|
34
|
-
0 done, every page read
|
|
35
|
-
1 error from the service or the network (message on stderr with the API error code, for example 401 unauthorized);
|
|
36
|
-
also an address that does not answer: a typo and an outage look the same, so a script may retry this
|
|
37
|
-
2 wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https)
|
|
38
|
-
3 the job is done but a page failed or did not run, or the job stopped early: the result is written anyway,
|
|
39
|
-
stderr says what is missing and names the job; treat the file as incomplete
|
|
40
|
-
4 the job did not finish within --timeout; it keeps running, stderr names the job
|
|
41
|
-
|
|
42
|
-
Python:
|
|
43
|
-
from ocr_software import Client, PagesUnread
|
|
44
|
-
client = Client() # key and address from the environment
|
|
45
|
-
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
46
|
-
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
47
|
-
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
48
|
-
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
49
|
-
client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
50
|
-
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
51
|
-
Price: the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001).
|
|
52
|
-
Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits:
|
|
53
|
-
https://ocr-software.com/legal/fair-usage/ ; for more volume write to info@ocr-software.com.
|
|
54
|
-
Word boxes (json): box = [x0, y0, x1, y1] in pixels of the page image, origin top left; width, height and dpi of the page say which
|
|
55
|
-
image. In PDF points: pixels * 72 / dpi. Per word, verified is true only where a second reader confirmed it (scan-vlm-ctc@2);
|
|
56
|
-
safe_ok is always false today. Judge by confidence (0 to 1). Every field: https://ocr-software.com/docs/reference/
|
|
57
|
-
Retries follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or Retry-After). An
|
|
58
|
-
upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection
|
|
59
|
-
can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on
|
|
60
|
-
Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A Retry-After over 60 s (locked_out) is not waited for. A submit carries an Idempotency-Key, so a retry never creates a second job.
|
|
61
|
-
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
62
|
-
|
|
63
|
-
Paperless-ngx, pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
64
|
-
#!/bin/sh
|
|
65
|
-
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
66
|
-
with OCR_SOFTWARE_API_KEY and OCR_SOFTWARE_BASE_URL set in the environment of the Paperless container.
|
|
67
|
-
|
|
68
|
-
Tests (fake local service, no network, no key):
|
|
69
|
-
python -m venv .venv
|
|
70
|
-
.venv/bin/pip install pytest (Windows: .venv\Scripts\pip install pytest)
|
|
71
|
-
.venv/bin/python -m pytest -p no:cacheprovider . (Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .)
|
ocr_software-0.1.0/PKG-INFO
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ocr-software
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Client and command line for the ocr-software.com OCR API: text, word boxes, layout, searchable PDF.
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Project-URL: Homepage, https://ocr-software.com/
|
|
7
|
-
Project-URL: Repository, https://github.com/ocr-software/ocr-software-python
|
|
8
|
-
Keywords: ocr,pdf,searchable-pdf,hocr,markdown,document-ai
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
11
|
-
Requires-Python: >=3.9
|
|
12
|
-
Description-Content-Type: text/plain
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Provides-Extra: test
|
|
15
|
-
Requires-Dist: pytest==9.0.2; extra == "test"
|
|
16
|
-
Dynamic: license-file
|
|
17
|
-
|
|
18
|
-
ocr-software: Python client and command line for the ocr-software.com OCR API (MIT, standard library only, Python 3.9 or newer).
|
|
19
|
-
|
|
20
|
-
Install:
|
|
21
|
-
pipx install ocr-software command line only, in its own environment
|
|
22
|
-
pip install ocr-software client library, inside a venv
|
|
23
|
-
uvx ocr-software --version run once without installing (uv)
|
|
24
|
-
First call (list the pipelines, then read one file):
|
|
25
|
-
ocr-software --list-pipelines
|
|
26
|
-
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
27
|
-
|
|
28
|
-
Settings (environment; the command line flag wins):
|
|
29
|
-
OCR_SOFTWARE_API_KEY API key (starts with ocr_). OCR_KEY is read too, it is the name used in the API docs.
|
|
30
|
-
OCR_SOFTWARE_BASE_URL default https://api.ocr-software.com ; own server e.g. http://127.0.0.1:8080 (also --base-url). OCR_BASE_URL is read too.
|
|
31
|
-
OCR_SOFTWARE_ALLOWED_DIR optional: read documents only from below this folder (symlinks and .. do not escape)
|
|
32
|
-
The key is never printed and never part of an error message. Without --pipeline the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; --list-pipelines marks it. In Python: client.ocr(path, client.default_pipeline()).
|
|
33
|
-
|
|
34
|
-
Command line:
|
|
35
|
-
ocr-software --list-pipelines available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
36
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run page count and price in euros, nothing runs, nothing is billed
|
|
37
|
-
ocr-software scan.pdf text to stdout, with the default pipeline (named on stderr)
|
|
38
|
-
ocr-software scan.pdf --pipeline NAME@VERSION text to stdout
|
|
39
|
-
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
40
|
-
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
41
|
-
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf searchable PDF, -o is required
|
|
42
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
43
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 your own server
|
|
44
|
-
python -m ocr_software ... the same command without the script on PATH
|
|
45
|
-
Options: --format text (default) | md | json | hocr | pdf ; --dpi 150|200|300 (PDF render resolution) ;
|
|
46
|
-
--timeout SECONDS (wait for the job, default 3600) ; --job-budget MILLICENTS (cap; ignored where billing is off) ; --dry-run ; --version
|
|
47
|
-
Without -o the result goes to stdout as UTF-8 (not for pdf). With -o the file appears whole or not at all, an existing
|
|
48
|
-
file is replaced, and the input file itself is refused as output.
|
|
49
|
-
|
|
50
|
-
Exit codes:
|
|
51
|
-
0 done, every page read
|
|
52
|
-
1 error from the service or the network (message on stderr with the API error code, for example 401 unauthorized);
|
|
53
|
-
also an address that does not answer: a typo and an outage look the same, so a script may retry this
|
|
54
|
-
2 wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https)
|
|
55
|
-
3 the job is done but a page failed or did not run, or the job stopped early: the result is written anyway,
|
|
56
|
-
stderr says what is missing and names the job; treat the file as incomplete
|
|
57
|
-
4 the job did not finish within --timeout; it keeps running, stderr names the job
|
|
58
|
-
|
|
59
|
-
Python:
|
|
60
|
-
from ocr_software import Client, PagesUnread
|
|
61
|
-
client = Client() # key and address from the environment
|
|
62
|
-
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
63
|
-
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
64
|
-
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
65
|
-
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
66
|
-
client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
67
|
-
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
68
|
-
Price: the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001).
|
|
69
|
-
Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits:
|
|
70
|
-
https://ocr-software.com/legal/fair-usage/ ; for more volume write to info@ocr-software.com.
|
|
71
|
-
Word boxes (json): box = [x0, y0, x1, y1] in pixels of the page image, origin top left; width, height and dpi of the page say which
|
|
72
|
-
image. In PDF points: pixels * 72 / dpi. Per word, verified is true only where a second reader confirmed it (scan-vlm-ctc@2);
|
|
73
|
-
safe_ok is always false today. Judge by confidence (0 to 1). Every field: https://ocr-software.com/docs/reference/
|
|
74
|
-
Retries follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or Retry-After). An
|
|
75
|
-
upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection
|
|
76
|
-
can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on
|
|
77
|
-
Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A Retry-After over 60 s (locked_out) is not waited for. A submit carries an Idempotency-Key, so a retry never creates a second job.
|
|
78
|
-
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
79
|
-
|
|
80
|
-
Paperless-ngx, pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
81
|
-
#!/bin/sh
|
|
82
|
-
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
83
|
-
with OCR_SOFTWARE_API_KEY and OCR_SOFTWARE_BASE_URL set in the environment of the Paperless container.
|
|
84
|
-
|
|
85
|
-
Tests (fake local service, no network, no key):
|
|
86
|
-
python -m venv .venv
|
|
87
|
-
.venv/bin/pip install pytest (Windows: .venv\Scripts\pip install pytest)
|
|
88
|
-
.venv/bin/python -m pytest -p no:cacheprovider . (Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .)
|
ocr_software-0.1.0/README.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
ocr-software: Python client and command line for the ocr-software.com OCR API (MIT, standard library only, Python 3.9 or newer).
|
|
2
|
-
|
|
3
|
-
Install:
|
|
4
|
-
pipx install ocr-software command line only, in its own environment
|
|
5
|
-
pip install ocr-software client library, inside a venv
|
|
6
|
-
uvx ocr-software --version run once without installing (uv)
|
|
7
|
-
First call (list the pipelines, then read one file):
|
|
8
|
-
ocr-software --list-pipelines
|
|
9
|
-
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
10
|
-
|
|
11
|
-
Settings (environment; the command line flag wins):
|
|
12
|
-
OCR_SOFTWARE_API_KEY API key (starts with ocr_). OCR_KEY is read too, it is the name used in the API docs.
|
|
13
|
-
OCR_SOFTWARE_BASE_URL default https://api.ocr-software.com ; own server e.g. http://127.0.0.1:8080 (also --base-url). OCR_BASE_URL is read too.
|
|
14
|
-
OCR_SOFTWARE_ALLOWED_DIR optional: read documents only from below this folder (symlinks and .. do not escape)
|
|
15
|
-
The key is never printed and never part of an error message. Without --pipeline the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; --list-pipelines marks it. In Python: client.ocr(path, client.default_pipeline()).
|
|
16
|
-
|
|
17
|
-
Command line:
|
|
18
|
-
ocr-software --list-pipelines available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
19
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run page count and price in euros, nothing runs, nothing is billed
|
|
20
|
-
ocr-software scan.pdf text to stdout, with the default pipeline (named on stderr)
|
|
21
|
-
ocr-software scan.pdf --pipeline NAME@VERSION text to stdout
|
|
22
|
-
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
23
|
-
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
24
|
-
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf searchable PDF, -o is required
|
|
25
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
26
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 your own server
|
|
27
|
-
python -m ocr_software ... the same command without the script on PATH
|
|
28
|
-
Options: --format text (default) | md | json | hocr | pdf ; --dpi 150|200|300 (PDF render resolution) ;
|
|
29
|
-
--timeout SECONDS (wait for the job, default 3600) ; --job-budget MILLICENTS (cap; ignored where billing is off) ; --dry-run ; --version
|
|
30
|
-
Without -o the result goes to stdout as UTF-8 (not for pdf). With -o the file appears whole or not at all, an existing
|
|
31
|
-
file is replaced, and the input file itself is refused as output.
|
|
32
|
-
|
|
33
|
-
Exit codes:
|
|
34
|
-
0 done, every page read
|
|
35
|
-
1 error from the service or the network (message on stderr with the API error code, for example 401 unauthorized);
|
|
36
|
-
also an address that does not answer: a typo and an outage look the same, so a script may retry this
|
|
37
|
-
2 wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https)
|
|
38
|
-
3 the job is done but a page failed or did not run, or the job stopped early: the result is written anyway,
|
|
39
|
-
stderr says what is missing and names the job; treat the file as incomplete
|
|
40
|
-
4 the job did not finish within --timeout; it keeps running, stderr names the job
|
|
41
|
-
|
|
42
|
-
Python:
|
|
43
|
-
from ocr_software import Client, PagesUnread
|
|
44
|
-
client = Client() # key and address from the environment
|
|
45
|
-
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
46
|
-
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
47
|
-
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
48
|
-
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
49
|
-
client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
50
|
-
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
51
|
-
Price: the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001).
|
|
52
|
-
Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits:
|
|
53
|
-
https://ocr-software.com/legal/fair-usage/ ; for more volume write to info@ocr-software.com.
|
|
54
|
-
Word boxes (json): box = [x0, y0, x1, y1] in pixels of the page image, origin top left; width, height and dpi of the page say which
|
|
55
|
-
image. In PDF points: pixels * 72 / dpi. Per word, verified is true only where a second reader confirmed it (scan-vlm-ctc@2);
|
|
56
|
-
safe_ok is always false today. Judge by confidence (0 to 1). Every field: https://ocr-software.com/docs/reference/
|
|
57
|
-
Retries follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or Retry-After). An
|
|
58
|
-
upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection
|
|
59
|
-
can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on
|
|
60
|
-
Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A Retry-After over 60 s (locked_out) is not waited for. A submit carries an Idempotency-Key, so a retry never creates a second job.
|
|
61
|
-
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
62
|
-
|
|
63
|
-
Paperless-ngx, pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
64
|
-
#!/bin/sh
|
|
65
|
-
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
66
|
-
with OCR_SOFTWARE_API_KEY and OCR_SOFTWARE_BASE_URL set in the environment of the Paperless container.
|
|
67
|
-
|
|
68
|
-
Tests (fake local service, no network, no key):
|
|
69
|
-
python -m venv .venv
|
|
70
|
-
.venv/bin/pip install pytest (Windows: .venv\Scripts\pip install pytest)
|
|
71
|
-
.venv/bin/python -m pytest -p no:cacheprovider . (Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .)
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ocr-software
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Client and command line for the ocr-software.com OCR API: text, word boxes, layout, searchable PDF.
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Project-URL: Homepage, https://ocr-software.com/
|
|
7
|
-
Project-URL: Repository, https://github.com/ocr-software/ocr-software-python
|
|
8
|
-
Keywords: ocr,pdf,searchable-pdf,hocr,markdown,document-ai
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
11
|
-
Requires-Python: >=3.9
|
|
12
|
-
Description-Content-Type: text/plain
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Provides-Extra: test
|
|
15
|
-
Requires-Dist: pytest==9.0.2; extra == "test"
|
|
16
|
-
Dynamic: license-file
|
|
17
|
-
|
|
18
|
-
ocr-software: Python client and command line for the ocr-software.com OCR API (MIT, standard library only, Python 3.9 or newer).
|
|
19
|
-
|
|
20
|
-
Install:
|
|
21
|
-
pipx install ocr-software command line only, in its own environment
|
|
22
|
-
pip install ocr-software client library, inside a venv
|
|
23
|
-
uvx ocr-software --version run once without installing (uv)
|
|
24
|
-
First call (list the pipelines, then read one file):
|
|
25
|
-
ocr-software --list-pipelines
|
|
26
|
-
ocr-software scan.pdf --pipeline scan-ctc@2 -o scan.txt
|
|
27
|
-
|
|
28
|
-
Settings (environment; the command line flag wins):
|
|
29
|
-
OCR_SOFTWARE_API_KEY API key (starts with ocr_). OCR_KEY is read too, it is the name used in the API docs.
|
|
30
|
-
OCR_SOFTWARE_BASE_URL default https://api.ocr-software.com ; own server e.g. http://127.0.0.1:8080 (also --base-url). OCR_BASE_URL is read too.
|
|
31
|
-
OCR_SOFTWARE_ALLOWED_DIR optional: read documents only from below this folder (symlinks and .. do not escape)
|
|
32
|
-
The key is never printed and never part of an error message. Without --pipeline the default is used: the fastest and cheapest available pipeline (no previews). It is named on stderr; --list-pipelines marks it. In Python: client.ocr(path, client.default_pipeline()).
|
|
33
|
-
|
|
34
|
-
Command line:
|
|
35
|
-
ocr-software --list-pipelines available pipelines, one per line: name@version, tab, what it delivers and costs; the default one on stderr (no key needed)
|
|
36
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --dry-run page count and price in euros, nothing runs, nothing is billed
|
|
37
|
-
ocr-software scan.pdf text to stdout, with the default pipeline (named on stderr)
|
|
38
|
-
ocr-software scan.pdf --pipeline NAME@VERSION text to stdout
|
|
39
|
-
ocr-software scan.pdf -o scan.md --pipeline NAME@VERSION --format md
|
|
40
|
-
ocr-software scan.pdf -o scan.pdf.txt --pipeline NAME@VERSION
|
|
41
|
-
ocr-software scan.pdf -o searchable.pdf --pipeline NAME@VERSION --format pdf searchable PDF, -o is required
|
|
42
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --format json > scan.json
|
|
43
|
-
ocr-software scan.pdf --pipeline NAME@VERSION --base-url http://10.0.0.5:8080 your own server
|
|
44
|
-
python -m ocr_software ... the same command without the script on PATH
|
|
45
|
-
Options: --format text (default) | md | json | hocr | pdf ; --dpi 150|200|300 (PDF render resolution) ;
|
|
46
|
-
--timeout SECONDS (wait for the job, default 3600) ; --job-budget MILLICENTS (cap; ignored where billing is off) ; --dry-run ; --version
|
|
47
|
-
Without -o the result goes to stdout as UTF-8 (not for pdf). With -o the file appears whole or not at all, an existing
|
|
48
|
-
file is replaced, and the input file itself is refused as output.
|
|
49
|
-
|
|
50
|
-
Exit codes:
|
|
51
|
-
0 done, every page read
|
|
52
|
-
1 error from the service or the network (message on stderr with the API error code, for example 401 unauthorized);
|
|
53
|
-
also an address that does not answer: a typo and an outage look the same, so a script may retry this
|
|
54
|
-
2 wrong call: unreadable or unsupported input, output not writable, no key, malformed address (not http/https)
|
|
55
|
-
3 the job is done but a page failed or did not run, or the job stopped early: the result is written anyway,
|
|
56
|
-
stderr says what is missing and names the job; treat the file as incomplete
|
|
57
|
-
4 the job did not finish within --timeout; it keeps running, stderr names the job
|
|
58
|
-
|
|
59
|
-
Python:
|
|
60
|
-
from ocr_software import Client, PagesUnread
|
|
61
|
-
client = Client() # key and address from the environment
|
|
62
|
-
text = client.ocr("scan.pdf", "NAME@VERSION", "md") # bytes; raises PagesUnread (with .data) if a page was not read
|
|
63
|
-
pdf = client.ocr("scan.pdf", "NAME@VERSION", "pdf") # searchable PDF
|
|
64
|
-
job = client.submit("scan.pdf", "NAME@VERSION") # step by step: submit, wait, result
|
|
65
|
-
client.wait(job["job_id"]); client.result(job["job_id"], "json")
|
|
66
|
-
client.quote("scan.pdf", "NAME@VERSION") # dry run: page count and price, nothing runs
|
|
67
|
-
from ocr_software import price_sentence; price_sentence(q) # the same sentence as --dry-run, in euros
|
|
68
|
-
Price: the API counts money in millicents, 100,000 millicents = 1 EUR (a page of the cheapest pipeline costs 100 = EUR 0.001).
|
|
69
|
-
Today nothing is charged ("you pay EUR 0.00 today"); the list price is shown for information. Free use has limits:
|
|
70
|
-
https://ocr-software.com/legal/fair-usage/ ; for more volume write to info@ocr-software.com.
|
|
71
|
-
Word boxes (json): box = [x0, y0, x1, y1] in pixels of the page image, origin top left; width, height and dpi of the page say which
|
|
72
|
-
image. In PDF points: pixels * 72 / dpi. Per word, verified is true only where a second reader confirmed it (scan-vlm-ctc@2);
|
|
73
|
-
safe_ok is always false today. Judge by confidence (0 to 1). Every field: https://ocr-software.com/docs/reference/
|
|
74
|
-
Retries follow the API rules: 429, 500, 502, 503, 504 and network errors up to 5 times (waits 1, 2, 4, 8, 16 s or Retry-After). An
|
|
75
|
-
upload the service cuts off (it does that beyond 2 uploads at once per key, instead of answering 429) counts like 429. If no connection
|
|
76
|
-
can be made at all (wrong address, host down) it gives up after 2 retries and names the address: a few seconds, up to about 10 s on
|
|
77
|
-
Windows, where a refused port itself takes 2 s per try (connect timeout 10 s). A Retry-After over 60 s (locked_out) is not waited for. A submit carries an Idempotency-Key, so a retry never creates a second job.
|
|
78
|
-
Every document is checked locally first: PDF, PNG, JPEG or TIFF by its first bytes, at most 100 MiB.
|
|
79
|
-
|
|
80
|
-
Paperless-ngx, pre-consume script (sketch, not tried against a real Paperless; a non-PDF input keeps its file name but becomes a PDF):
|
|
81
|
-
#!/bin/sh
|
|
82
|
-
ocr-software "$DOCUMENT_WORKING_PATH" --pipeline NAME@VERSION --format pdf -o "$DOCUMENT_WORKING_PATH.ocr" && mv "$DOCUMENT_WORKING_PATH.ocr" "$DOCUMENT_WORKING_PATH"
|
|
83
|
-
with OCR_SOFTWARE_API_KEY and OCR_SOFTWARE_BASE_URL set in the environment of the Paperless container.
|
|
84
|
-
|
|
85
|
-
Tests (fake local service, no network, no key):
|
|
86
|
-
python -m venv .venv
|
|
87
|
-
.venv/bin/pip install pytest (Windows: .venv\Scripts\pip install pytest)
|
|
88
|
-
.venv/bin/python -m pytest -p no:cacheprovider . (Windows: .venv\Scripts\python -m pytest -p no:cacheprovider .)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|