snipget-client 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,34 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+
22
+ - name: Install
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ pip install -e ".[dev]"
26
+
27
+ - name: Lint
28
+ run: ruff check src/ tests/
29
+
30
+ - name: Format check
31
+ run: ruff format --check src/ tests/
32
+
33
+ - name: Test
34
+ run: pytest -q
@@ -0,0 +1,62 @@
1
+ # Publish snipget-client to PyPI via Trusted Publishing (OIDC).
2
+ #
3
+ # No API tokens anywhere: PyPI's trusted-publisher config for the
4
+ # `snipget-client` project trusts exactly this repo + workflow file +
5
+ # the `pypi` environment. Releasing is one step: publish a GitHub
6
+ # Release tagged `vX.Y.Z` (matching pyproject.toml's version — the
7
+ # guard below fails the run on a mismatch).
8
+
9
+ name: Publish to PyPI
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ jobs:
16
+ build:
17
+ name: Build distribution
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v5
21
+
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.13"
25
+
26
+ - name: Verify release tag matches package version
27
+ run: |
28
+ PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
29
+ TAG="${GITHUB_REF_NAME#v}"
30
+ if [ "$PKG_VERSION" != "$TAG" ]; then
31
+ echo "::error::Release tag v$TAG does not match pyproject.toml version $PKG_VERSION"
32
+ exit 1
33
+ fi
34
+
35
+ - name: Build sdist + wheel
36
+ run: |
37
+ python -m pip install --upgrade build
38
+ python -m build
39
+
40
+ - uses: actions/upload-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ publish:
46
+ name: Publish to PyPI
47
+ needs: build
48
+ runs-on: ubuntu-latest
49
+ environment:
50
+ name: pypi
51
+ url: https://pypi.org/project/snipget-client/
52
+ permissions:
53
+ # Required for PyPI Trusted Publishing — mints the OIDC token the
54
+ # pypa publish action exchanges for a short-lived PyPI credential.
55
+ id-token: write
56
+ steps:
57
+ - uses: actions/download-artifact@v4
58
+ with:
59
+ name: dist
60
+ path: dist/
61
+
62
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,38 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ .eggs/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # Test / lint caches
18
+ .pytest_cache/
19
+ .ruff_cache/
20
+ .coverage
21
+ htmlcov/
22
+ .tox/
23
+
24
+ # Type checker caches
25
+ .mypy_cache/
26
+ .pyre/
27
+
28
+ # Editors / IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
36
+
37
+ # Local env files
38
+ .env
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright 2026 Snipget Inc.
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.
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: snipget-client
3
+ Version: 0.1.0
4
+ Summary: Official Python client for the Snipget API: data normalization, parsing, validation, and classification utilities for AI agents.
5
+ Project-URL: Homepage, https://snipget.ai
6
+ Project-URL: Documentation, https://api.snipget.ai/docs
7
+ Project-URL: Repository, https://github.com/snipget/snipget-python
8
+ Author-email: "Snipget Inc." <hello@snipget.ai>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent-tools,ai-agents,api,data-normalization,data-validation,healthcare,llm,mcp,npi,parsing
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: httpx<1,>=0.24.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.8; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # snipget-client
30
+
31
+ The official Python client for [Snipget](https://snipget.ai), the hosted utility API for AI agents: data normalization, parsing, validation, and classification over plain HTTPS.
32
+
33
+ ## What is Snipget
34
+
35
+ Snipget is a hosted, pay-per-call utility API built for AI agents and the developers who build them. It serves 130+ programmatic endpoints for data normalization, parsing, validation, and classification, with particular depth in healthcare data: NPI validation and lookup, DEA numbers, provider taxonomy, credentials, and certifications. Every endpoint is deterministic (no LLM calls inside the API), returns a confidence score, and ships in single-record and batch variants.
36
+
37
+ Snipget is agent-native by design. Agents can discover and call it through the [OpenAPI spec](https://api.snipget.ai/openapi.json) or the MCP server, and every response uses one consistent JSON envelope so a single integration covers the whole catalog. This package is a thin HTTP wrapper around that hosted API; all the actual logic runs server-side, and the [interactive docs](https://api.snipget.ai/docs) are the per-endpoint contract.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ pip install snipget-client
43
+ ```
44
+
45
+ Requires Python 3.10+. The only dependency is [httpx](https://www.python-httpx.org/).
46
+
47
+ ## Quickstart
48
+
49
+ You need an API key from [snipget.ai](https://snipget.ai). One generic `call()` method reaches every endpoint; pass the path and the JSON payload from the [API docs](https://api.snipget.ai/docs).
50
+
51
+ ```python
52
+ from snipget import Client
53
+
54
+ client = Client(api_key="YOUR_API_KEY") # or set SNIPGET_API_KEY
55
+
56
+ resp = client.call("/healthcare/npi/validate", {"npi": "1234567893"})
57
+
58
+ print(resp.result)
59
+ # {'npi': 1234567893, 'is_valid': True, 'checksum_valid': True, 'input_was_clean': True}
60
+ print(resp.confidence) # 1.0
61
+ print(resp.meta.cost_units) # 1
62
+ print(resp.meta.request_id) # 'req_...'
63
+
64
+ # Batch variants exist for every utility:
65
+ resp = client.call(
66
+ "/healthcare/npi/validate/batch",
67
+ {"items": ["1234567893", "1234567890"]},
68
+ )
69
+ print(resp.result["summary"]) # {'total': 2, 'valid': 1, 'invalid': 1}
70
+ ```
71
+
72
+ Async, same surface:
73
+
74
+ ```python
75
+ import asyncio
76
+ from snipget import AsyncClient
77
+
78
+ async def main():
79
+ async with AsyncClient() as client: # reads SNIPGET_API_KEY
80
+ resp = await client.call(
81
+ "/common/phone/validate",
82
+ {"value": "(415) 555-0132", "country_hint": "US"},
83
+ )
84
+ print(resp.result)
85
+
86
+ asyncio.run(main())
87
+ ```
88
+
89
+ `call()` defaults to `POST` when a payload is given and `GET` otherwise, which matches every endpoint in the spec; pass `method=` to override.
90
+
91
+ ## Authentication
92
+
93
+ Get an API key at [snipget.ai](https://snipget.ai). The client resolves the key in this order:
94
+
95
+ 1. `Client(api_key="...")`
96
+ 2. The `SNIPGET_API_KEY` environment variable
97
+
98
+ By default the key is sent as `Authorization: Bearer <key>`. The API also accepts an `X-API-Key` header; opt in with `Client(auth_header="x-api-key")`.
99
+
100
+ ## Error handling
101
+
102
+ Every API error is raised as a typed exception. All of them subclass `SnipgetError` and carry `error_code`, `message`, `request_id`, `http_status`, and the full parsed envelope as `body`.
103
+
104
+ ```python
105
+ import snipget
106
+
107
+ client = snipget.Client()
108
+
109
+ try:
110
+ resp = client.call("/healthcare/npi/validate", {"npi": "1234567893"})
111
+ except snipget.AuthenticationError as e:
112
+ print("Check your API key:", e.error_code) # 401/403
113
+ except snipget.InvalidRequestError as e:
114
+ print("Bad request:", e.body.get("details")) # 400/422
115
+ except snipget.RateLimitError as e:
116
+ print("Throttled; retry in", e.retry_after, "seconds") # 429 RATE_LIMITED
117
+ except snipget.QuotaExceededError as e:
118
+ print("Out of monthly capacity:", e.body.get("limit_type"))
119
+ print("Allowance left (USD):", e.credit_remaining_usd) # 429 QUOTA_EXCEEDED
120
+ except snipget.MaintenanceError as e:
121
+ print("Maintenance window; retry in", e.retry_after) # 503 MAINTENANCE_MODE
122
+ except snipget.APIError as e:
123
+ print("Server error; quote this id to support:", e.request_id)
124
+ ```
125
+
126
+ The two 429s mean different things: `RateLimitError` is a per-second throughput throttle and clears in seconds; `QuotaExceededError` means the monthly included calls or prepaid overage allowance are exhausted and will not clear until the monthly reset, a tier upgrade, or an allowance top-up. The client retries the first automatically and never retries the second.
127
+
128
+ ## Retries and timeouts
129
+
130
+ ```python
131
+ client = Client(
132
+ api_key="...",
133
+ timeout=30.0, # per-request timeout in seconds
134
+ max_retries=2, # retries on top of the initial attempt
135
+ )
136
+ ```
137
+
138
+ The client automatically retries network errors, `RATE_LIMITED` 429s (honoring the server's `Retry-After`), and 5xx responses, using exponential backoff with jitter. Snipget utility calls are pure and idempotent, so retrying a POST is safe. It never retries `QUOTA_EXCEEDED` or any other 4xx. Maintenance 503s are retried on the short backoff only; if the window outlasts the retry budget you get a `MaintenanceError` with `retry_after` (typically 300 seconds) so you can schedule your own retry.
139
+
140
+ ## The response envelope
141
+
142
+ Every Snipget endpoint, success or error, returns one envelope shape. `call()` returns a `SnipgetResponse`:
143
+
144
+ | Attribute | Type | Meaning |
145
+ | --- | --- | --- |
146
+ | `result` | endpoint-specific | The payload, exactly as the API returned it |
147
+ | `confidence` | `float` | 0.0-1.0 confidence score (1.0 = deterministic match; batch responses always report 1.0 at the top level, with per-item confidences inside `result.items`) |
148
+ | `status` | `str` | `"ok"` on success |
149
+ | `meta.cost_units` | `int` | Billable units consumed by this call |
150
+ | `meta.request_id` | `str` | Server request id; quote it to support |
151
+ | `meta.elapsed_ms` | `int` | Server-side processing time |
152
+ | `meta.version` | `str` | API version |
153
+ | `meta.rate_limit_remaining` / `meta.rate_limit_reset` | `int` | Throughput headroom and bucket reset (unix time) |
154
+ | `meta.quota_remaining` / `meta.quota_reset` | `int` | Monthly included-call headroom and reset (unix time) |
155
+ | `meta.credit_remaining_usd` | `float` | Live prepaid-allowance balance, populated once a call starts burning allowance |
156
+ | `meta.trace` | `list[str]` | Reasoning trace, when the request set `include_trace: true` |
157
+ | `raw` | `dict` | The full unmodified envelope |
158
+
159
+ Meta fields the server didn't send are `None`; unknown future fields stay available via `meta.raw`.
160
+
161
+ ## Links
162
+
163
+ - Website: [https://snipget.ai](https://snipget.ai)
164
+ - Interactive API docs: [https://api.snipget.ai/docs](https://api.snipget.ai/docs)
165
+ - OpenAPI spec: [https://api.snipget.ai/openapi.json](https://api.snipget.ai/openapi.json)
166
+ - npm sibling: a JavaScript/TypeScript client (`snipget` on npm) is planned but not yet published
167
+
168
+ ## License
169
+
170
+ MIT. Copyright 2026 Snipget Inc.
@@ -0,0 +1,142 @@
1
+ # snipget-client
2
+
3
+ The official Python client for [Snipget](https://snipget.ai), the hosted utility API for AI agents: data normalization, parsing, validation, and classification over plain HTTPS.
4
+
5
+ ## What is Snipget
6
+
7
+ Snipget is a hosted, pay-per-call utility API built for AI agents and the developers who build them. It serves 130+ programmatic endpoints for data normalization, parsing, validation, and classification, with particular depth in healthcare data: NPI validation and lookup, DEA numbers, provider taxonomy, credentials, and certifications. Every endpoint is deterministic (no LLM calls inside the API), returns a confidence score, and ships in single-record and batch variants.
8
+
9
+ Snipget is agent-native by design. Agents can discover and call it through the [OpenAPI spec](https://api.snipget.ai/openapi.json) or the MCP server, and every response uses one consistent JSON envelope so a single integration covers the whole catalog. This package is a thin HTTP wrapper around that hosted API; all the actual logic runs server-side, and the [interactive docs](https://api.snipget.ai/docs) are the per-endpoint contract.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install snipget-client
15
+ ```
16
+
17
+ Requires Python 3.10+. The only dependency is [httpx](https://www.python-httpx.org/).
18
+
19
+ ## Quickstart
20
+
21
+ You need an API key from [snipget.ai](https://snipget.ai). One generic `call()` method reaches every endpoint; pass the path and the JSON payload from the [API docs](https://api.snipget.ai/docs).
22
+
23
+ ```python
24
+ from snipget import Client
25
+
26
+ client = Client(api_key="YOUR_API_KEY") # or set SNIPGET_API_KEY
27
+
28
+ resp = client.call("/healthcare/npi/validate", {"npi": "1234567893"})
29
+
30
+ print(resp.result)
31
+ # {'npi': 1234567893, 'is_valid': True, 'checksum_valid': True, 'input_was_clean': True}
32
+ print(resp.confidence) # 1.0
33
+ print(resp.meta.cost_units) # 1
34
+ print(resp.meta.request_id) # 'req_...'
35
+
36
+ # Batch variants exist for every utility:
37
+ resp = client.call(
38
+ "/healthcare/npi/validate/batch",
39
+ {"items": ["1234567893", "1234567890"]},
40
+ )
41
+ print(resp.result["summary"]) # {'total': 2, 'valid': 1, 'invalid': 1}
42
+ ```
43
+
44
+ Async, same surface:
45
+
46
+ ```python
47
+ import asyncio
48
+ from snipget import AsyncClient
49
+
50
+ async def main():
51
+ async with AsyncClient() as client: # reads SNIPGET_API_KEY
52
+ resp = await client.call(
53
+ "/common/phone/validate",
54
+ {"value": "(415) 555-0132", "country_hint": "US"},
55
+ )
56
+ print(resp.result)
57
+
58
+ asyncio.run(main())
59
+ ```
60
+
61
+ `call()` defaults to `POST` when a payload is given and `GET` otherwise, which matches every endpoint in the spec; pass `method=` to override.
62
+
63
+ ## Authentication
64
+
65
+ Get an API key at [snipget.ai](https://snipget.ai). The client resolves the key in this order:
66
+
67
+ 1. `Client(api_key="...")`
68
+ 2. The `SNIPGET_API_KEY` environment variable
69
+
70
+ By default the key is sent as `Authorization: Bearer <key>`. The API also accepts an `X-API-Key` header; opt in with `Client(auth_header="x-api-key")`.
71
+
72
+ ## Error handling
73
+
74
+ Every API error is raised as a typed exception. All of them subclass `SnipgetError` and carry `error_code`, `message`, `request_id`, `http_status`, and the full parsed envelope as `body`.
75
+
76
+ ```python
77
+ import snipget
78
+
79
+ client = snipget.Client()
80
+
81
+ try:
82
+ resp = client.call("/healthcare/npi/validate", {"npi": "1234567893"})
83
+ except snipget.AuthenticationError as e:
84
+ print("Check your API key:", e.error_code) # 401/403
85
+ except snipget.InvalidRequestError as e:
86
+ print("Bad request:", e.body.get("details")) # 400/422
87
+ except snipget.RateLimitError as e:
88
+ print("Throttled; retry in", e.retry_after, "seconds") # 429 RATE_LIMITED
89
+ except snipget.QuotaExceededError as e:
90
+ print("Out of monthly capacity:", e.body.get("limit_type"))
91
+ print("Allowance left (USD):", e.credit_remaining_usd) # 429 QUOTA_EXCEEDED
92
+ except snipget.MaintenanceError as e:
93
+ print("Maintenance window; retry in", e.retry_after) # 503 MAINTENANCE_MODE
94
+ except snipget.APIError as e:
95
+ print("Server error; quote this id to support:", e.request_id)
96
+ ```
97
+
98
+ The two 429s mean different things: `RateLimitError` is a per-second throughput throttle and clears in seconds; `QuotaExceededError` means the monthly included calls or prepaid overage allowance are exhausted and will not clear until the monthly reset, a tier upgrade, or an allowance top-up. The client retries the first automatically and never retries the second.
99
+
100
+ ## Retries and timeouts
101
+
102
+ ```python
103
+ client = Client(
104
+ api_key="...",
105
+ timeout=30.0, # per-request timeout in seconds
106
+ max_retries=2, # retries on top of the initial attempt
107
+ )
108
+ ```
109
+
110
+ The client automatically retries network errors, `RATE_LIMITED` 429s (honoring the server's `Retry-After`), and 5xx responses, using exponential backoff with jitter. Snipget utility calls are pure and idempotent, so retrying a POST is safe. It never retries `QUOTA_EXCEEDED` or any other 4xx. Maintenance 503s are retried on the short backoff only; if the window outlasts the retry budget you get a `MaintenanceError` with `retry_after` (typically 300 seconds) so you can schedule your own retry.
111
+
112
+ ## The response envelope
113
+
114
+ Every Snipget endpoint, success or error, returns one envelope shape. `call()` returns a `SnipgetResponse`:
115
+
116
+ | Attribute | Type | Meaning |
117
+ | --- | --- | --- |
118
+ | `result` | endpoint-specific | The payload, exactly as the API returned it |
119
+ | `confidence` | `float` | 0.0-1.0 confidence score (1.0 = deterministic match; batch responses always report 1.0 at the top level, with per-item confidences inside `result.items`) |
120
+ | `status` | `str` | `"ok"` on success |
121
+ | `meta.cost_units` | `int` | Billable units consumed by this call |
122
+ | `meta.request_id` | `str` | Server request id; quote it to support |
123
+ | `meta.elapsed_ms` | `int` | Server-side processing time |
124
+ | `meta.version` | `str` | API version |
125
+ | `meta.rate_limit_remaining` / `meta.rate_limit_reset` | `int` | Throughput headroom and bucket reset (unix time) |
126
+ | `meta.quota_remaining` / `meta.quota_reset` | `int` | Monthly included-call headroom and reset (unix time) |
127
+ | `meta.credit_remaining_usd` | `float` | Live prepaid-allowance balance, populated once a call starts burning allowance |
128
+ | `meta.trace` | `list[str]` | Reasoning trace, when the request set `include_trace: true` |
129
+ | `raw` | `dict` | The full unmodified envelope |
130
+
131
+ Meta fields the server didn't send are `None`; unknown future fields stay available via `meta.raw`.
132
+
133
+ ## Links
134
+
135
+ - Website: [https://snipget.ai](https://snipget.ai)
136
+ - Interactive API docs: [https://api.snipget.ai/docs](https://api.snipget.ai/docs)
137
+ - OpenAPI spec: [https://api.snipget.ai/openapi.json](https://api.snipget.ai/openapi.json)
138
+ - npm sibling: a JavaScript/TypeScript client (`snipget` on npm) is planned but not yet published
139
+
140
+ ## License
141
+
142
+ MIT. Copyright 2026 Snipget Inc.
@@ -0,0 +1,59 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.26"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "snipget-client"
7
+ version = "0.1.0"
8
+ description = "Official Python client for the Snipget API: data normalization, parsing, validation, and classification utilities for AI agents."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [{ name = "Snipget Inc.", email = "hello@snipget.ai" }]
14
+ keywords = [
15
+ "api",
16
+ "ai-agents",
17
+ "llm",
18
+ "data-normalization",
19
+ "data-validation",
20
+ "parsing",
21
+ "healthcare",
22
+ "npi",
23
+ "mcp",
24
+ "agent-tools",
25
+ ]
26
+ classifiers = [
27
+ "Development Status :: 4 - Beta",
28
+ "Intended Audience :: Developers",
29
+ "Operating System :: OS Independent",
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.10",
32
+ "Programming Language :: Python :: 3.11",
33
+ "Programming Language :: Python :: 3.12",
34
+ "Programming Language :: Python :: 3.13",
35
+ "Topic :: Software Development :: Libraries :: Python Modules",
36
+ "Typing :: Typed",
37
+ ]
38
+ dependencies = ["httpx>=0.24.0,<1"]
39
+
40
+ [project.urls]
41
+ Homepage = "https://snipget.ai"
42
+ Documentation = "https://api.snipget.ai/docs"
43
+ Repository = "https://github.com/snipget/snipget-python"
44
+
45
+ [project.optional-dependencies]
46
+ dev = ["pytest>=8.0", "ruff>=0.8"]
47
+
48
+ [tool.hatch.build.targets.wheel]
49
+ packages = ["src/snipget"]
50
+
51
+ [tool.pytest.ini_options]
52
+ testpaths = ["tests"]
53
+
54
+ [tool.ruff]
55
+ line-length = 100
56
+ target-version = "py310"
57
+
58
+ [tool.ruff.lint]
59
+ select = ["E", "F", "W", "I", "UP", "B"]
@@ -0,0 +1,41 @@
1
+ """Official Python client for the Snipget API.
2
+
3
+ Snipget is a hosted utility API for AI agents and developers: data
4
+ normalization, parsing, validation, and classification. This package is a
5
+ thin HTTP wrapper around it — the per-endpoint contract lives in the
6
+ OpenAPI spec at https://api.snipget.ai/openapi.json.
7
+
8
+ from snipget import Client
9
+
10
+ client = Client(api_key="...") # or set SNIPGET_API_KEY
11
+ resp = client.call("/healthcare/npi/validate", {"npi": "1234567893"})
12
+ print(resp.result, resp.confidence, resp.meta.request_id)
13
+ """
14
+
15
+ from snipget._client import AsyncClient, Client
16
+ from snipget._exceptions import (
17
+ APIError,
18
+ AuthenticationError,
19
+ InvalidRequestError,
20
+ MaintenanceError,
21
+ QuotaExceededError,
22
+ RateLimitError,
23
+ SnipgetError,
24
+ )
25
+ from snipget._response import ResponseMeta, SnipgetResponse
26
+ from snipget._version import __version__
27
+
28
+ __all__ = [
29
+ "APIError",
30
+ "AsyncClient",
31
+ "AuthenticationError",
32
+ "Client",
33
+ "InvalidRequestError",
34
+ "MaintenanceError",
35
+ "QuotaExceededError",
36
+ "RateLimitError",
37
+ "ResponseMeta",
38
+ "SnipgetError",
39
+ "SnipgetResponse",
40
+ "__version__",
41
+ ]