clairic 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,22 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Environment variables
13
+ .env
14
+
15
+ # Tooling caches
16
+ .pytest_cache/
17
+ .ruff_cache/
18
+
19
+ # Local agent notes and skills
20
+ .cursor/brainstorms/
21
+ .cursor/plans/
22
+ .claude/skills/
clairic-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vianney Mixtur
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
clairic-0.1.0/NOTICE ADDED
@@ -0,0 +1,18 @@
1
+ clairic is an unofficial project. It is not affiliated with, endorsed by, or
2
+ supported by Cloudflare, Inc. "Cloudflare", "Workers AI" and "Clairic" are
3
+ names of Cloudflare, Inc. products.
4
+
5
+ Docstrings in this package adapt text from the Cloudflare documentation,
6
+ which Cloudflare publishes under the Creative Commons Attribution 4.0
7
+ International license (CC BY 4.0, https://creativecommons.org/licenses/by/4.0/).
8
+ The adapted text was edited for length and context. Sources:
9
+
10
+ - Clairic model reference
11
+ https://developers.cloudflare.com/workers-ai/models/clairic/
12
+ - Clairic input and output JSON schemas
13
+ https://developers.cloudflare.com/workers-ai/models/clairic/schema-input.json
14
+ https://developers.cloudflare.com/workers-ai/models/clairic/schema-output.json
15
+ - Extraction models concepts
16
+ https://developers.cloudflare.com/workers-ai/concepts/extraction-models/
17
+ - "Clairic" launch post, The Cloudflare Blog
18
+ https://blog.cloudflare.com/clairic-extraction-model/
clairic-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.5
2
+ Name: clairic
3
+ Version: 0.1.0
4
+ Summary: Unofficial typed Python SDK for Cloudflare's Clairic extraction model, built on Pydantic.
5
+ Project-URL: Homepage, https://github.com/VianneyMI/clairic
6
+ Project-URL: Repository, https://github.com/VianneyMI/clairic
7
+ Project-URL: Issues, https://github.com/VianneyMI/clairic/issues
8
+ Project-URL: Clairic model reference, https://developers.cloudflare.com/workers-ai/models/clairic/
9
+ Author-email: Vianney Mixtur <vianney@consio.ai>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Vianney Mixtur
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ License-File: NOTICE
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Programming Language :: Python :: 3.14
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: >=3.10
45
+ Requires-Dist: httpx>=0.27
46
+ Requires-Dist: pydantic>=2.7
47
+ Requires-Dist: typing-extensions>=4.12
48
+ Description-Content-Type: text/markdown
49
+
50
+ # clairic
51
+
52
+ **Unofficial** typed Python SDK for [Cloudflare Clairic](https://developers.cloudflare.com/workers-ai/models/clairic/), the Workers AI extraction model. This project is not affiliated with or endorsed by Cloudflare.
53
+
54
+ Clairic reads a text and returns typed values for the fields you name: extracted, computed, estimated or forecast, each with a confidence score, a probability of absence, or a percentile range. `clairic` lets you declare those fields as a Pydantic model and get the answers back as typed Pydantic objects.
55
+
56
+ ```python
57
+ from typing import Annotated
58
+
59
+ from pydantic import BaseModel, Field
60
+
61
+ from clairic import Clairic, DateAnswer, Estimate, EstimateAnswer, Number, NumberAnswer, TextAnswer
62
+
63
+
64
+ class InvoiceExtraction(BaseModel):
65
+ invoice_number: TextAnswer
66
+ due_date: DateAnswer = Field(description="Issue date plus the net payment days")
67
+ total: Annotated[NumberAnswer[float], Number(decimals=2, unit="USD")] = Field(
68
+ description="Amount due including shipping"
69
+ )
70
+ po_number: TextAnswer = Field(description="Purchase order number")
71
+ days_to_pay: Annotated[EstimateAnswer[int], Estimate(min=0, max=120, step=1)] = Field(
72
+ description="Days after issue until this invoice is paid"
73
+ )
74
+
75
+
76
+ with Clairic() as clairic:
77
+ result = clairic.extract(
78
+ "Invoice INV-2291 from Northwind Supply, issued 2026-09-02, net 30. "
79
+ "4 pallets at $250.00 each, shipping $80.00.",
80
+ InvoiceExtraction,
81
+ )
82
+
83
+ result.data.total.value # 1080.0
84
+ result.data.total.confidence # 0.99995
85
+ result.data.po_number.value # None: the invoice has no PO number
86
+ result.data.days_to_pay.p90 # 37
87
+ ```
88
+
89
+ ## Install
90
+
91
+ ```sh
92
+ pip install clairic
93
+ ```
94
+
95
+ Python 3.10 or later. Dependencies: `httpx` and `pydantic` 2.
96
+
97
+ ## Credentials
98
+
99
+ The client reads `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN`, or takes them as arguments:
100
+
101
+ ```python
102
+ clairic = Clairic(account_id="...", api_token="...")
103
+ ```
104
+
105
+ Create the token in the Cloudflare dashboard with access to Workers AI.
106
+
107
+ ## Declaring fields
108
+
109
+ Each field of the extraction model is an answer type. The answer type sets the Clairic field type; an `Annotated` spec sets its options; `Field(description=...)` gives Clairic the instructions; a Pydantic `alias` sets the field name sent to Clairic.
110
+
111
+ | Answer type | Clairic type | Spec (options) |
112
+ |---|---|---|
113
+ | `TextAnswer` | `text`: a span of the input | `Text(unit, null_threshold)` |
114
+ | `NumberAnswer[float]`, `NumberAnswer[int]` | `number` (`int` requests whole numbers) | `Number(unit, null_threshold, decimals)` |
115
+ | `DateAnswer`, `TimeAnswer`, `DatetimeAnswer` | `date`, `time`, `datetime` | `Date(null_threshold)`, `Time(...)`, `Datetime(...)` |
116
+ | `DurationAnswer[float]`, `DurationAnswer[int]` | `duration` | `Duration(unit, null_threshold, decimals)`, unit defaults to seconds |
117
+ | `TextListAnswer` | `list` of text spans | `List(unit, decimals)` |
118
+ | `ListAnswer[int]`, `ListAnswer[float]`, `ListAnswer[date]` | `list` of numbers or dates | `List(unit, decimals)` |
119
+ | `EstimateAnswer[int]`, `EstimateAnswer[float]` | `estimate` with number bounds | `Estimate(min, max, step, scale, unit)`, required |
120
+ | `DateEstimateAnswer` | `estimate` with date bounds | `Estimate(min=date, max=date, step="month")`, required |
121
+ | `ForecastAnswer` | `forecast` of a series | `Forecast(min, max, horizon, interval, step, scale, unit)`, required |
122
+
123
+ Invalid declarations fail before any request: a non-answer annotation, a missing or mismatched spec, or an option Clairic rejects (such as `decimals=7` or `scale="log"` with `min=0`) raises `ModelDefinitionError` or `ValueError` naming the problem.
124
+
125
+ Set `reference_date` whenever a field depends on today's date or on dates written without a year:
126
+
127
+ ```python
128
+ clairic.extract(text, InvoiceExtraction, reference_date=date(2026, 9, 2))
129
+ ```
130
+
131
+ ## Reading answers
132
+
133
+ Every answer holds a `value` and the metadata Clairic attaches to it. Your editor completes the attributes, and a type checker knows their types.
134
+
135
+ - **Single values** (`text`, `number`, `date`, `time`, `datetime`, `duration`): `value`, `guess`, `confidence`, `p_null`. `value` is `None` when `p_null` exceeds the field's `null_threshold` (0.5 by default); `guess` still shows the best candidate.
136
+ - **Text**: `span`, end-exclusive offsets into the input: `text[span.start:span.end]`. Text lists carry `spans`.
137
+ - **Number and date lists**: `confidences`, one per item.
138
+ - **Estimates**: `value` (the mean rounded to the `step` grid), `mean`, `median`, `p10`, `p90`, and for number bounds `p_below` and `p_above`, the probability mass outside `[min, max]`.
139
+ - **Forecasts**: per-step lists `value`, `median`, `p10`, `p90`, and `steps` with the full estimate of each step.
140
+
141
+ The p10 to p90 range is an 80% interval. Cloudflare measures its calibration but does not guarantee it, and intervals can be too narrow on unfamiliar data. Use `confidence`, `p_null` and the interval to decide which answers to act on and which to review.
142
+
143
+ ## Plain values
144
+
145
+ `values_as` copies each answer value into the same-named field of a plain Pydantic model, ready for the rest of your program:
146
+
147
+ ```python
148
+ class Invoice(BaseModel):
149
+ invoice_number: str
150
+ total: float
151
+ po_number: str | None
152
+ days_to_pay: int
153
+
154
+
155
+ invoice = result.values_as(Invoice)
156
+ ```
157
+
158
+ Pydantic validates the values, so a `None` landing in a field that does not accept `None` raises `ValidationError`.
159
+
160
+ ## Storing results
161
+
162
+ A `Result` serializes to JSON and back with its answers, token usage and request id:
163
+
164
+ ```python
165
+ stored = result.model_dump_json()
166
+ result = Result[InvoiceExtraction].model_validate_json(stored)
167
+ ```
168
+
169
+ ## Async
170
+
171
+ ```python
172
+ from clairic import AsyncClairic
173
+
174
+ async with AsyncClairic() as clairic:
175
+ result = await clairic.extract(text, InvoiceExtraction)
176
+ ```
177
+
178
+ ## Errors
179
+
180
+ | Exception | When |
181
+ |---|---|
182
+ | `ModelDefinitionError` | The extraction model cannot be sent to Clairic. Raised before any request. |
183
+ | `ClairicConfigurationError` | The account id or token is missing. |
184
+ | `AuthenticationError` | HTTP 401: invalid token or unknown account. |
185
+ | `InvalidRequestError` | HTTP 400 or 422: Cloudflare rejected the request content. |
186
+ | `ContextWindowExceededError` | HTTP 413: the input exceeds the 65,536-token context window. |
187
+ | `APIError` | Any other error response, or answers that do not fit the model. Base class of the API errors. |
188
+ | `APIConnectionError`, `APITimeoutError` | Cloudflare could not be reached, or did not answer within the timeout (30 seconds by default). |
189
+
190
+ API errors carry `status_code`, the Cloudflare error `code`, `message` and `request_id`. When Clairic reports a truncated input, the client emits `ClairicTruncationWarning` and sets `result.truncated`.
191
+
192
+ ## Cost
193
+
194
+ Clairic bills input tokens only ($0.10 per million at the time of writing). Fields that do not fit next to the input in one 8,192-token pass are split across parallel passes, and each pass reads the whole input, so `result.usage.input_tokens` counts the input once per pass.
195
+
196
+ ## Development
197
+
198
+ ```sh
199
+ uv sync
200
+ uv run ruff format --check && uv run ruff check && uv run pyright && uv run pytest
201
+ uv run pytest -m live # real API, needs credentials
202
+ uv run python scripts/check_schema_drift.py # compare Cloudflare's schemas with the vendored ones
203
+ ```
204
+
205
+ `examples/invoice.py` runs the invoice extraction end to end.
206
+
207
+ ## License and attribution
208
+
209
+ MIT. Docstrings adapt text from the Cloudflare documentation, published under CC BY 4.0; see `NOTICE`.
@@ -0,0 +1,160 @@
1
+ # clairic
2
+
3
+ **Unofficial** typed Python SDK for [Cloudflare Clairic](https://developers.cloudflare.com/workers-ai/models/clairic/), the Workers AI extraction model. This project is not affiliated with or endorsed by Cloudflare.
4
+
5
+ Clairic reads a text and returns typed values for the fields you name: extracted, computed, estimated or forecast, each with a confidence score, a probability of absence, or a percentile range. `clairic` lets you declare those fields as a Pydantic model and get the answers back as typed Pydantic objects.
6
+
7
+ ```python
8
+ from typing import Annotated
9
+
10
+ from pydantic import BaseModel, Field
11
+
12
+ from clairic import Clairic, DateAnswer, Estimate, EstimateAnswer, Number, NumberAnswer, TextAnswer
13
+
14
+
15
+ class InvoiceExtraction(BaseModel):
16
+ invoice_number: TextAnswer
17
+ due_date: DateAnswer = Field(description="Issue date plus the net payment days")
18
+ total: Annotated[NumberAnswer[float], Number(decimals=2, unit="USD")] = Field(
19
+ description="Amount due including shipping"
20
+ )
21
+ po_number: TextAnswer = Field(description="Purchase order number")
22
+ days_to_pay: Annotated[EstimateAnswer[int], Estimate(min=0, max=120, step=1)] = Field(
23
+ description="Days after issue until this invoice is paid"
24
+ )
25
+
26
+
27
+ with Clairic() as clairic:
28
+ result = clairic.extract(
29
+ "Invoice INV-2291 from Northwind Supply, issued 2026-09-02, net 30. "
30
+ "4 pallets at $250.00 each, shipping $80.00.",
31
+ InvoiceExtraction,
32
+ )
33
+
34
+ result.data.total.value # 1080.0
35
+ result.data.total.confidence # 0.99995
36
+ result.data.po_number.value # None: the invoice has no PO number
37
+ result.data.days_to_pay.p90 # 37
38
+ ```
39
+
40
+ ## Install
41
+
42
+ ```sh
43
+ pip install clairic
44
+ ```
45
+
46
+ Python 3.10 or later. Dependencies: `httpx` and `pydantic` 2.
47
+
48
+ ## Credentials
49
+
50
+ The client reads `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN`, or takes them as arguments:
51
+
52
+ ```python
53
+ clairic = Clairic(account_id="...", api_token="...")
54
+ ```
55
+
56
+ Create the token in the Cloudflare dashboard with access to Workers AI.
57
+
58
+ ## Declaring fields
59
+
60
+ Each field of the extraction model is an answer type. The answer type sets the Clairic field type; an `Annotated` spec sets its options; `Field(description=...)` gives Clairic the instructions; a Pydantic `alias` sets the field name sent to Clairic.
61
+
62
+ | Answer type | Clairic type | Spec (options) |
63
+ |---|---|---|
64
+ | `TextAnswer` | `text`: a span of the input | `Text(unit, null_threshold)` |
65
+ | `NumberAnswer[float]`, `NumberAnswer[int]` | `number` (`int` requests whole numbers) | `Number(unit, null_threshold, decimals)` |
66
+ | `DateAnswer`, `TimeAnswer`, `DatetimeAnswer` | `date`, `time`, `datetime` | `Date(null_threshold)`, `Time(...)`, `Datetime(...)` |
67
+ | `DurationAnswer[float]`, `DurationAnswer[int]` | `duration` | `Duration(unit, null_threshold, decimals)`, unit defaults to seconds |
68
+ | `TextListAnswer` | `list` of text spans | `List(unit, decimals)` |
69
+ | `ListAnswer[int]`, `ListAnswer[float]`, `ListAnswer[date]` | `list` of numbers or dates | `List(unit, decimals)` |
70
+ | `EstimateAnswer[int]`, `EstimateAnswer[float]` | `estimate` with number bounds | `Estimate(min, max, step, scale, unit)`, required |
71
+ | `DateEstimateAnswer` | `estimate` with date bounds | `Estimate(min=date, max=date, step="month")`, required |
72
+ | `ForecastAnswer` | `forecast` of a series | `Forecast(min, max, horizon, interval, step, scale, unit)`, required |
73
+
74
+ Invalid declarations fail before any request: a non-answer annotation, a missing or mismatched spec, or an option Clairic rejects (such as `decimals=7` or `scale="log"` with `min=0`) raises `ModelDefinitionError` or `ValueError` naming the problem.
75
+
76
+ Set `reference_date` whenever a field depends on today's date or on dates written without a year:
77
+
78
+ ```python
79
+ clairic.extract(text, InvoiceExtraction, reference_date=date(2026, 9, 2))
80
+ ```
81
+
82
+ ## Reading answers
83
+
84
+ Every answer holds a `value` and the metadata Clairic attaches to it. Your editor completes the attributes, and a type checker knows their types.
85
+
86
+ - **Single values** (`text`, `number`, `date`, `time`, `datetime`, `duration`): `value`, `guess`, `confidence`, `p_null`. `value` is `None` when `p_null` exceeds the field's `null_threshold` (0.5 by default); `guess` still shows the best candidate.
87
+ - **Text**: `span`, end-exclusive offsets into the input: `text[span.start:span.end]`. Text lists carry `spans`.
88
+ - **Number and date lists**: `confidences`, one per item.
89
+ - **Estimates**: `value` (the mean rounded to the `step` grid), `mean`, `median`, `p10`, `p90`, and for number bounds `p_below` and `p_above`, the probability mass outside `[min, max]`.
90
+ - **Forecasts**: per-step lists `value`, `median`, `p10`, `p90`, and `steps` with the full estimate of each step.
91
+
92
+ The p10 to p90 range is an 80% interval. Cloudflare measures its calibration but does not guarantee it, and intervals can be too narrow on unfamiliar data. Use `confidence`, `p_null` and the interval to decide which answers to act on and which to review.
93
+
94
+ ## Plain values
95
+
96
+ `values_as` copies each answer value into the same-named field of a plain Pydantic model, ready for the rest of your program:
97
+
98
+ ```python
99
+ class Invoice(BaseModel):
100
+ invoice_number: str
101
+ total: float
102
+ po_number: str | None
103
+ days_to_pay: int
104
+
105
+
106
+ invoice = result.values_as(Invoice)
107
+ ```
108
+
109
+ Pydantic validates the values, so a `None` landing in a field that does not accept `None` raises `ValidationError`.
110
+
111
+ ## Storing results
112
+
113
+ A `Result` serializes to JSON and back with its answers, token usage and request id:
114
+
115
+ ```python
116
+ stored = result.model_dump_json()
117
+ result = Result[InvoiceExtraction].model_validate_json(stored)
118
+ ```
119
+
120
+ ## Async
121
+
122
+ ```python
123
+ from clairic import AsyncClairic
124
+
125
+ async with AsyncClairic() as clairic:
126
+ result = await clairic.extract(text, InvoiceExtraction)
127
+ ```
128
+
129
+ ## Errors
130
+
131
+ | Exception | When |
132
+ |---|---|
133
+ | `ModelDefinitionError` | The extraction model cannot be sent to Clairic. Raised before any request. |
134
+ | `ClairicConfigurationError` | The account id or token is missing. |
135
+ | `AuthenticationError` | HTTP 401: invalid token or unknown account. |
136
+ | `InvalidRequestError` | HTTP 400 or 422: Cloudflare rejected the request content. |
137
+ | `ContextWindowExceededError` | HTTP 413: the input exceeds the 65,536-token context window. |
138
+ | `APIError` | Any other error response, or answers that do not fit the model. Base class of the API errors. |
139
+ | `APIConnectionError`, `APITimeoutError` | Cloudflare could not be reached, or did not answer within the timeout (30 seconds by default). |
140
+
141
+ API errors carry `status_code`, the Cloudflare error `code`, `message` and `request_id`. When Clairic reports a truncated input, the client emits `ClairicTruncationWarning` and sets `result.truncated`.
142
+
143
+ ## Cost
144
+
145
+ Clairic bills input tokens only ($0.10 per million at the time of writing). Fields that do not fit next to the input in one 8,192-token pass are split across parallel passes, and each pass reads the whole input, so `result.usage.input_tokens` counts the input once per pass.
146
+
147
+ ## Development
148
+
149
+ ```sh
150
+ uv sync
151
+ uv run ruff format --check && uv run ruff check && uv run pyright && uv run pytest
152
+ uv run pytest -m live # real API, needs credentials
153
+ uv run python scripts/check_schema_drift.py # compare Cloudflare's schemas with the vendored ones
154
+ ```
155
+
156
+ `examples/invoice.py` runs the invoice extraction end to end.
157
+
158
+ ## License and attribution
159
+
160
+ MIT. Docstrings adapt text from the Cloudflare documentation, published under CC BY 4.0; see `NOTICE`.
@@ -0,0 +1,83 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "clairic"
7
+ dynamic = ["version"]
8
+ description = "Unofficial typed Python SDK for Cloudflare's Clairic extraction model, built on Pydantic."
9
+ readme = "README.md"
10
+ authors = [{ name = "Vianney Mixtur", email = "vianney@consio.ai" }]
11
+ license = { file = "LICENSE" }
12
+ requires-python = ">=3.10"
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
24
+ "Typing :: Typed",
25
+ ]
26
+ dependencies = [
27
+ "httpx>=0.27",
28
+ "pydantic>=2.7",
29
+ "typing-extensions>=4.12",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/VianneyMI/clairic"
34
+ Repository = "https://github.com/VianneyMI/clairic"
35
+ Issues = "https://github.com/VianneyMI/clairic/issues"
36
+ "Clairic model reference" = "https://developers.cloudflare.com/workers-ai/models/clairic/"
37
+
38
+ [dependency-groups]
39
+ dev = [
40
+ "anyio>=4.4",
41
+ "pyright>=1.1.400",
42
+ "pytest>=8.3",
43
+ "python-dotenv>=1.0",
44
+ "ruff>=0.8",
45
+ ]
46
+
47
+ [tool.hatch.version]
48
+ path = "src/clairic/_version.py"
49
+
50
+ [tool.hatch.build.targets.wheel]
51
+ packages = ["src/clairic"]
52
+
53
+ [tool.hatch.build.targets.sdist]
54
+ include = ["/src", "/LICENSE", "/NOTICE", "/README.md", "/pyproject.toml"]
55
+
56
+ [tool.ruff]
57
+ line-length = 100
58
+ target-version = "py310"
59
+
60
+ [tool.ruff.lint]
61
+ select = ["E", "F", "W", "I", "B", "UP", "SIM", "RUF", "D"]
62
+ ignore = [
63
+ "D100", "D104", "D105", "D107", # module, package, magic and __init__ docstrings are optional
64
+ "D203", "D213", # use D211 and D212 (Google style)
65
+ ]
66
+
67
+ [tool.ruff.lint.pydocstyle]
68
+ convention = "google"
69
+
70
+ [tool.ruff.lint.per-file-ignores]
71
+ "tests/**" = ["D"]
72
+ "scripts/**" = ["D"]
73
+ "examples/**" = ["D"]
74
+
75
+ [tool.pyright]
76
+ include = ["src", "tests", "scripts", "examples"]
77
+ pythonVersion = "3.10"
78
+ typeCheckingMode = "strict"
79
+
80
+ [tool.pytest.ini_options]
81
+ testpaths = ["tests", "src"]
82
+ markers = ["live: calls the real Cloudflare API (needs CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN)"]
83
+ addopts = "-m 'not live' --doctest-modules"
@@ -0,0 +1,100 @@
1
+ """Unofficial typed Python SDK for Cloudflare Clairic.
2
+
3
+ Clairic is a Workers AI extraction model: it reads a text and returns typed values for named
4
+ fields, with confidence scores, probabilities of absence and percentile ranges. This package is
5
+ not affiliated with or endorsed by Cloudflare.
6
+
7
+ See https://developers.cloudflare.com/workers-ai/models/clairic/ for the model reference.
8
+ """
9
+
10
+ from clairic._client import AsyncClairic, Clairic
11
+ from clairic._version import __version__
12
+ from clairic.answers import (
13
+ Answer,
14
+ DateAnswer,
15
+ DateEstimateAnswer,
16
+ DatetimeAnswer,
17
+ DurationAnswer,
18
+ DurationUnit,
19
+ EstimateAnswer,
20
+ ForecastAnswer,
21
+ ForecastStep,
22
+ ListAnswer,
23
+ NumberAnswer,
24
+ Span,
25
+ TextAnswer,
26
+ TextListAnswer,
27
+ TimeAnswer,
28
+ )
29
+ from clairic.errors import (
30
+ APIConnectionError,
31
+ APIError,
32
+ APITimeoutError,
33
+ AuthenticationError,
34
+ ClairicConfigurationError,
35
+ ClairicError,
36
+ ClairicTruncationWarning,
37
+ ContextWindowExceededError,
38
+ InvalidRequestError,
39
+ ModelDefinitionError,
40
+ )
41
+ from clairic.result import Result, Usage
42
+ from clairic.specs import (
43
+ Date,
44
+ Datetime,
45
+ Duration,
46
+ Estimate,
47
+ Forecast,
48
+ Interval,
49
+ List,
50
+ Number,
51
+ Scale,
52
+ Spec,
53
+ Text,
54
+ Time,
55
+ )
56
+
57
+ __all__ = [
58
+ "APIConnectionError",
59
+ "APIError",
60
+ "APITimeoutError",
61
+ "Answer",
62
+ "AsyncClairic",
63
+ "AuthenticationError",
64
+ "Clairic",
65
+ "ClairicConfigurationError",
66
+ "ClairicError",
67
+ "ClairicTruncationWarning",
68
+ "ContextWindowExceededError",
69
+ "Date",
70
+ "DateAnswer",
71
+ "DateEstimateAnswer",
72
+ "Datetime",
73
+ "DatetimeAnswer",
74
+ "Duration",
75
+ "DurationAnswer",
76
+ "DurationUnit",
77
+ "Estimate",
78
+ "EstimateAnswer",
79
+ "Forecast",
80
+ "ForecastAnswer",
81
+ "ForecastStep",
82
+ "Interval",
83
+ "InvalidRequestError",
84
+ "List",
85
+ "ListAnswer",
86
+ "ModelDefinitionError",
87
+ "Number",
88
+ "NumberAnswer",
89
+ "Result",
90
+ "Scale",
91
+ "Span",
92
+ "Spec",
93
+ "Text",
94
+ "TextAnswer",
95
+ "TextListAnswer",
96
+ "Time",
97
+ "TimeAnswer",
98
+ "Usage",
99
+ "__version__",
100
+ ]