nopaque 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.
Files changed (71) hide show
  1. nopaque-0.1.0/.github/workflows/ci.yml +31 -0
  2. nopaque-0.1.0/.github/workflows/nightly-integration.yml +22 -0
  3. nopaque-0.1.0/.github/workflows/release.yml +48 -0
  4. nopaque-0.1.0/.gitignore +15 -0
  5. nopaque-0.1.0/CHANGELOG.md +23 -0
  6. nopaque-0.1.0/LICENSE +21 -0
  7. nopaque-0.1.0/PKG-INFO +134 -0
  8. nopaque-0.1.0/README.md +88 -0
  9. nopaque-0.1.0/examples/async_example.py +27 -0
  10. nopaque-0.1.0/examples/audio_upload.py +18 -0
  11. nopaque-0.1.0/examples/mapping_and_wait.py +33 -0
  12. nopaque-0.1.0/examples/quickstart.py +11 -0
  13. nopaque-0.1.0/pyproject.toml +87 -0
  14. nopaque-0.1.0/src/nopaque/__init__.py +115 -0
  15. nopaque-0.1.0/src/nopaque/_client.py +107 -0
  16. nopaque-0.1.0/src/nopaque/_config.py +42 -0
  17. nopaque-0.1.0/src/nopaque/_errors.py +122 -0
  18. nopaque-0.1.0/src/nopaque/_pagination.py +100 -0
  19. nopaque-0.1.0/src/nopaque/_polling.py +106 -0
  20. nopaque-0.1.0/src/nopaque/_request_options.py +30 -0
  21. nopaque-0.1.0/src/nopaque/_resource.py +19 -0
  22. nopaque-0.1.0/src/nopaque/_retry.py +93 -0
  23. nopaque-0.1.0/src/nopaque/_s3.py +94 -0
  24. nopaque-0.1.0/src/nopaque/_transport.py +253 -0
  25. nopaque-0.1.0/src/nopaque/_user_agent.py +20 -0
  26. nopaque-0.1.0/src/nopaque/_version.py +1 -0
  27. nopaque-0.1.0/src/nopaque/models/__init__.py +90 -0
  28. nopaque-0.1.0/src/nopaque/models/audio.py +67 -0
  29. nopaque-0.1.0/src/nopaque/models/batches.py +52 -0
  30. nopaque-0.1.0/src/nopaque/models/datasets.py +44 -0
  31. nopaque-0.1.0/src/nopaque/models/enrichment.py +57 -0
  32. nopaque-0.1.0/src/nopaque/models/load_testing.py +76 -0
  33. nopaque-0.1.0/src/nopaque/models/mapping.py +208 -0
  34. nopaque-0.1.0/src/nopaque/models/profiles.py +46 -0
  35. nopaque-0.1.0/src/nopaque/models/scheduler.py +42 -0
  36. nopaque-0.1.0/src/nopaque/models/sweeps.py +52 -0
  37. nopaque-0.1.0/src/nopaque/models/testing.py +55 -0
  38. nopaque-0.1.0/src/nopaque/resources/__init__.py +0 -0
  39. nopaque-0.1.0/src/nopaque/resources/audio.py +274 -0
  40. nopaque-0.1.0/src/nopaque/resources/batches.py +360 -0
  41. nopaque-0.1.0/src/nopaque/resources/datasets.py +209 -0
  42. nopaque-0.1.0/src/nopaque/resources/enrichment.py +101 -0
  43. nopaque-0.1.0/src/nopaque/resources/load_testing.py +413 -0
  44. nopaque-0.1.0/src/nopaque/resources/mapping.py +637 -0
  45. nopaque-0.1.0/src/nopaque/resources/profiles.py +335 -0
  46. nopaque-0.1.0/src/nopaque/resources/scheduler.py +247 -0
  47. nopaque-0.1.0/src/nopaque/resources/sweeps.py +361 -0
  48. nopaque-0.1.0/src/nopaque/resources/testing.py +552 -0
  49. nopaque-0.1.0/tests/__init__.py +0 -0
  50. nopaque-0.1.0/tests/conftest.py +1 -0
  51. nopaque-0.1.0/tests/integration/__init__.py +0 -0
  52. nopaque-0.1.0/tests/integration/test_smoke.py +59 -0
  53. nopaque-0.1.0/tests/resources/__init__.py +0 -0
  54. nopaque-0.1.0/tests/resources/test_audio.py +210 -0
  55. nopaque-0.1.0/tests/resources/test_batches.py +121 -0
  56. nopaque-0.1.0/tests/resources/test_datasets.py +81 -0
  57. nopaque-0.1.0/tests/resources/test_enrichment.py +58 -0
  58. nopaque-0.1.0/tests/resources/test_load_testing.py +139 -0
  59. nopaque-0.1.0/tests/resources/test_mapping.py +248 -0
  60. nopaque-0.1.0/tests/resources/test_profiles.py +137 -0
  61. nopaque-0.1.0/tests/resources/test_scheduler.py +88 -0
  62. nopaque-0.1.0/tests/resources/test_sweeps.py +121 -0
  63. nopaque-0.1.0/tests/resources/test_testing.py +163 -0
  64. nopaque-0.1.0/tests/test_client.py +40 -0
  65. nopaque-0.1.0/tests/test_config.py +51 -0
  66. nopaque-0.1.0/tests/test_errors.py +82 -0
  67. nopaque-0.1.0/tests/test_pagination.py +68 -0
  68. nopaque-0.1.0/tests/test_polling.py +91 -0
  69. nopaque-0.1.0/tests/test_retry.py +103 -0
  70. nopaque-0.1.0/tests/test_transport.py +194 -0
  71. nopaque-0.1.0/tests/test_user_agent.py +18 -0
@@ -0,0 +1,31 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ cache: pip
22
+ - name: Install hatch and build
23
+ run: pip install hatch build
24
+ - name: Lint
25
+ run: hatch run lint
26
+ - name: Type check
27
+ run: hatch run type
28
+ - name: Test
29
+ run: hatch run test
30
+ - name: Build distributions
31
+ run: python -m build
@@ -0,0 +1,22 @@
1
+ name: Nightly Integration
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "0 6 * * *" # 06:00 UTC daily
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ integration:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.12"
16
+ cache: pip
17
+ - run: pip install hatch
18
+ - name: Run integration suite
19
+ env:
20
+ NOPAQUE_API_KEY: ${{ secrets.NOPAQUE_DEV_API_KEY }}
21
+ NOPAQUE_BASE_URL: https://api.dev.nopaque.co.uk
22
+ run: hatch run test:integration -v
@@ -0,0 +1,48 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write # required for PyPI OIDC trusted publishing
13
+ contents: write # required to create GitHub Release
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+ cache: pip
22
+
23
+ - name: Install hatch and build
24
+ run: pip install hatch build
25
+
26
+ - name: Verify tag matches package version
27
+ run: |
28
+ TAG="${GITHUB_REF#refs/tags/v}"
29
+ VERSION=$(python -c "import re, pathlib; m=re.search(r'__version__ = \"(.*)\"', pathlib.Path('src/nopaque/_version.py').read_text()); print(m.group(1))")
30
+ if [ "$TAG" != "$VERSION" ]; then
31
+ echo "Tag $TAG does not match package version $VERSION"
32
+ exit 1
33
+ fi
34
+
35
+ - name: Run tests
36
+ run: hatch run test
37
+
38
+ - name: Build distributions
39
+ run: python -m build
40
+
41
+ - name: Publish to PyPI (trusted publishing)
42
+ uses: pypa/gh-action-pypi-publish@release/v1
43
+
44
+ - name: Create GitHub Release
45
+ uses: softprops/action-gh-release@v2
46
+ with:
47
+ generate_release_notes: true
48
+ files: dist/*
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ .hatch/
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ .coverage
12
+ htmlcov/
13
+ .venv/
14
+ venv/
15
+ .env
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-04-19
10
+
11
+ ### Added
12
+ - Initial release.
13
+ - Synchronous (`Nopaque`) and asynchronous (`AsyncNopaque`) clients.
14
+ - Full coverage of the API-key-authenticated Nopaque REST API:
15
+ mapping, profiles, testing (configs/jobs/runs), batches, sweeps,
16
+ datasets, load testing, scheduler, enrichment, audio.
17
+ - Automatic pagination, polling helpers for long-running jobs,
18
+ one-call audio upload/download.
19
+ - Method-aware retry with exponential jitter and `Retry-After` honor.
20
+ - Typed exception hierarchy.
21
+
22
+ [Unreleased]: https://github.com/nopaque/python-sdk/compare/v0.1.0...HEAD
23
+ [0.1.0]: https://github.com/nopaque/python-sdk/releases/tag/v0.1.0
nopaque-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nopaque Ltd
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.
nopaque-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: nopaque
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the Nopaque API
5
+ Project-URL: Homepage, https://nopaque.co.uk
6
+ Project-URL: Documentation, https://nopaque.co.uk/docs/sdks
7
+ Project-URL: Repository, https://github.com/nopaque/python-sdk
8
+ Project-URL: Issues, https://github.com/nopaque/python-sdk/issues
9
+ Author-email: Nopaque <support@nopaque.co.uk>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Nopaque Ltd
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
+ Keywords: api,ivr,nopaque,sdk
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.9
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Typing :: Typed
42
+ Requires-Python: >=3.9
43
+ Requires-Dist: httpx>=0.27
44
+ Requires-Dist: pydantic>=2.6
45
+ Description-Content-Type: text/markdown
46
+
47
+ # nopaque - Python SDK for Nopaque
48
+
49
+ Official Python client for the [Nopaque](https://nopaque.co.uk) API.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install nopaque
55
+ ```
56
+
57
+ ## Quick start
58
+
59
+ ```python
60
+ from nopaque import Nopaque
61
+
62
+ client = Nopaque(api_key="nop_live_...") # or set NOPAQUE_API_KEY
63
+
64
+ # Create a mapping job and wait for it to complete
65
+ job = client.mapping.create(
66
+ name="Main IVR",
67
+ phone_number="+441234567890",
68
+ mapping_mode="dtmf",
69
+ )
70
+ client.mapping.start(job.id)
71
+ final = client.mapping.wait_for_complete(job.id)
72
+ print(final.status)
73
+
74
+ # List audio files with automatic pagination
75
+ for audio in client.audio.list():
76
+ print(audio.id, audio.file_name)
77
+
78
+ client.close()
79
+ ```
80
+
81
+ ## Async
82
+
83
+ ```python
84
+ import asyncio
85
+ from nopaque import AsyncNopaque
86
+
87
+ async def main():
88
+ async with AsyncNopaque() as client:
89
+ job = await client.mapping.get("map_abc123")
90
+ print(job.status)
91
+
92
+ asyncio.run(main())
93
+ ```
94
+
95
+ ## Features
96
+
97
+ - Full coverage of the Nopaque REST API via API-key auth
98
+ - Typed Pydantic v2 models for every request and response
99
+ - Paired sync (`Nopaque`) and async (`AsyncNopaque`) clients
100
+ - Automatic pagination for list endpoints
101
+ - Polling helpers for long-running jobs (`wait_for_complete`)
102
+ - One-call audio upload/download wrapping the presigned-URL flow
103
+ - Method-aware retry with exponential jitter and `Retry-After` honor
104
+ - Typed exception hierarchy (`NotFoundError`, `RateLimitError`, etc.)
105
+
106
+ ## Documentation
107
+
108
+ Full reference: <https://nopaque.co.uk/docs/sdks>
109
+
110
+ ## Authentication
111
+
112
+ Pass your API key to the client:
113
+
114
+ ```python
115
+ Nopaque(api_key="nop_live_...")
116
+ ```
117
+
118
+ Or set the environment variable:
119
+
120
+ ```bash
121
+ export NOPAQUE_API_KEY=nop_live_...
122
+ ```
123
+
124
+ API keys are workspace-scoped and subject to per-minute rate limits based on
125
+ your subscription tier. Free tier cannot use API keys.
126
+
127
+ ## Requirements
128
+
129
+ - Python 3.9+
130
+ - `httpx >= 0.27`, `pydantic >= 2.6`
131
+
132
+ ## License
133
+
134
+ MIT
@@ -0,0 +1,88 @@
1
+ # nopaque - Python SDK for Nopaque
2
+
3
+ Official Python client for the [Nopaque](https://nopaque.co.uk) API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install nopaque
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```python
14
+ from nopaque import Nopaque
15
+
16
+ client = Nopaque(api_key="nop_live_...") # or set NOPAQUE_API_KEY
17
+
18
+ # Create a mapping job and wait for it to complete
19
+ job = client.mapping.create(
20
+ name="Main IVR",
21
+ phone_number="+441234567890",
22
+ mapping_mode="dtmf",
23
+ )
24
+ client.mapping.start(job.id)
25
+ final = client.mapping.wait_for_complete(job.id)
26
+ print(final.status)
27
+
28
+ # List audio files with automatic pagination
29
+ for audio in client.audio.list():
30
+ print(audio.id, audio.file_name)
31
+
32
+ client.close()
33
+ ```
34
+
35
+ ## Async
36
+
37
+ ```python
38
+ import asyncio
39
+ from nopaque import AsyncNopaque
40
+
41
+ async def main():
42
+ async with AsyncNopaque() as client:
43
+ job = await client.mapping.get("map_abc123")
44
+ print(job.status)
45
+
46
+ asyncio.run(main())
47
+ ```
48
+
49
+ ## Features
50
+
51
+ - Full coverage of the Nopaque REST API via API-key auth
52
+ - Typed Pydantic v2 models for every request and response
53
+ - Paired sync (`Nopaque`) and async (`AsyncNopaque`) clients
54
+ - Automatic pagination for list endpoints
55
+ - Polling helpers for long-running jobs (`wait_for_complete`)
56
+ - One-call audio upload/download wrapping the presigned-URL flow
57
+ - Method-aware retry with exponential jitter and `Retry-After` honor
58
+ - Typed exception hierarchy (`NotFoundError`, `RateLimitError`, etc.)
59
+
60
+ ## Documentation
61
+
62
+ Full reference: <https://nopaque.co.uk/docs/sdks>
63
+
64
+ ## Authentication
65
+
66
+ Pass your API key to the client:
67
+
68
+ ```python
69
+ Nopaque(api_key="nop_live_...")
70
+ ```
71
+
72
+ Or set the environment variable:
73
+
74
+ ```bash
75
+ export NOPAQUE_API_KEY=nop_live_...
76
+ ```
77
+
78
+ API keys are workspace-scoped and subject to per-minute rate limits based on
79
+ your subscription tier. Free tier cannot use API keys.
80
+
81
+ ## Requirements
82
+
83
+ - Python 3.9+
84
+ - `httpx >= 0.27`, `pydantic >= 2.6`
85
+
86
+ ## License
87
+
88
+ MIT
@@ -0,0 +1,27 @@
1
+ """Async client example: parallel fetch of multiple resources."""
2
+ import asyncio
3
+
4
+ from nopaque import AsyncNopaque
5
+
6
+
7
+ async def _collect(iterator):
8
+ out = []
9
+ async for item in iterator:
10
+ out.append(item)
11
+ return out
12
+
13
+
14
+ async def main() -> None:
15
+ async with AsyncNopaque() as client:
16
+ audio_task = asyncio.create_task(
17
+ _collect(client.audio.list(limit=10))
18
+ )
19
+ profiles_task = asyncio.create_task(
20
+ _collect(client.profiles.list(limit=10))
21
+ )
22
+ audio, profiles = await asyncio.gather(audio_task, profiles_task)
23
+ print(f"{len(audio)} audio files, {len(profiles)} profiles")
24
+
25
+
26
+ if __name__ == "__main__":
27
+ asyncio.run(main())
@@ -0,0 +1,18 @@
1
+ """Upload a local audio file, then download it by ID."""
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ from nopaque import Nopaque
6
+
7
+ if len(sys.argv) != 2:
8
+ print("Usage: python audio_upload.py <path-to-audio-file>")
9
+ sys.exit(1)
10
+
11
+ path = Path(sys.argv[1])
12
+ with Nopaque() as client:
13
+ audio = client.audio.upload(file=str(path))
14
+ print(f"Uploaded {audio.id} ({audio.file_name})")
15
+
16
+ out = Path("downloaded.wav")
17
+ client.audio.download(audio.id, to=str(out))
18
+ print(f"Downloaded to {out}")
@@ -0,0 +1,33 @@
1
+ """Create a mapping job, start it, wait until it terminates, print tree stats."""
2
+ import os
3
+
4
+ from nopaque import Nopaque
5
+
6
+ PHONE_NUMBER = os.environ["TARGET_PHONE_NUMBER"] # e.g. +441234567890
7
+
8
+ with Nopaque() as client:
9
+ job = client.mapping.create(
10
+ name="Demo mapping",
11
+ phone_number=PHONE_NUMBER,
12
+ mapping_mode="dtmf",
13
+ )
14
+ print(f"Created job {job.id}")
15
+
16
+ client.mapping.start(job.id)
17
+ print("Started run; waiting for completion...")
18
+
19
+ final = client.mapping.wait_for_complete(
20
+ job.id,
21
+ timeout=900.0,
22
+ on_update=lambda j: print(f" status={j.status}"),
23
+ )
24
+ print(f"Final status: {final.status}")
25
+
26
+ tree = client.mapping.tree(job.id)
27
+ if tree.stats:
28
+ s = tree.stats
29
+ print(
30
+ f"Total calls: {s.total_calls} "
31
+ f"(completed={s.completed_calls}, failed={s.failed_calls}, "
32
+ f"loops={s.loops_detected})"
33
+ )
@@ -0,0 +1,11 @@
1
+ """Five-line Nopaque quickstart.
2
+
3
+ Before running: export NOPAQUE_API_KEY=your_key
4
+ """
5
+ from nopaque import Nopaque
6
+
7
+ client = Nopaque()
8
+ print("Listing audio files in workspace:")
9
+ for audio in client.audio.list(limit=5):
10
+ print(f" {audio.id} - {audio.file_name}")
11
+ client.close()
@@ -0,0 +1,87 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "nopaque"
7
+ dynamic = ["version"]
8
+ description = "Official Python SDK for the Nopaque API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { file = "LICENSE" }
12
+ authors = [{ name = "Nopaque", email = "support@nopaque.co.uk" }]
13
+ keywords = ["nopaque", "ivr", "sdk", "api"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "httpx>=0.27",
27
+ "pydantic>=2.6",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://nopaque.co.uk"
32
+ Documentation = "https://nopaque.co.uk/docs/sdks"
33
+ Repository = "https://github.com/nopaque/python-sdk"
34
+ Issues = "https://github.com/nopaque/python-sdk/issues"
35
+
36
+ [tool.hatch.version]
37
+ path = "src/nopaque/_version.py"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/nopaque"]
41
+
42
+ [tool.hatch.envs.default]
43
+ dependencies = [
44
+ "pytest>=8",
45
+ "pytest-asyncio>=0.23",
46
+ "pytest-httpx>=0.30",
47
+ "mypy>=1.10",
48
+ "ruff>=0.4",
49
+ ]
50
+
51
+ [tool.hatch.envs.default.scripts]
52
+ test = "pytest {args:tests}"
53
+ "test:integration" = "pytest tests/integration {args}"
54
+ type = "mypy src/nopaque"
55
+ lint = "ruff check src/nopaque tests"
56
+ format = "ruff format src/nopaque tests"
57
+
58
+ [[tool.hatch.envs.default.matrix]]
59
+ python = ["3.9", "3.10", "3.11", "3.12"]
60
+
61
+ [tool.pytest.ini_options]
62
+ asyncio_mode = "auto"
63
+ testpaths = ["tests"]
64
+ addopts = "--ignore=tests/integration"
65
+ markers = [
66
+ "integration: marks tests that hit the live dev API (run only when NOPAQUE_API_KEY is set)",
67
+ ]
68
+
69
+ [tool.ruff]
70
+ line-length = 100
71
+ target-version = "py39"
72
+
73
+ [tool.ruff.lint]
74
+ select = ["E", "F", "W", "I", "B", "UP", "N"]
75
+ # UP006/UP007 suggest PEP 585/604 generics, but runtime-evaluated Pydantic
76
+ # models need Python 3.10+ for that syntax; we target 3.9.
77
+ ignore = ["UP006", "UP007", "UP035", "UP045"]
78
+
79
+ [tool.ruff.lint.per-file-ignores]
80
+ "tests/**/*.py" = ["E501"]
81
+
82
+ [tool.mypy]
83
+ python_version = "3.9"
84
+ warn_unused_configs = true
85
+ disallow_untyped_defs = true
86
+ check_untyped_defs = true
87
+ ignore_missing_imports = true
@@ -0,0 +1,115 @@
1
+ """Official Python SDK for the Nopaque API."""
2
+ from ._client import AsyncNopaque, Nopaque
3
+ from ._errors import (
4
+ APIConnectionError,
5
+ APITimeoutError,
6
+ AuthenticationError,
7
+ ConflictError,
8
+ NopaqueAPIError,
9
+ NopaqueConfigError,
10
+ NopaqueError,
11
+ NopaqueTimeoutError,
12
+ NotFoundError,
13
+ PermissionError,
14
+ RateLimitError,
15
+ ServerError,
16
+ ValidationError,
17
+ )
18
+ from ._version import __version__
19
+ from .models import (
20
+ AudioDownloadURL,
21
+ AudioFile,
22
+ AudioUploadURL,
23
+ Batch,
24
+ BatchRun,
25
+ Dataset,
26
+ DTMFOption,
27
+ EnrichmentJob,
28
+ EnrichmentResult,
29
+ LoadTest,
30
+ LoadTestEstimate,
31
+ LoadTestProgress,
32
+ LoadTestRun,
33
+ LoadTestStatus,
34
+ MappingJob,
35
+ MappingJobConfig,
36
+ MappingJobStats,
37
+ MappingPath,
38
+ MappingRun,
39
+ MappingStep,
40
+ MappingTree,
41
+ Profile,
42
+ ProfileItem,
43
+ ProfileParameters,
44
+ ResolvedDataset,
45
+ ResolvedEntry,
46
+ RetryConfig,
47
+ Schedule,
48
+ StepResult,
49
+ Sweep,
50
+ SweepRun,
51
+ TestConfig,
52
+ TestJob,
53
+ TestRun,
54
+ TokenUsage,
55
+ TokenUsageDetails,
56
+ TreeNode,
57
+ )
58
+
59
+ __all__ = [
60
+ "__version__",
61
+ "Nopaque",
62
+ "AsyncNopaque",
63
+ # Errors
64
+ "NopaqueError",
65
+ "NopaqueAPIError",
66
+ "AuthenticationError",
67
+ "PermissionError",
68
+ "NotFoundError",
69
+ "ValidationError",
70
+ "ConflictError",
71
+ "RateLimitError",
72
+ "ServerError",
73
+ "APIConnectionError",
74
+ "APITimeoutError",
75
+ "NopaqueConfigError",
76
+ "NopaqueTimeoutError",
77
+ # Models
78
+ "AudioDownloadURL",
79
+ "AudioFile",
80
+ "AudioUploadURL",
81
+ "Batch",
82
+ "BatchRun",
83
+ "Dataset",
84
+ "DTMFOption",
85
+ "EnrichmentJob",
86
+ "EnrichmentResult",
87
+ "LoadTest",
88
+ "LoadTestEstimate",
89
+ "LoadTestProgress",
90
+ "LoadTestRun",
91
+ "LoadTestStatus",
92
+ "MappingJob",
93
+ "MappingJobConfig",
94
+ "MappingJobStats",
95
+ "MappingPath",
96
+ "MappingRun",
97
+ "MappingStep",
98
+ "MappingTree",
99
+ "Profile",
100
+ "ProfileItem",
101
+ "ProfileParameters",
102
+ "ResolvedDataset",
103
+ "ResolvedEntry",
104
+ "RetryConfig",
105
+ "Schedule",
106
+ "StepResult",
107
+ "Sweep",
108
+ "SweepRun",
109
+ "TestConfig",
110
+ "TestJob",
111
+ "TestRun",
112
+ "TokenUsage",
113
+ "TokenUsageDetails",
114
+ "TreeNode",
115
+ ]