audiopod 2.1.0__py3-none-any.whl → 2.2.0__py3-none-any.whl
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.
- audiopod/__init__.py +12 -13
- audiopod/client.py +238 -124
- audiopod/config.py +17 -0
- audiopod/exceptions.py +19 -27
- audiopod/services/__init__.py +30 -0
- audiopod/services/base.py +69 -0
- audiopod/services/credits.py +42 -0
- audiopod/services/denoiser.py +136 -0
- audiopod/services/music.py +217 -0
- audiopod/services/speaker.py +134 -0
- audiopod/services/stem_extraction.py +287 -0
- audiopod/services/transcription.py +210 -0
- audiopod/services/translation.py +135 -0
- audiopod/services/video.py +329 -0
- audiopod/services/voice.py +187 -0
- audiopod/services/wallet.py +235 -0
- audiopod-2.2.0.dist-info/METADATA +206 -0
- audiopod-2.2.0.dist-info/RECORD +21 -0
- {audiopod-2.1.0.dist-info → audiopod-2.2.0.dist-info}/WHEEL +1 -1
- audiopod/resources/__init__.py +0 -23
- audiopod/resources/denoiser.py +0 -116
- audiopod/resources/music.py +0 -166
- audiopod/resources/speaker.py +0 -132
- audiopod/resources/stems.py +0 -267
- audiopod/resources/transcription.py +0 -205
- audiopod/resources/voice.py +0 -139
- audiopod/resources/wallet.py +0 -110
- audiopod-2.1.0.dist-info/METADATA +0 -205
- audiopod-2.1.0.dist-info/RECORD +0 -16
- {audiopod-2.1.0.dist-info → audiopod-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {audiopod-2.1.0.dist-info → audiopod-2.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API Wallet Service - Manage API billing and balance
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any, Optional, List
|
|
6
|
+
from .base import BaseService
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WalletService(BaseService):
|
|
10
|
+
"""
|
|
11
|
+
Service for managing API wallet balance and billing.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
```python
|
|
15
|
+
from audiopod import Client
|
|
16
|
+
|
|
17
|
+
client = Client()
|
|
18
|
+
|
|
19
|
+
# Get balance
|
|
20
|
+
balance = client.wallet.get_balance()
|
|
21
|
+
print(f"Balance: {balance['balance_usd']}")
|
|
22
|
+
|
|
23
|
+
# Estimate cost
|
|
24
|
+
estimate = client.wallet.estimate_cost("stem_extraction", 300)
|
|
25
|
+
print(f"Cost: {estimate['cost_usd']}")
|
|
26
|
+
|
|
27
|
+
# Create top-up checkout
|
|
28
|
+
checkout = client.wallet.create_topup_checkout(2500) # $25.00
|
|
29
|
+
print(f"Pay at: {checkout['url']}")
|
|
30
|
+
```
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def get_balance(self) -> Dict[str, Any]:
|
|
34
|
+
"""
|
|
35
|
+
Get current API wallet balance.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Dict with balance_cents, balance_usd, total_topup_cents, total_spent_cents
|
|
39
|
+
"""
|
|
40
|
+
if self.async_mode:
|
|
41
|
+
return self._async_get_balance()
|
|
42
|
+
return self.client.request("GET", "/api/v1/api-wallet/balance")
|
|
43
|
+
|
|
44
|
+
async def _async_get_balance(self) -> Dict[str, Any]:
|
|
45
|
+
return await self.client.request("GET", "/api/v1/api-wallet/balance")
|
|
46
|
+
|
|
47
|
+
def get_pricing(self) -> Dict[str, Any]:
|
|
48
|
+
"""
|
|
49
|
+
Get pricing table for all services.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Dict with services pricing and wallet configuration
|
|
53
|
+
"""
|
|
54
|
+
if self.async_mode:
|
|
55
|
+
return self._async_get_pricing()
|
|
56
|
+
return self.client.request("GET", "/api/v1/api-wallet/pricing")
|
|
57
|
+
|
|
58
|
+
async def _async_get_pricing(self) -> Dict[str, Any]:
|
|
59
|
+
return await self.client.request("GET", "/api/v1/api-wallet/pricing")
|
|
60
|
+
|
|
61
|
+
def estimate_cost(self, service_type: str, duration_seconds: int) -> Dict[str, Any]:
|
|
62
|
+
"""
|
|
63
|
+
Estimate cost for a service operation.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
service_type: Type of service (e.g., "stem_extraction", "transcription")
|
|
67
|
+
duration_seconds: Duration of audio in seconds
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Dict with cost_cents, cost_usd, duration_minutes
|
|
71
|
+
"""
|
|
72
|
+
if self.async_mode:
|
|
73
|
+
return self._async_estimate_cost(service_type, duration_seconds)
|
|
74
|
+
return self.client.request(
|
|
75
|
+
"POST",
|
|
76
|
+
"/api/v1/api-wallet/estimate",
|
|
77
|
+
json_data={"service_type": service_type, "duration_seconds": duration_seconds},
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
async def _async_estimate_cost(self, service_type: str, duration_seconds: int) -> Dict[str, Any]:
|
|
81
|
+
return await self.client.request(
|
|
82
|
+
"POST",
|
|
83
|
+
"/api/v1/api-wallet/estimate",
|
|
84
|
+
json_data={"service_type": service_type, "duration_seconds": duration_seconds},
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def check_balance(self, service_type: str, duration_seconds: int) -> Dict[str, Any]:
|
|
88
|
+
"""
|
|
89
|
+
Check if balance is sufficient for an operation.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
service_type: Type of service
|
|
93
|
+
duration_seconds: Duration of audio in seconds
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
Dict with can_proceed, cost_cents, current_balance_cents
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
InsufficientBalanceError: If balance is insufficient (402 response)
|
|
100
|
+
"""
|
|
101
|
+
if self.async_mode:
|
|
102
|
+
return self._async_check_balance(service_type, duration_seconds)
|
|
103
|
+
return self.client.request(
|
|
104
|
+
"POST",
|
|
105
|
+
"/api/v1/api-wallet/check-balance",
|
|
106
|
+
json_data={"service_type": service_type, "duration_seconds": duration_seconds},
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
async def _async_check_balance(self, service_type: str, duration_seconds: int) -> Dict[str, Any]:
|
|
110
|
+
return await self.client.request(
|
|
111
|
+
"POST",
|
|
112
|
+
"/api/v1/api-wallet/check-balance",
|
|
113
|
+
json_data={"service_type": service_type, "duration_seconds": duration_seconds},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def create_topup_checkout(self, amount_cents: int) -> Dict[str, Any]:
|
|
117
|
+
"""
|
|
118
|
+
Create a Stripe checkout session to top up wallet.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
amount_cents: Amount in cents (min 100 = $1.00, max 1000000 = $10,000)
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Dict with session_id, url, amount_cents, amount_usd
|
|
125
|
+
"""
|
|
126
|
+
if self.async_mode:
|
|
127
|
+
return self._async_create_topup_checkout(amount_cents)
|
|
128
|
+
return self.client.request(
|
|
129
|
+
"POST",
|
|
130
|
+
"/api/v1/api-wallet/topup/checkout",
|
|
131
|
+
json_data={"amount_cents": amount_cents},
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
async def _async_create_topup_checkout(self, amount_cents: int) -> Dict[str, Any]:
|
|
135
|
+
return await self.client.request(
|
|
136
|
+
"POST",
|
|
137
|
+
"/api/v1/api-wallet/topup/checkout",
|
|
138
|
+
json_data={"amount_cents": amount_cents},
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def create_topup_payment_intent(self, amount_cents: int) -> Dict[str, Any]:
|
|
142
|
+
"""
|
|
143
|
+
Create a Stripe PaymentIntent for custom payment flows.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
amount_cents: Amount in cents
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Dict with client_secret, payment_intent_id, amount_cents
|
|
150
|
+
"""
|
|
151
|
+
if self.async_mode:
|
|
152
|
+
return self._async_create_topup_payment_intent(amount_cents)
|
|
153
|
+
return self.client.request(
|
|
154
|
+
"POST",
|
|
155
|
+
"/api/v1/api-wallet/topup/payment-intent",
|
|
156
|
+
json_data={"amount_cents": amount_cents},
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
async def _async_create_topup_payment_intent(self, amount_cents: int) -> Dict[str, Any]:
|
|
160
|
+
return await self.client.request(
|
|
161
|
+
"POST",
|
|
162
|
+
"/api/v1/api-wallet/topup/payment-intent",
|
|
163
|
+
json_data={"amount_cents": amount_cents},
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
def get_usage_history(
|
|
167
|
+
self, page: int = 1, limit: int = 50
|
|
168
|
+
) -> Dict[str, Any]:
|
|
169
|
+
"""
|
|
170
|
+
Get API usage history.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
page: Page number (1-indexed)
|
|
174
|
+
limit: Results per page (max 100)
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Dict with page, limit, logs (list of usage records)
|
|
178
|
+
"""
|
|
179
|
+
if self.async_mode:
|
|
180
|
+
return self._async_get_usage_history(page, limit)
|
|
181
|
+
return self.client.request(
|
|
182
|
+
"GET",
|
|
183
|
+
"/api/v1/api-wallet/usage",
|
|
184
|
+
params={"page": page, "limit": limit},
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
async def _async_get_usage_history(self, page: int, limit: int) -> Dict[str, Any]:
|
|
188
|
+
return await self.client.request(
|
|
189
|
+
"GET",
|
|
190
|
+
"/api/v1/api-wallet/usage",
|
|
191
|
+
params={"page": page, "limit": limit},
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def get_topup_history(
|
|
195
|
+
self, page: int = 1, limit: int = 20
|
|
196
|
+
) -> Dict[str, Any]:
|
|
197
|
+
"""
|
|
198
|
+
Get wallet top-up history.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
page: Page number (1-indexed)
|
|
202
|
+
limit: Results per page (max 100)
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
Dict with page, limit, topups (list of top-up records)
|
|
206
|
+
"""
|
|
207
|
+
if self.async_mode:
|
|
208
|
+
return self._async_get_topup_history(page, limit)
|
|
209
|
+
return self.client.request(
|
|
210
|
+
"GET",
|
|
211
|
+
"/api/v1/api-wallet/topups",
|
|
212
|
+
params={"page": page, "limit": limit},
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
async def _async_get_topup_history(self, page: int, limit: int) -> Dict[str, Any]:
|
|
216
|
+
return await self.client.request(
|
|
217
|
+
"GET",
|
|
218
|
+
"/api/v1/api-wallet/topups",
|
|
219
|
+
params={"page": page, "limit": limit},
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
def get_service_types(self) -> List[str]:
|
|
223
|
+
"""
|
|
224
|
+
Get list of available service types.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
List of service type strings
|
|
228
|
+
"""
|
|
229
|
+
if self.async_mode:
|
|
230
|
+
return self._async_get_service_types()
|
|
231
|
+
return self.client.request("GET", "/api/v1/api-wallet/service-types")
|
|
232
|
+
|
|
233
|
+
async def _async_get_service_types(self) -> List[str]:
|
|
234
|
+
return await self.client.request("GET", "/api/v1/api-wallet/service-types")
|
|
235
|
+
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: audiopod
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: AudioPod SDK for Python - Professional Audio Processing powered by AI
|
|
5
|
+
Author-email: AudioPod AI <support@audiopod.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://audiopod.ai
|
|
8
|
+
Project-URL: Documentation, https://docs.audiopod.ai
|
|
9
|
+
Project-URL: Repository, https://github.com/AudiopodAI/audiopod-python
|
|
10
|
+
Keywords: audiopod,audio,ai,voice,cloning,transcription,stem-separation,music,sdk
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: requests>=2.28.0
|
|
26
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
30
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# AudioPod Python SDK
|
|
35
|
+
|
|
36
|
+
Official Python SDK for [AudioPod AI](https://audiopod.ai) - Professional Audio Processing powered by AI.
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install audiopod
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from audiopod import Client
|
|
48
|
+
|
|
49
|
+
# Initialize client
|
|
50
|
+
client = Client(api_key="ap_your_api_key")
|
|
51
|
+
# Or set AUDIOPOD_API_KEY environment variable
|
|
52
|
+
|
|
53
|
+
# Check wallet balance
|
|
54
|
+
balance = client.wallet.get_balance()
|
|
55
|
+
print(f"Balance: {balance['balance_usd']}")
|
|
56
|
+
|
|
57
|
+
# Extract stems from audio
|
|
58
|
+
job = client.stem_extraction.extract_stems(
|
|
59
|
+
audio_file="song.mp3",
|
|
60
|
+
stem_types=["vocals", "drums", "bass", "other"],
|
|
61
|
+
wait_for_completion=True
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Download stems
|
|
65
|
+
for stem, url in job["download_urls"].items():
|
|
66
|
+
print(f"{stem}: {url}")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Services
|
|
70
|
+
|
|
71
|
+
### Wallet (API Billing)
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
# Get balance
|
|
75
|
+
balance = client.wallet.get_balance()
|
|
76
|
+
|
|
77
|
+
# Get pricing
|
|
78
|
+
pricing = client.wallet.get_pricing()
|
|
79
|
+
|
|
80
|
+
# Estimate cost
|
|
81
|
+
estimate = client.wallet.estimate_cost("stem_extraction", duration_seconds=300)
|
|
82
|
+
|
|
83
|
+
# Top up wallet
|
|
84
|
+
checkout = client.wallet.create_topup_checkout(amount_cents=2500) # $25
|
|
85
|
+
print(f"Pay at: {checkout['url']}")
|
|
86
|
+
|
|
87
|
+
# Usage history
|
|
88
|
+
usage = client.wallet.get_usage_history(page=1, limit=50)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Stem Extraction
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
# Extract all stems
|
|
95
|
+
job = client.stem_extraction.extract_stems(
|
|
96
|
+
audio_file="song.mp3",
|
|
97
|
+
stem_types=["vocals", "drums", "bass", "other"],
|
|
98
|
+
wait_for_completion=True
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# From URL
|
|
102
|
+
job = client.stem_extraction.extract_stems(
|
|
103
|
+
url="https://example.com/song.mp3",
|
|
104
|
+
stem_types=["vocals", "other"]
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Check status
|
|
108
|
+
status = client.stem_extraction.get_job(job_id=123)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Transcription
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
# Transcribe audio
|
|
115
|
+
result = client.transcription.transcribe(
|
|
116
|
+
audio_file="podcast.mp3",
|
|
117
|
+
speaker_diarization=True,
|
|
118
|
+
wait_for_completion=True
|
|
119
|
+
)
|
|
120
|
+
print(result["transcript"])
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Voice Cloning & TTS
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# List voices
|
|
127
|
+
voices = client.voice.list_voices()
|
|
128
|
+
|
|
129
|
+
# Generate speech
|
|
130
|
+
audio = client.voice.generate_speech(
|
|
131
|
+
text="Hello, world!",
|
|
132
|
+
voice_id=123,
|
|
133
|
+
wait_for_completion=True
|
|
134
|
+
)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Music Generation
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
# Generate music
|
|
141
|
+
result = client.music.generate(
|
|
142
|
+
prompt="upbeat electronic dance music",
|
|
143
|
+
duration=30,
|
|
144
|
+
wait_for_completion=True
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Noise Reduction
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
# Denoise audio
|
|
152
|
+
result = client.denoiser.denoise(
|
|
153
|
+
audio_file="noisy.mp3",
|
|
154
|
+
mode="studio",
|
|
155
|
+
wait_for_completion=True
|
|
156
|
+
)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Async Support
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
import asyncio
|
|
163
|
+
from audiopod import AsyncClient
|
|
164
|
+
|
|
165
|
+
async def main():
|
|
166
|
+
async with AsyncClient() as client:
|
|
167
|
+
balance = await client.wallet.get_balance()
|
|
168
|
+
print(f"Balance: {balance['balance_usd']}")
|
|
169
|
+
|
|
170
|
+
asyncio.run(main())
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Error Handling
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from audiopod import Client
|
|
177
|
+
from audiopod.exceptions import (
|
|
178
|
+
AuthenticationError,
|
|
179
|
+
InsufficientBalanceError,
|
|
180
|
+
RateLimitError,
|
|
181
|
+
APIError
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
client = Client()
|
|
186
|
+
job = client.stem_extraction.extract_stems(audio_file="song.mp3")
|
|
187
|
+
except AuthenticationError:
|
|
188
|
+
print("Invalid API key")
|
|
189
|
+
except InsufficientBalanceError as e:
|
|
190
|
+
print(f"Need to top up: required {e.required_cents} cents")
|
|
191
|
+
except RateLimitError:
|
|
192
|
+
print("Rate limit exceeded, try again later")
|
|
193
|
+
except APIError as e:
|
|
194
|
+
print(f"API error ({e.status_code}): {e}")
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Documentation
|
|
198
|
+
|
|
199
|
+
- [API Reference](https://docs.audiopod.ai)
|
|
200
|
+
- [API Wallet](https://docs.audiopod.ai/account/api-wallet)
|
|
201
|
+
- [Stem Separation](https://docs.audiopod.ai/api-reference/stem-splitter)
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
MIT
|
|
206
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
audiopod/__init__.py,sha256=1L2mJzzdEVx9vKmhMV1RDHZ_v3DqJAxMvDNd1mp7eDk,621
|
|
2
|
+
audiopod/client.py,sha256=UyUqCHh2l770Tr5cgThWbxf5na5T551ZOvfXp2vepE8,10482
|
|
3
|
+
audiopod/config.py,sha256=pbmISyy8K9QpR4aYON7xHG5kpimac2lbqgi9wXF7q-Q,316
|
|
4
|
+
audiopod/exceptions.py,sha256=djjLqVHGhUIe2SXFMWkVOw3TdHOZLQzFpQ5EWPjlGFM,946
|
|
5
|
+
audiopod/services/__init__.py,sha256=F7JgtEzVcUqDLjgavUNes6SozoqD74ebwUqPwBWRWY4,708
|
|
6
|
+
audiopod/services/base.py,sha256=-g3PQnXnrJyszj7wdV5Jb1SkUNSvm65TMpWqyIsh8Yo,2256
|
|
7
|
+
audiopod/services/credits.py,sha256=l8zk1XR77nsvMVwjSDOqN_8hUPbwWVCqSXo4JmocXrI,1450
|
|
8
|
+
audiopod/services/denoiser.py,sha256=LeV2zw-BVXkz-wWdXAQPx2mbtJeWBRPCvV0Q_avAAKA,4984
|
|
9
|
+
audiopod/services/music.py,sha256=iihNVLaGCDp5A0jDbziLNLDASdsY1XJbStWkpH6lfuQ,7676
|
|
10
|
+
audiopod/services/speaker.py,sha256=wrQcoKUS9VHjfYwDPYCncXJmeBSJm0bUH8fwlis-NMo,4692
|
|
11
|
+
audiopod/services/stem_extraction.py,sha256=JJwDT63bn7Y7UrRYNd0qXcl6lFkrV1o4yZXkmMzXdYg,10311
|
|
12
|
+
audiopod/services/transcription.py,sha256=OdIaqoYtVLg3O8zTZ1p3LZKH1arFprJuDJc2II9IgnU,7920
|
|
13
|
+
audiopod/services/translation.py,sha256=lpkXKpSGz_ounvDRMCa4vbvv9jHQtQ-Gk3BDR_9fWJo,5222
|
|
14
|
+
audiopod/services/video.py,sha256=y-gSpo8yu6U5bQrpOmT9wqgc4n9tuEag7PcPWyDOQRM,11711
|
|
15
|
+
audiopod/services/voice.py,sha256=JtlH9DCHi-D9eVSo3g95VeB99aBjdcOxTOm6RN8Re1E,7234
|
|
16
|
+
audiopod/services/wallet.py,sha256=Dg32Ak51w7BcbLVRl4TrI7yipA4QE5_RUZPHp2JS8T8,7735
|
|
17
|
+
audiopod-2.2.0.dist-info/licenses/LICENSE,sha256=hqEjnOaGNbnLSBxbtbC7WQVREU2vQI8FmwecCiZlMfA,1068
|
|
18
|
+
audiopod-2.2.0.dist-info/METADATA,sha256=Z1BSKVVEmm6Ez-lerTHrHqnoorAuCH9rU_bEhHaNKuQ,4819
|
|
19
|
+
audiopod-2.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
20
|
+
audiopod-2.2.0.dist-info/top_level.txt,sha256=M6yyOFFNpLdH4i1AMRqJZLRIgfpg1NvrQVmnPd8A6N8,9
|
|
21
|
+
audiopod-2.2.0.dist-info/RECORD,,
|
audiopod/resources/__init__.py
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"""AudioPod SDK Resources"""
|
|
2
|
-
|
|
3
|
-
from .transcription import Transcription
|
|
4
|
-
from .voice import Voice
|
|
5
|
-
from .music import Music
|
|
6
|
-
from .stems import StemExtraction
|
|
7
|
-
from .denoiser import Denoiser
|
|
8
|
-
from .speaker import Speaker
|
|
9
|
-
from .wallet import Wallet
|
|
10
|
-
|
|
11
|
-
__all__ = [
|
|
12
|
-
"Transcription",
|
|
13
|
-
"Voice",
|
|
14
|
-
"Music",
|
|
15
|
-
"StemExtraction",
|
|
16
|
-
"Denoiser",
|
|
17
|
-
"Speaker",
|
|
18
|
-
"Wallet",
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
audiopod/resources/denoiser.py
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Denoiser Service - Audio Noise Reduction
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import time
|
|
6
|
-
from typing import Optional, List, Dict, Any, TYPE_CHECKING
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from ..client import AudioPod
|
|
10
|
-
|
|
11
|
-
POLL_INTERVAL = 3 # seconds
|
|
12
|
-
DEFAULT_TIMEOUT = 600 # 10 minutes
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class Denoiser:
|
|
16
|
-
"""Audio noise reduction service."""
|
|
17
|
-
|
|
18
|
-
def __init__(self, client: "AudioPod"):
|
|
19
|
-
self._client = client
|
|
20
|
-
|
|
21
|
-
def create(
|
|
22
|
-
self,
|
|
23
|
-
*,
|
|
24
|
-
file: Optional[str] = None,
|
|
25
|
-
url: Optional[str] = None,
|
|
26
|
-
) -> Dict[str, Any]:
|
|
27
|
-
"""
|
|
28
|
-
Create a denoise job.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
file: Path to audio file
|
|
32
|
-
url: URL of audio/video
|
|
33
|
-
|
|
34
|
-
Returns:
|
|
35
|
-
Denoise job object
|
|
36
|
-
|
|
37
|
-
Example:
|
|
38
|
-
>>> job = client.denoiser.create(file="./noisy-audio.mp3")
|
|
39
|
-
"""
|
|
40
|
-
if file:
|
|
41
|
-
return self._client.upload(
|
|
42
|
-
"/api/v1/denoiser/denoise",
|
|
43
|
-
file,
|
|
44
|
-
field_name="file",
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
if url:
|
|
48
|
-
return self._client.post(
|
|
49
|
-
"/api/v1/denoiser/denoise",
|
|
50
|
-
json_data={"url": url},
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
raise ValueError("Either file or url must be provided")
|
|
54
|
-
|
|
55
|
-
def get(self, job_id: int) -> Dict[str, Any]:
|
|
56
|
-
"""Get a denoise job by ID."""
|
|
57
|
-
return self._client.get(f"/api/v1/denoiser/jobs/{job_id}")
|
|
58
|
-
|
|
59
|
-
def list(
|
|
60
|
-
self,
|
|
61
|
-
*,
|
|
62
|
-
skip: int = 0,
|
|
63
|
-
limit: int = 50,
|
|
64
|
-
status: Optional[str] = None,
|
|
65
|
-
) -> List[Dict[str, Any]]:
|
|
66
|
-
"""List denoise jobs."""
|
|
67
|
-
return self._client.get(
|
|
68
|
-
"/api/v1/denoiser/jobs",
|
|
69
|
-
params={"skip": skip, "limit": limit, "status": status},
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
def delete(self, job_id: int) -> None:
|
|
73
|
-
"""Delete a denoise job."""
|
|
74
|
-
self._client.delete(f"/api/v1/denoiser/jobs/{job_id}")
|
|
75
|
-
|
|
76
|
-
def wait_for_completion(
|
|
77
|
-
self, job_id: int, timeout: int = DEFAULT_TIMEOUT
|
|
78
|
-
) -> Dict[str, Any]:
|
|
79
|
-
"""Wait for denoising to complete."""
|
|
80
|
-
start_time = time.time()
|
|
81
|
-
|
|
82
|
-
while time.time() - start_time < timeout:
|
|
83
|
-
job = self.get(job_id)
|
|
84
|
-
status = job.get("status", "")
|
|
85
|
-
|
|
86
|
-
if status == "COMPLETED":
|
|
87
|
-
return job
|
|
88
|
-
if status == "FAILED":
|
|
89
|
-
raise RuntimeError(
|
|
90
|
-
f"Denoising failed: {job.get('error_message', 'Unknown error')}"
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
time.sleep(POLL_INTERVAL)
|
|
94
|
-
|
|
95
|
-
raise TimeoutError(f"Denoising timed out after {timeout}s")
|
|
96
|
-
|
|
97
|
-
def denoise(
|
|
98
|
-
self,
|
|
99
|
-
*,
|
|
100
|
-
file: Optional[str] = None,
|
|
101
|
-
url: Optional[str] = None,
|
|
102
|
-
timeout: int = DEFAULT_TIMEOUT,
|
|
103
|
-
) -> Dict[str, Any]:
|
|
104
|
-
"""
|
|
105
|
-
Denoise audio and wait for completion.
|
|
106
|
-
|
|
107
|
-
Example:
|
|
108
|
-
>>> result = client.denoiser.denoise(file="./noisy-audio.mp3")
|
|
109
|
-
>>> print(result["output_url"])
|
|
110
|
-
"""
|
|
111
|
-
job = self.create(file=file, url=url)
|
|
112
|
-
return self.wait_for_completion(job["id"], timeout=timeout)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|