ofspectrum 1.1.1__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,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: ofspectrum
3
+ Version: 1.1.1
4
+ Summary: OfSpectrum Audio Watermarking SDK
5
+ Author-email: OfSpectrum <dev@ofspectrum.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://ofspectrum.com
8
+ Project-URL: Documentation, https://api.ofspectrum.com/docs
9
+ Project-URL: Repository, https://github.com/ofspectrum/python-sdk
10
+ Keywords: audio,watermark,api,sdk,ofspectrum
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Multimedia :: Sound/Audio
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: httpx>=0.24.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
28
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
29
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
30
+
31
+ # OfSpectrum Python SDK
32
+
33
+ Official Python SDK for the OfSpectrum Audio Watermarking API.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install ofspectrum
39
+ ```
40
+
41
+ Or install from source:
42
+
43
+ ```bash
44
+ pip install -e /path/to/neo/sdk
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ```python
50
+ from ofspectrum import OfSpectrum
51
+
52
+ # Initialize client with your API key
53
+ client = OfSpectrum(api_key="your_api_key")
54
+
55
+ # Create a watermark token (simple - uses "standard" type by default)
56
+ token = client.tokens.create(name="Production Token")
57
+ print(f"Created token: {token.id}")
58
+
59
+ # Or specify a type (creator/enterprise require public_key)
60
+ # token = client.tokens.create(
61
+ # name="Creator Token",
62
+ # token_type="creator",
63
+ # public_key=12345
64
+ # )
65
+
66
+ # Encode watermark into audio
67
+ result = client.audio.encode(
68
+ audio="input.mp3",
69
+ token_id=token.id,
70
+ output_path="watermarked.mp3"
71
+ )
72
+ print(f"Encoded {result.audio_duration}s of audio")
73
+
74
+ # Decode (detect) watermark from audio
75
+ decode = client.audio.decode("suspect.mp3")
76
+ if decode.watermarked:
77
+ print(f"Watermark detected! Token ID: {decode.token_id}")
78
+ else:
79
+ print("No watermark detected")
80
+
81
+ # Check your quota
82
+ quota = client.quotas.get_encode_quota()
83
+ print(f"Remaining encode quota: {quota.remaining}/{quota.quota_limit} seconds")
84
+ ```
85
+
86
+ ## Features
87
+
88
+ ### Token Management
89
+
90
+ ```python
91
+ # List all tokens
92
+ tokens = client.tokens.list()
93
+
94
+ # Get a specific token
95
+ token = client.tokens.get("token-uuid")
96
+
97
+ # Update a token
98
+ token = client.tokens.update(
99
+ token_id="token-uuid",
100
+ name="New Name"
101
+ )
102
+
103
+ # Note: Token deletion is not available via API.
104
+ # Tokens are consumable resources.
105
+ ```
106
+
107
+ ### Audio Watermarking
108
+
109
+ ```python
110
+ # Encode with custom settings
111
+ result = client.audio.encode(
112
+ audio="input.mp3",
113
+ token_id=token.id,
114
+ strength=1.0, # 0.1-2.0
115
+ normalize=True, # Smooth audio to reduce artifacts
116
+ check_watermark=True, # Check for existing watermark first
117
+ output_path="output.mp3"
118
+ )
119
+
120
+ # Decode watermark from audio file
121
+ decode = client.audio.decode("suspect.mp3")
122
+ if decode.watermarked:
123
+ print(f"Token: {decode.token_id}")
124
+ ```
125
+
126
+ ### Notebook (Notes) Management
127
+
128
+ ```python
129
+ # Create a public notebook for a token
130
+ notebook = client.notebooks.create(
131
+ token_id=token.id,
132
+ note_name="Release Notes",
133
+ text_content="## Version 1.0\n\nInitial release.",
134
+ is_public=True
135
+ )
136
+
137
+ # Create a private notebook (default password: "123")
138
+ private_nb = client.notebooks.create(
139
+ token_id=token.id,
140
+ note_name="Private Notes",
141
+ text_content="Confidential content",
142
+ is_public=False,
143
+ credential_val="123" # Optional, defaults to "123"
144
+ )
145
+
146
+ # Upload media to notebook
147
+ client.notebooks.upload_media(
148
+ note_id=notebook.id,
149
+ file="cover.jpg"
150
+ )
151
+
152
+ # List notebooks for a token
153
+ notebooks = client.notebooks.list(token_id=token.id)
154
+ ```
155
+
156
+ ### Quota Checking
157
+
158
+ ```python
159
+ # Get all quotas
160
+ quotas = client.quotas.get_all()
161
+ for quota in quotas:
162
+ print(f"{quota.service_name}: {quota.remaining}/{quota.quota_limit}")
163
+
164
+ # Check if encoding is available
165
+ if client.quotas.check_encode_available(duration_seconds=300):
166
+ # Proceed with encoding
167
+ pass
168
+ ```
169
+
170
+ ## Error Handling
171
+
172
+ ```python
173
+ from ofspectrum import (
174
+ OfSpectrumError,
175
+ AuthenticationError,
176
+ RateLimitError,
177
+ QuotaExceededError,
178
+ WatermarkExistsError,
179
+ ResourceNotFoundError,
180
+ )
181
+
182
+ try:
183
+ result = client.audio.encode(audio="input.mp3", token_id="...")
184
+ except RateLimitError as e:
185
+ print(f"Rate limited! Retry after {e.retry_after} seconds")
186
+ except QuotaExceededError as e:
187
+ print(f"Quota exceeded for {e.service}")
188
+ except WatermarkExistsError:
189
+ print("Audio already has a watermark!")
190
+ except AuthenticationError:
191
+ print("Invalid API key")
192
+ except OfSpectrumError as e:
193
+ print(f"API error: {e.code} - {e.message}")
194
+ ```
195
+
196
+ ## Retry Logic
197
+
198
+ ```python
199
+ from ofspectrum import OfSpectrum, RetryConfig, with_retry
200
+
201
+ # Use built-in retry decorator
202
+ @with_retry(RetryConfig(max_retries=3))
203
+ def encode_with_retry():
204
+ return client.audio.encode(...)
205
+
206
+ # Or configure retry globally
207
+ config = RetryConfig(
208
+ max_retries=5,
209
+ initial_delay=1.0,
210
+ max_delay=60.0,
211
+ exponential_base=2.0,
212
+ jitter=True
213
+ )
214
+ ```
215
+
216
+ ## Context Manager
217
+
218
+ ```python
219
+ # Recommended: Use context manager for automatic cleanup
220
+ with OfSpectrum(api_key="your_api_key") as client:
221
+ tokens = client.tokens.list()
222
+ ```
223
+
224
+ ## Configuration
225
+
226
+ ```python
227
+ client = OfSpectrum(
228
+ api_key="your_api_key",
229
+ base_url="https://api.ofspectrum.com/api/v1", # Optional: custom base URL
230
+ timeout=120.0 # Optional: request timeout in seconds
231
+ )
232
+ ```
233
+
234
+ ## Requirements
235
+
236
+ - Python 3.8+
237
+ - httpx >= 0.24.0
238
+
239
+ ## License
240
+
241
+ MIT License
@@ -0,0 +1,211 @@
1
+ # OfSpectrum Python SDK
2
+
3
+ Official Python SDK for the OfSpectrum Audio Watermarking API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install ofspectrum
9
+ ```
10
+
11
+ Or install from source:
12
+
13
+ ```bash
14
+ pip install -e /path/to/neo/sdk
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```python
20
+ from ofspectrum import OfSpectrum
21
+
22
+ # Initialize client with your API key
23
+ client = OfSpectrum(api_key="your_api_key")
24
+
25
+ # Create a watermark token (simple - uses "standard" type by default)
26
+ token = client.tokens.create(name="Production Token")
27
+ print(f"Created token: {token.id}")
28
+
29
+ # Or specify a type (creator/enterprise require public_key)
30
+ # token = client.tokens.create(
31
+ # name="Creator Token",
32
+ # token_type="creator",
33
+ # public_key=12345
34
+ # )
35
+
36
+ # Encode watermark into audio
37
+ result = client.audio.encode(
38
+ audio="input.mp3",
39
+ token_id=token.id,
40
+ output_path="watermarked.mp3"
41
+ )
42
+ print(f"Encoded {result.audio_duration}s of audio")
43
+
44
+ # Decode (detect) watermark from audio
45
+ decode = client.audio.decode("suspect.mp3")
46
+ if decode.watermarked:
47
+ print(f"Watermark detected! Token ID: {decode.token_id}")
48
+ else:
49
+ print("No watermark detected")
50
+
51
+ # Check your quota
52
+ quota = client.quotas.get_encode_quota()
53
+ print(f"Remaining encode quota: {quota.remaining}/{quota.quota_limit} seconds")
54
+ ```
55
+
56
+ ## Features
57
+
58
+ ### Token Management
59
+
60
+ ```python
61
+ # List all tokens
62
+ tokens = client.tokens.list()
63
+
64
+ # Get a specific token
65
+ token = client.tokens.get("token-uuid")
66
+
67
+ # Update a token
68
+ token = client.tokens.update(
69
+ token_id="token-uuid",
70
+ name="New Name"
71
+ )
72
+
73
+ # Note: Token deletion is not available via API.
74
+ # Tokens are consumable resources.
75
+ ```
76
+
77
+ ### Audio Watermarking
78
+
79
+ ```python
80
+ # Encode with custom settings
81
+ result = client.audio.encode(
82
+ audio="input.mp3",
83
+ token_id=token.id,
84
+ strength=1.0, # 0.1-2.0
85
+ normalize=True, # Smooth audio to reduce artifacts
86
+ check_watermark=True, # Check for existing watermark first
87
+ output_path="output.mp3"
88
+ )
89
+
90
+ # Decode watermark from audio file
91
+ decode = client.audio.decode("suspect.mp3")
92
+ if decode.watermarked:
93
+ print(f"Token: {decode.token_id}")
94
+ ```
95
+
96
+ ### Notebook (Notes) Management
97
+
98
+ ```python
99
+ # Create a public notebook for a token
100
+ notebook = client.notebooks.create(
101
+ token_id=token.id,
102
+ note_name="Release Notes",
103
+ text_content="## Version 1.0\n\nInitial release.",
104
+ is_public=True
105
+ )
106
+
107
+ # Create a private notebook (default password: "123")
108
+ private_nb = client.notebooks.create(
109
+ token_id=token.id,
110
+ note_name="Private Notes",
111
+ text_content="Confidential content",
112
+ is_public=False,
113
+ credential_val="123" # Optional, defaults to "123"
114
+ )
115
+
116
+ # Upload media to notebook
117
+ client.notebooks.upload_media(
118
+ note_id=notebook.id,
119
+ file="cover.jpg"
120
+ )
121
+
122
+ # List notebooks for a token
123
+ notebooks = client.notebooks.list(token_id=token.id)
124
+ ```
125
+
126
+ ### Quota Checking
127
+
128
+ ```python
129
+ # Get all quotas
130
+ quotas = client.quotas.get_all()
131
+ for quota in quotas:
132
+ print(f"{quota.service_name}: {quota.remaining}/{quota.quota_limit}")
133
+
134
+ # Check if encoding is available
135
+ if client.quotas.check_encode_available(duration_seconds=300):
136
+ # Proceed with encoding
137
+ pass
138
+ ```
139
+
140
+ ## Error Handling
141
+
142
+ ```python
143
+ from ofspectrum import (
144
+ OfSpectrumError,
145
+ AuthenticationError,
146
+ RateLimitError,
147
+ QuotaExceededError,
148
+ WatermarkExistsError,
149
+ ResourceNotFoundError,
150
+ )
151
+
152
+ try:
153
+ result = client.audio.encode(audio="input.mp3", token_id="...")
154
+ except RateLimitError as e:
155
+ print(f"Rate limited! Retry after {e.retry_after} seconds")
156
+ except QuotaExceededError as e:
157
+ print(f"Quota exceeded for {e.service}")
158
+ except WatermarkExistsError:
159
+ print("Audio already has a watermark!")
160
+ except AuthenticationError:
161
+ print("Invalid API key")
162
+ except OfSpectrumError as e:
163
+ print(f"API error: {e.code} - {e.message}")
164
+ ```
165
+
166
+ ## Retry Logic
167
+
168
+ ```python
169
+ from ofspectrum import OfSpectrum, RetryConfig, with_retry
170
+
171
+ # Use built-in retry decorator
172
+ @with_retry(RetryConfig(max_retries=3))
173
+ def encode_with_retry():
174
+ return client.audio.encode(...)
175
+
176
+ # Or configure retry globally
177
+ config = RetryConfig(
178
+ max_retries=5,
179
+ initial_delay=1.0,
180
+ max_delay=60.0,
181
+ exponential_base=2.0,
182
+ jitter=True
183
+ )
184
+ ```
185
+
186
+ ## Context Manager
187
+
188
+ ```python
189
+ # Recommended: Use context manager for automatic cleanup
190
+ with OfSpectrum(api_key="your_api_key") as client:
191
+ tokens = client.tokens.list()
192
+ ```
193
+
194
+ ## Configuration
195
+
196
+ ```python
197
+ client = OfSpectrum(
198
+ api_key="your_api_key",
199
+ base_url="https://api.ofspectrum.com/api/v1", # Optional: custom base URL
200
+ timeout=120.0 # Optional: request timeout in seconds
201
+ )
202
+ ```
203
+
204
+ ## Requirements
205
+
206
+ - Python 3.8+
207
+ - httpx >= 0.24.0
208
+
209
+ ## License
210
+
211
+ MIT License
@@ -0,0 +1,91 @@
1
+ """
2
+ OfSpectrum Python SDK
3
+
4
+ Audio watermarking and AI detection API client.
5
+
6
+ Example:
7
+ from ofspectrum import OfSpectrum
8
+
9
+ client = OfSpectrum(api_key="your_api_key")
10
+
11
+ # Create a token
12
+ token = client.tokens.create(name="My Token", token_type="creator")
13
+
14
+ # Encode watermark
15
+ result = client.audio.encode(
16
+ audio="input.mp3",
17
+ token_id=token.id,
18
+ output_path="watermarked.mp3"
19
+ )
20
+ print(f"Encoded {result.audio_duration}s of audio")
21
+
22
+ # Decode watermark
23
+ decode = client.audio.decode("suspect.mp3")
24
+ if decode.watermarked:
25
+ print(f"Found watermark: {decode.token_id}")
26
+
27
+ # Check quota
28
+ quota = client.quotas.get_encode_quota()
29
+ print(f"Remaining: {quota.remaining}/{quota.quota_limit}")
30
+ """
31
+
32
+ __version__ = "1.0.0"
33
+ __author__ = "OfSpectrum"
34
+
35
+ from .client import OfSpectrum, AsyncOfSpectrum
36
+ from .exceptions import (
37
+ OfSpectrumError,
38
+ AuthenticationError,
39
+ RateLimitError,
40
+ QuotaExceededError,
41
+ ResourceNotFoundError,
42
+ ValidationError,
43
+ WatermarkExistsError,
44
+ TimeoutError,
45
+ ServiceUnavailableError,
46
+ NetworkError,
47
+ )
48
+ from .models import (
49
+ Token,
50
+ TokenCreateParams,
51
+ TokenUpdateParams,
52
+ Notebook,
53
+ NotebookMedia,
54
+ NotebookCreateParams,
55
+ EncodeResult,
56
+ DecodeResult,
57
+ Quota,
58
+ QuotaList,
59
+ )
60
+ from .utils import RetryConfig, with_retry
61
+
62
+ __all__ = [
63
+ # Client
64
+ "OfSpectrum",
65
+ "AsyncOfSpectrum",
66
+ # Exceptions
67
+ "OfSpectrumError",
68
+ "AuthenticationError",
69
+ "RateLimitError",
70
+ "QuotaExceededError",
71
+ "ResourceNotFoundError",
72
+ "ValidationError",
73
+ "WatermarkExistsError",
74
+ "TimeoutError",
75
+ "ServiceUnavailableError",
76
+ "NetworkError",
77
+ # Models
78
+ "Token",
79
+ "TokenCreateParams",
80
+ "TokenUpdateParams",
81
+ "Notebook",
82
+ "NotebookMedia",
83
+ "NotebookCreateParams",
84
+ "EncodeResult",
85
+ "DecodeResult",
86
+ "Quota",
87
+ "QuotaList",
88
+ # Utils
89
+ "RetryConfig",
90
+ "with_retry",
91
+ ]