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.
- nopaque-0.1.0/.github/workflows/ci.yml +31 -0
- nopaque-0.1.0/.github/workflows/nightly-integration.yml +22 -0
- nopaque-0.1.0/.github/workflows/release.yml +48 -0
- nopaque-0.1.0/.gitignore +15 -0
- nopaque-0.1.0/CHANGELOG.md +23 -0
- nopaque-0.1.0/LICENSE +21 -0
- nopaque-0.1.0/PKG-INFO +134 -0
- nopaque-0.1.0/README.md +88 -0
- nopaque-0.1.0/examples/async_example.py +27 -0
- nopaque-0.1.0/examples/audio_upload.py +18 -0
- nopaque-0.1.0/examples/mapping_and_wait.py +33 -0
- nopaque-0.1.0/examples/quickstart.py +11 -0
- nopaque-0.1.0/pyproject.toml +87 -0
- nopaque-0.1.0/src/nopaque/__init__.py +115 -0
- nopaque-0.1.0/src/nopaque/_client.py +107 -0
- nopaque-0.1.0/src/nopaque/_config.py +42 -0
- nopaque-0.1.0/src/nopaque/_errors.py +122 -0
- nopaque-0.1.0/src/nopaque/_pagination.py +100 -0
- nopaque-0.1.0/src/nopaque/_polling.py +106 -0
- nopaque-0.1.0/src/nopaque/_request_options.py +30 -0
- nopaque-0.1.0/src/nopaque/_resource.py +19 -0
- nopaque-0.1.0/src/nopaque/_retry.py +93 -0
- nopaque-0.1.0/src/nopaque/_s3.py +94 -0
- nopaque-0.1.0/src/nopaque/_transport.py +253 -0
- nopaque-0.1.0/src/nopaque/_user_agent.py +20 -0
- nopaque-0.1.0/src/nopaque/_version.py +1 -0
- nopaque-0.1.0/src/nopaque/models/__init__.py +90 -0
- nopaque-0.1.0/src/nopaque/models/audio.py +67 -0
- nopaque-0.1.0/src/nopaque/models/batches.py +52 -0
- nopaque-0.1.0/src/nopaque/models/datasets.py +44 -0
- nopaque-0.1.0/src/nopaque/models/enrichment.py +57 -0
- nopaque-0.1.0/src/nopaque/models/load_testing.py +76 -0
- nopaque-0.1.0/src/nopaque/models/mapping.py +208 -0
- nopaque-0.1.0/src/nopaque/models/profiles.py +46 -0
- nopaque-0.1.0/src/nopaque/models/scheduler.py +42 -0
- nopaque-0.1.0/src/nopaque/models/sweeps.py +52 -0
- nopaque-0.1.0/src/nopaque/models/testing.py +55 -0
- nopaque-0.1.0/src/nopaque/resources/__init__.py +0 -0
- nopaque-0.1.0/src/nopaque/resources/audio.py +274 -0
- nopaque-0.1.0/src/nopaque/resources/batches.py +360 -0
- nopaque-0.1.0/src/nopaque/resources/datasets.py +209 -0
- nopaque-0.1.0/src/nopaque/resources/enrichment.py +101 -0
- nopaque-0.1.0/src/nopaque/resources/load_testing.py +413 -0
- nopaque-0.1.0/src/nopaque/resources/mapping.py +637 -0
- nopaque-0.1.0/src/nopaque/resources/profiles.py +335 -0
- nopaque-0.1.0/src/nopaque/resources/scheduler.py +247 -0
- nopaque-0.1.0/src/nopaque/resources/sweeps.py +361 -0
- nopaque-0.1.0/src/nopaque/resources/testing.py +552 -0
- nopaque-0.1.0/tests/__init__.py +0 -0
- nopaque-0.1.0/tests/conftest.py +1 -0
- nopaque-0.1.0/tests/integration/__init__.py +0 -0
- nopaque-0.1.0/tests/integration/test_smoke.py +59 -0
- nopaque-0.1.0/tests/resources/__init__.py +0 -0
- nopaque-0.1.0/tests/resources/test_audio.py +210 -0
- nopaque-0.1.0/tests/resources/test_batches.py +121 -0
- nopaque-0.1.0/tests/resources/test_datasets.py +81 -0
- nopaque-0.1.0/tests/resources/test_enrichment.py +58 -0
- nopaque-0.1.0/tests/resources/test_load_testing.py +139 -0
- nopaque-0.1.0/tests/resources/test_mapping.py +248 -0
- nopaque-0.1.0/tests/resources/test_profiles.py +137 -0
- nopaque-0.1.0/tests/resources/test_scheduler.py +88 -0
- nopaque-0.1.0/tests/resources/test_sweeps.py +121 -0
- nopaque-0.1.0/tests/resources/test_testing.py +163 -0
- nopaque-0.1.0/tests/test_client.py +40 -0
- nopaque-0.1.0/tests/test_config.py +51 -0
- nopaque-0.1.0/tests/test_errors.py +82 -0
- nopaque-0.1.0/tests/test_pagination.py +68 -0
- nopaque-0.1.0/tests/test_polling.py +91 -0
- nopaque-0.1.0/tests/test_retry.py +103 -0
- nopaque-0.1.0/tests/test_transport.py +194 -0
- 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/*
|
nopaque-0.1.0/.gitignore
ADDED
|
@@ -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
|
nopaque-0.1.0/README.md
ADDED
|
@@ -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
|
+
]
|