veriis 0.1.0__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.
@@ -0,0 +1,82 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ # Anchored to repo root: these are Python build/venv artifacts. Unanchored
14
+ # (`lib/`) they also match nested JS dirs like frontend/src/lib — which silently
15
+ # dropped the frontend's lib/ from git and broke the CI build.
16
+ /lib/
17
+ /lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ share/python-wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # uv
29
+ .venv/
30
+ venv/
31
+ ENV/
32
+ env/
33
+
34
+ # Testing
35
+ .pytest_cache/
36
+ .coverage
37
+ .coverage.*
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ coverage.xml
42
+ *.cover
43
+ .hypothesis/
44
+
45
+ # mypy
46
+ .mypy_cache/
47
+ .dmypy.json
48
+ dmypy.json
49
+
50
+ # Ruff
51
+ .ruff_cache/
52
+
53
+ # Environments
54
+ .env
55
+ .env.local
56
+ .env.*.local
57
+
58
+ # IDEs
59
+ .idea/
60
+ .vscode/
61
+ *.swp
62
+ *.swo
63
+ .DS_Store
64
+
65
+ # Logs
66
+ *.log
67
+ logs/
68
+
69
+ # Tessdata downloads (built into image, not committed)
70
+ assets/tessdata/*.traineddata
71
+
72
+ # OS
73
+ Thumbs.db
74
+
75
+ # Docker
76
+ .docker/
77
+
78
+ # Superpowers brainstorming companion (local mockups, not committed)
79
+ .superpowers/
80
+
81
+ # Local Codex/runtime scratch files and UI migration backups
82
+ .tmp/
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ All notable changes to the Veris OCR Python client are documented here.
4
+
5
+ ## 0.1.0
6
+
7
+ - Initial synchronous and asynchronous Python clients.
8
+ - Passport, document, resume, history, admin, and health resources.
9
+ - Typed Pydantic response models.
10
+ - File-path, bytes, file-object, and explicit file-descriptor inputs.
11
+ - Typed API, connection, timeout, validation, and rate-limit errors.
12
+ - Bounded retries for idempotent requests on rate limits and transient service
13
+ failures.
14
+ - Redirect blocking to prevent forwarding API credentials to another origin.
veriis-0.1.0/LICENSE ADDED
@@ -0,0 +1,6 @@
1
+ Copyright (c) 2026 RecursAI Technologies. All rights reserved.
2
+
3
+ This software is proprietary and confidential. No permission is granted to
4
+ use, copy, modify, merge, publish, distribute, sublicense, or sell copies of
5
+ the software except under a separate written agreement with RecursAI
6
+ Technologies.
veriis-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,299 @@
1
+ Metadata-Version: 2.4
2
+ Name: veriis
3
+ Version: 0.1.0
4
+ Summary: Official Python client for the Veris OCR API.
5
+ Project-URL: Homepage, https://github.com/MohamedNasirS/veris-ocr-recursai
6
+ Project-URL: Documentation, https://github.com/MohamedNasirS/veris-ocr-recursai/tree/main/clients/python
7
+ Project-URL: Repository, https://github.com/MohamedNasirS/veris-ocr-recursai.git
8
+ Project-URL: Issues, https://github.com/MohamedNasirS/veris-ocr-recursai/issues
9
+ Author-email: RecursAI Technologies <founders@recursai.com>
10
+ License-Expression: LicenseRef-Proprietary
11
+ License-File: LICENSE
12
+ Keywords: document,mrz,ocr,passport,recursai,resume,veris
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: <3.15,>=3.10
25
+ Requires-Dist: httpx<1,>=0.27
26
+ Requires-Dist: pydantic<3,>=2.8
27
+ Provides-Extra: dev
28
+ Requires-Dist: build>=1.2; extra == 'dev'
29
+ Requires-Dist: hatchling<2,>=1.27; extra == 'dev'
30
+ Requires-Dist: mypy<2,>=1.13; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
32
+ Requires-Dist: pytest-cov>=6; extra == 'dev'
33
+ Requires-Dist: pytest>=8.3; extra == 'dev'
34
+ Requires-Dist: ruff>=0.8; extra == 'dev'
35
+ Requires-Dist: twine>=6; extra == 'dev'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # veriis
39
+
40
+ Official Python client for the Veris OCR API by RecursAI Technologies. The
41
+ service performs passport MRZ extraction, general document OCR, and structured
42
+ resume parsing; this package provides a small typed client for calling it.
43
+
44
+ - Synchronous and asynchronous clients
45
+ - Typed Pydantic response models
46
+ - File paths, raw bytes, binary file objects, and explicit file descriptors
47
+ - Typed errors, request timeouts, and bounded retries
48
+ - Python 3.10–3.14
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install veriis
54
+ ```
55
+
56
+ ## Quickstart
57
+
58
+ ```python
59
+ from veriis import VerisOCR
60
+
61
+ with VerisOCR(
62
+ base_url="https://veris.recursai.in",
63
+ api_key="pk_live_...",
64
+ ) as client:
65
+ passport = client.passport.extract("passport.jpg")
66
+ print(passport.mrz.passport_number, passport.mrz.expiry_date)
67
+
68
+ document = client.document.extract("invoice.pdf", lang="eng+fra")
69
+ print(document.page_count, document.pages[0].text)
70
+
71
+ resume = client.resume.extract("cv.pdf")
72
+ print(resume.name, resume.total_experience_human, resume.skills)
73
+ ```
74
+
75
+ The same settings can come from the environment:
76
+
77
+ ```bash
78
+ export VERIS_OCR_BASE_URL=https://veris.recursai.in
79
+ export VERIS_OCR_API_KEY=pk_live_...
80
+ ```
81
+
82
+ ```python
83
+ from veriis import VerisOCR
84
+
85
+ client = VerisOCR()
86
+ ```
87
+
88
+ ## Async client
89
+
90
+ ```python
91
+ import asyncio
92
+
93
+ from veriis import AsyncVerisOCR
94
+
95
+
96
+ async def main() -> None:
97
+ async with AsyncVerisOCR(
98
+ base_url="https://veris.recursai.in",
99
+ api_key="pk_live_...",
100
+ ) as client:
101
+ result = await client.document.extract("invoice.pdf", lang="eng")
102
+ print(result.pages[0].text)
103
+
104
+
105
+ asyncio.run(main())
106
+ ```
107
+
108
+ ## Configuration
109
+
110
+ ```python
111
+ client = VerisOCR(
112
+ base_url="https://veris.recursai.in", # or VERIS_OCR_BASE_URL
113
+ api_key="pk_live_...", # or VERIS_OCR_API_KEY
114
+ admin_token="...", # or VERIS_OCR_ADMIN_TOKEN
115
+ timeout=120.0, # seconds; OCR can be slow
116
+ max_retries=2, # transient failures on idempotent operations
117
+ headers={"X-Application": "billing"},
118
+ )
119
+ ```
120
+
121
+ Every resource method also accepts `timeout=` and `max_retries=` overrides.
122
+ Retries apply to idempotent health, history, admin-list, and key-revoke
123
+ operations. Extraction and key-creation requests are never automatically
124
+ retried because repeating them could create duplicate work or keys. Redirects
125
+ are surfaced as errors so API credentials are never forwarded to another
126
+ origin. Async requests can be cancelled with normal asyncio task cancellation.
127
+
128
+ ## File inputs
129
+
130
+ Extraction methods accept:
131
+
132
+ - a `str` or `pathlib.Path` filesystem path;
133
+ - `bytes`, `bytearray`, or `memoryview`;
134
+ - a binary file object such as an open file or `io.BytesIO`;
135
+ - `FileDescriptor(data=..., filename=..., content_type=...)`.
136
+
137
+ The SDK detects JPEG, PNG, WEBP, PDF, GIF, BMP, and TIFF signatures. The Veris
138
+ OCR server currently accepts JPEG, PNG, WEBP, and PDF extraction uploads.
139
+
140
+ ```python
141
+ from veriis import FileDescriptor
142
+
143
+ result = client.passport.extract(
144
+ FileDescriptor(
145
+ data=image_bytes,
146
+ filename="passport-front.jpg",
147
+ content_type="image/jpeg",
148
+ )
149
+ )
150
+ ```
151
+
152
+ ## Resources
153
+
154
+ ```python
155
+ client.passport.extract(file)
156
+ client.document.extract(file, lang="eng")
157
+ client.resume.extract(file)
158
+
159
+ client.history.list(mode="passport", limit=50, offset=0)
160
+ client.history.get(item_id)
161
+ client.history.delete(item_id)
162
+ client.history.clear()
163
+
164
+ client.health.check() # no API key required
165
+ ```
166
+
167
+ Admin operations use `admin_token`, not `api_key`:
168
+
169
+ ```python
170
+ created = client.admin.create_key(
171
+ customer_email="developer@example.com",
172
+ customer_name="Example Developer",
173
+ key_name="production",
174
+ allowed_ocr_modes=["passport", "document"],
175
+ )
176
+ print(created.key) # returned only once
177
+
178
+ keys = client.admin.list_keys(include_revoked=False)
179
+ client.admin.revoke_key(created.api_key_id)
180
+ ```
181
+
182
+ ## Response models
183
+
184
+ Successful responses are Pydantic models. Access fields as attributes or
185
+ convert them back to JSON-compatible dictionaries:
186
+
187
+ ```python
188
+ result = client.passport.extract("passport.jpg")
189
+ print(result.request_id)
190
+ print(result.model_dump(mode="json"))
191
+ ```
192
+
193
+ Models allow unknown response fields so compatible server additions do not
194
+ break older client versions.
195
+
196
+ ## Errors
197
+
198
+ HTTP, timeout, connection, and invalid-response failures derive from
199
+ `VerisOCRError`:
200
+
201
+ ```python
202
+ from veriis import VerisOCRBadRequestError, VerisOCRRateLimitError
203
+
204
+ try:
205
+ client.passport.extract("passport.jpg")
206
+ except VerisOCRRateLimitError as exc:
207
+ print(f"Retry after {exc.retry_after} seconds")
208
+ except VerisOCRBadRequestError as exc:
209
+ print(exc.code, exc.request_id, str(exc))
210
+ ```
211
+
212
+ Available subclasses:
213
+
214
+ - `VerisOCRBadRequestError` for 400 and 413
215
+ - `VerisOCRAuthenticationError` for 401 and 403
216
+ - `VerisOCRNotFoundError` for 404
217
+ - `VerisOCRValidationError` for 422
218
+ - `VerisOCRRateLimitError` for 429
219
+ - `VerisOCRServerError` for 5xx
220
+ - `VerisOCRTimeoutError` for request timeouts
221
+ - `VerisOCRConnectionError` for network and connection failures
222
+
223
+ Local input failures stay idiomatic: missing paths raise `FileNotFoundError`,
224
+ unsupported file values raise `TypeError`, and invalid admin-key parameters
225
+ raise Pydantic `ValidationError` before any request is sent.
226
+
227
+ ## Development and release
228
+
229
+ Run these commands from `clients/python`. The locked environment is the source
230
+ of the build tools used to create release artifacts:
231
+
232
+ ```bash
233
+ uv sync --locked --extra dev --python 3.12
234
+ uv run --locked ruff format --check .
235
+ uv run --locked ruff check .
236
+ uv run --locked mypy
237
+ uv run --locked pytest --cov
238
+ uv run --locked python -m build --no-isolation
239
+ uv run --locked twine check --strict dist/*
240
+ uv run --locked python scripts/check_dist.py
241
+ ```
242
+
243
+ Remove existing files from `dist/` before making a release build so the
244
+ distribution validator sees exactly one wheel and one source distribution.
245
+
246
+ TestPyPI can be used as an optional manual validation step. Configure a
247
+ TestPyPI API token for Twine, upload the freshly validated artifacts, install
248
+ the exact candidate version, and run an import smoke test:
249
+
250
+ ```bash
251
+ python -m twine upload --repository testpypi dist/*
252
+ python -m pip install --index-url https://test.pypi.org/simple/ \
253
+ --extra-index-url https://pypi.org/simple/ veriis==0.1.0
254
+ python -c "from veriis import VerisOCR, __version__; print(__version__)"
255
+ ```
256
+
257
+ Production releases use only the repository's Trusted Publishing workflow; do
258
+ not upload production artifacts manually. Because the bundled license permits
259
+ use and redistribution only under a separate written agreement, obtain the
260
+ appropriate business/legal approval before making the artifacts public.
261
+ Before the first automated release, create the `veriis` project on
262
+ PyPI or configure a pending publisher with these exact settings:
263
+
264
+ - GitHub owner: `MohamedNasirS`
265
+ - Repository: `veris-ocr-recursai`
266
+ - Workflow: `python-client-release.yml`
267
+ - Environment: `pypi`
268
+
269
+ A pending publisher does not reserve the project name until its first
270
+ successful upload. Protect the GitHub `pypi` environment with a required
271
+ reviewer. Also add a repository ruleset for tags matching `python-v*` that
272
+ restricts tag creation, updates, and deletion to release maintainers.
273
+
274
+ For each release:
275
+
276
+ 1. Update `src/veriis/_version.py` and `CHANGELOG.md`.
277
+ 2. Regenerate `uv.lock` if dependency metadata changed, then run
278
+ `uv lock --check`.
279
+ 3. Remove old artifacts, run the development and distribution checks above,
280
+ and verify both clean-environment smoke installs.
281
+ 4. Merge the release commit to protected `main` and wait for Python client CI
282
+ to pass.
283
+ 5. Create and push an annotated tag whose version exactly matches
284
+ `__version__`:
285
+
286
+ ```bash
287
+ git tag -a python-v0.1.0 -m "Python client 0.1.0"
288
+ git push origin python-v0.1.0
289
+ ```
290
+
291
+ The workflow rejects release commits that are not reachable from `main`,
292
+ checks that the tag equals `__version__`, runs linting, typing, and tests,
293
+ builds and validates the wheel and source distribution once, smoke-installs
294
+ both artifacts, and publishes that exact artifact through PyPI's OpenID
295
+ Connect trusted-publisher flow.
296
+
297
+ ## License
298
+
299
+ Proprietary — © RecursAI Technologies.
veriis-0.1.0/README.md ADDED
@@ -0,0 +1,262 @@
1
+ # veriis
2
+
3
+ Official Python client for the Veris OCR API by RecursAI Technologies. The
4
+ service performs passport MRZ extraction, general document OCR, and structured
5
+ resume parsing; this package provides a small typed client for calling it.
6
+
7
+ - Synchronous and asynchronous clients
8
+ - Typed Pydantic response models
9
+ - File paths, raw bytes, binary file objects, and explicit file descriptors
10
+ - Typed errors, request timeouts, and bounded retries
11
+ - Python 3.10–3.14
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pip install veriis
17
+ ```
18
+
19
+ ## Quickstart
20
+
21
+ ```python
22
+ from veriis import VerisOCR
23
+
24
+ with VerisOCR(
25
+ base_url="https://veris.recursai.in",
26
+ api_key="pk_live_...",
27
+ ) as client:
28
+ passport = client.passport.extract("passport.jpg")
29
+ print(passport.mrz.passport_number, passport.mrz.expiry_date)
30
+
31
+ document = client.document.extract("invoice.pdf", lang="eng+fra")
32
+ print(document.page_count, document.pages[0].text)
33
+
34
+ resume = client.resume.extract("cv.pdf")
35
+ print(resume.name, resume.total_experience_human, resume.skills)
36
+ ```
37
+
38
+ The same settings can come from the environment:
39
+
40
+ ```bash
41
+ export VERIS_OCR_BASE_URL=https://veris.recursai.in
42
+ export VERIS_OCR_API_KEY=pk_live_...
43
+ ```
44
+
45
+ ```python
46
+ from veriis import VerisOCR
47
+
48
+ client = VerisOCR()
49
+ ```
50
+
51
+ ## Async client
52
+
53
+ ```python
54
+ import asyncio
55
+
56
+ from veriis import AsyncVerisOCR
57
+
58
+
59
+ async def main() -> None:
60
+ async with AsyncVerisOCR(
61
+ base_url="https://veris.recursai.in",
62
+ api_key="pk_live_...",
63
+ ) as client:
64
+ result = await client.document.extract("invoice.pdf", lang="eng")
65
+ print(result.pages[0].text)
66
+
67
+
68
+ asyncio.run(main())
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ ```python
74
+ client = VerisOCR(
75
+ base_url="https://veris.recursai.in", # or VERIS_OCR_BASE_URL
76
+ api_key="pk_live_...", # or VERIS_OCR_API_KEY
77
+ admin_token="...", # or VERIS_OCR_ADMIN_TOKEN
78
+ timeout=120.0, # seconds; OCR can be slow
79
+ max_retries=2, # transient failures on idempotent operations
80
+ headers={"X-Application": "billing"},
81
+ )
82
+ ```
83
+
84
+ Every resource method also accepts `timeout=` and `max_retries=` overrides.
85
+ Retries apply to idempotent health, history, admin-list, and key-revoke
86
+ operations. Extraction and key-creation requests are never automatically
87
+ retried because repeating them could create duplicate work or keys. Redirects
88
+ are surfaced as errors so API credentials are never forwarded to another
89
+ origin. Async requests can be cancelled with normal asyncio task cancellation.
90
+
91
+ ## File inputs
92
+
93
+ Extraction methods accept:
94
+
95
+ - a `str` or `pathlib.Path` filesystem path;
96
+ - `bytes`, `bytearray`, or `memoryview`;
97
+ - a binary file object such as an open file or `io.BytesIO`;
98
+ - `FileDescriptor(data=..., filename=..., content_type=...)`.
99
+
100
+ The SDK detects JPEG, PNG, WEBP, PDF, GIF, BMP, and TIFF signatures. The Veris
101
+ OCR server currently accepts JPEG, PNG, WEBP, and PDF extraction uploads.
102
+
103
+ ```python
104
+ from veriis import FileDescriptor
105
+
106
+ result = client.passport.extract(
107
+ FileDescriptor(
108
+ data=image_bytes,
109
+ filename="passport-front.jpg",
110
+ content_type="image/jpeg",
111
+ )
112
+ )
113
+ ```
114
+
115
+ ## Resources
116
+
117
+ ```python
118
+ client.passport.extract(file)
119
+ client.document.extract(file, lang="eng")
120
+ client.resume.extract(file)
121
+
122
+ client.history.list(mode="passport", limit=50, offset=0)
123
+ client.history.get(item_id)
124
+ client.history.delete(item_id)
125
+ client.history.clear()
126
+
127
+ client.health.check() # no API key required
128
+ ```
129
+
130
+ Admin operations use `admin_token`, not `api_key`:
131
+
132
+ ```python
133
+ created = client.admin.create_key(
134
+ customer_email="developer@example.com",
135
+ customer_name="Example Developer",
136
+ key_name="production",
137
+ allowed_ocr_modes=["passport", "document"],
138
+ )
139
+ print(created.key) # returned only once
140
+
141
+ keys = client.admin.list_keys(include_revoked=False)
142
+ client.admin.revoke_key(created.api_key_id)
143
+ ```
144
+
145
+ ## Response models
146
+
147
+ Successful responses are Pydantic models. Access fields as attributes or
148
+ convert them back to JSON-compatible dictionaries:
149
+
150
+ ```python
151
+ result = client.passport.extract("passport.jpg")
152
+ print(result.request_id)
153
+ print(result.model_dump(mode="json"))
154
+ ```
155
+
156
+ Models allow unknown response fields so compatible server additions do not
157
+ break older client versions.
158
+
159
+ ## Errors
160
+
161
+ HTTP, timeout, connection, and invalid-response failures derive from
162
+ `VerisOCRError`:
163
+
164
+ ```python
165
+ from veriis import VerisOCRBadRequestError, VerisOCRRateLimitError
166
+
167
+ try:
168
+ client.passport.extract("passport.jpg")
169
+ except VerisOCRRateLimitError as exc:
170
+ print(f"Retry after {exc.retry_after} seconds")
171
+ except VerisOCRBadRequestError as exc:
172
+ print(exc.code, exc.request_id, str(exc))
173
+ ```
174
+
175
+ Available subclasses:
176
+
177
+ - `VerisOCRBadRequestError` for 400 and 413
178
+ - `VerisOCRAuthenticationError` for 401 and 403
179
+ - `VerisOCRNotFoundError` for 404
180
+ - `VerisOCRValidationError` for 422
181
+ - `VerisOCRRateLimitError` for 429
182
+ - `VerisOCRServerError` for 5xx
183
+ - `VerisOCRTimeoutError` for request timeouts
184
+ - `VerisOCRConnectionError` for network and connection failures
185
+
186
+ Local input failures stay idiomatic: missing paths raise `FileNotFoundError`,
187
+ unsupported file values raise `TypeError`, and invalid admin-key parameters
188
+ raise Pydantic `ValidationError` before any request is sent.
189
+
190
+ ## Development and release
191
+
192
+ Run these commands from `clients/python`. The locked environment is the source
193
+ of the build tools used to create release artifacts:
194
+
195
+ ```bash
196
+ uv sync --locked --extra dev --python 3.12
197
+ uv run --locked ruff format --check .
198
+ uv run --locked ruff check .
199
+ uv run --locked mypy
200
+ uv run --locked pytest --cov
201
+ uv run --locked python -m build --no-isolation
202
+ uv run --locked twine check --strict dist/*
203
+ uv run --locked python scripts/check_dist.py
204
+ ```
205
+
206
+ Remove existing files from `dist/` before making a release build so the
207
+ distribution validator sees exactly one wheel and one source distribution.
208
+
209
+ TestPyPI can be used as an optional manual validation step. Configure a
210
+ TestPyPI API token for Twine, upload the freshly validated artifacts, install
211
+ the exact candidate version, and run an import smoke test:
212
+
213
+ ```bash
214
+ python -m twine upload --repository testpypi dist/*
215
+ python -m pip install --index-url https://test.pypi.org/simple/ \
216
+ --extra-index-url https://pypi.org/simple/ veriis==0.1.0
217
+ python -c "from veriis import VerisOCR, __version__; print(__version__)"
218
+ ```
219
+
220
+ Production releases use only the repository's Trusted Publishing workflow; do
221
+ not upload production artifacts manually. Because the bundled license permits
222
+ use and redistribution only under a separate written agreement, obtain the
223
+ appropriate business/legal approval before making the artifacts public.
224
+ Before the first automated release, create the `veriis` project on
225
+ PyPI or configure a pending publisher with these exact settings:
226
+
227
+ - GitHub owner: `MohamedNasirS`
228
+ - Repository: `veris-ocr-recursai`
229
+ - Workflow: `python-client-release.yml`
230
+ - Environment: `pypi`
231
+
232
+ A pending publisher does not reserve the project name until its first
233
+ successful upload. Protect the GitHub `pypi` environment with a required
234
+ reviewer. Also add a repository ruleset for tags matching `python-v*` that
235
+ restricts tag creation, updates, and deletion to release maintainers.
236
+
237
+ For each release:
238
+
239
+ 1. Update `src/veriis/_version.py` and `CHANGELOG.md`.
240
+ 2. Regenerate `uv.lock` if dependency metadata changed, then run
241
+ `uv lock --check`.
242
+ 3. Remove old artifacts, run the development and distribution checks above,
243
+ and verify both clean-environment smoke installs.
244
+ 4. Merge the release commit to protected `main` and wait for Python client CI
245
+ to pass.
246
+ 5. Create and push an annotated tag whose version exactly matches
247
+ `__version__`:
248
+
249
+ ```bash
250
+ git tag -a python-v0.1.0 -m "Python client 0.1.0"
251
+ git push origin python-v0.1.0
252
+ ```
253
+
254
+ The workflow rejects release commits that are not reachable from `main`,
255
+ checks that the tag equals `__version__`, runs linting, typing, and tests,
256
+ builds and validates the wheel and source distribution once, smoke-installs
257
+ both artifacts, and publishes that exact artifact through PyPI's OpenID
258
+ Connect trusted-publisher flow.
259
+
260
+ ## License
261
+
262
+ Proprietary — © RecursAI Technologies.
@@ -0,0 +1,16 @@
1
+ """Extract document text asynchronously."""
2
+
3
+ import asyncio
4
+
5
+ from veriis import AsyncVerisOCR
6
+
7
+
8
+ async def main() -> None:
9
+ async with AsyncVerisOCR() as client:
10
+ result = await client.document.extract("document.pdf", lang="eng")
11
+ for page in result.pages:
12
+ print(page.text)
13
+
14
+
15
+ if __name__ == "__main__":
16
+ asyncio.run(main())
@@ -0,0 +1,13 @@
1
+ """Extract passport data with settings supplied through environment variables."""
2
+
3
+ from veriis import VerisOCR
4
+
5
+
6
+ def main() -> None:
7
+ with VerisOCR() as client:
8
+ result = client.passport.extract("passport.jpg")
9
+ print(result.model_dump_json(indent=2))
10
+
11
+
12
+ if __name__ == "__main__":
13
+ main()