sixtydb 1.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.
- sixtydb-1.1.0/PKG-INFO +224 -0
- sixtydb-1.1.0/README.md +204 -0
- sixtydb-1.1.0/pyproject.toml +29 -0
- sixtydb-1.1.0/setup.cfg +4 -0
- sixtydb-1.1.0/sixtydb/__init__.py +31 -0
- sixtydb-1.1.0/sixtydb/client.py +312 -0
- sixtydb-1.1.0/sixtydb/dialer.py +238 -0
- sixtydb-1.1.0/sixtydb/judge.py +214 -0
- sixtydb-1.1.0/sixtydb/music.py +180 -0
- sixtydb-1.1.0/sixtydb.egg-info/PKG-INFO +224 -0
- sixtydb-1.1.0/sixtydb.egg-info/SOURCES.txt +12 -0
- sixtydb-1.1.0/sixtydb.egg-info/dependency_links.txt +1 -0
- sixtydb-1.1.0/sixtydb.egg-info/requires.txt +2 -0
- sixtydb-1.1.0/sixtydb.egg-info/top_level.txt +1 -0
sixtydb-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sixtydb
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Official 60db SDK for Python
|
|
5
|
+
Author: 60db
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: 60db,tts,stt,voice,ai
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: requests>=2.28.0
|
|
19
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
20
|
+
|
|
21
|
+
# 60db
|
|
22
|
+
|
|
23
|
+
Official 60db SDK for Python
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install sixtydb
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from sixtydb import SixtyDBClient
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def fetch_and_display_voices(client: SixtyDBClient) -> str:
|
|
38
|
+
"""
|
|
39
|
+
Fetch all available voices and print their details.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
str: Selected voice_id
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
response = client.get_voices()
|
|
46
|
+
except Exception as exc:
|
|
47
|
+
print("Error fetching voices:", exc)
|
|
48
|
+
raise
|
|
49
|
+
|
|
50
|
+
if not response.get("success"):
|
|
51
|
+
raise Exception(response.get("message"))
|
|
52
|
+
|
|
53
|
+
voices = response["data"]["built_in_voices"]
|
|
54
|
+
|
|
55
|
+
if not voices:
|
|
56
|
+
raise Exception("No voices available.")
|
|
57
|
+
|
|
58
|
+
print("\nAvailable Voices:\n" + "-" * 40)
|
|
59
|
+
|
|
60
|
+
for voice in voices:
|
|
61
|
+
print(
|
|
62
|
+
f"Name: {voice.get('name')} | "
|
|
63
|
+
f"Voice ID: {voice.get('voice_id')} | "
|
|
64
|
+
f"Language: {voice.get('language_name')} | "
|
|
65
|
+
f"Gender: {voice.get('gender')}"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return voices[0]["voice_id"]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def generate_speech(client: SixtyDBClient, voice_id: str) -> None:
|
|
72
|
+
"""
|
|
73
|
+
Generate speech and save to file.
|
|
74
|
+
"""
|
|
75
|
+
try:
|
|
76
|
+
audio = client.text_to_speech(
|
|
77
|
+
text="Hello, world!",
|
|
78
|
+
voice_id=voice_id,
|
|
79
|
+
speed=1.0
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
with open("output.mp3", "wb") as file:
|
|
83
|
+
file.write(audio)
|
|
84
|
+
|
|
85
|
+
print("\nAudio saved to output.mp3")
|
|
86
|
+
|
|
87
|
+
except Exception as exc:
|
|
88
|
+
print("Error generating speech:", exc)
|
|
89
|
+
raise
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def main() -> None:
|
|
93
|
+
try:
|
|
94
|
+
client = SixtyDBClient("your-api-key")
|
|
95
|
+
except Exception as exc:
|
|
96
|
+
print("Error creating client:", exc)
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
voice_id = fetch_and_display_voices(client)
|
|
101
|
+
generate_speech(client, voice_id)
|
|
102
|
+
except Exception as exc:
|
|
103
|
+
print("Operation failed:", exc)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
main()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## API Methods
|
|
113
|
+
|
|
114
|
+
### Text-to-Speech
|
|
115
|
+
- `text_to_speech(text, voice_id=None, **params)` – Convert text to speech
|
|
116
|
+
|
|
117
|
+
### Speech-to-Text
|
|
118
|
+
- `speech_to_text(audio_file, language=None)` – Transcribe audio
|
|
119
|
+
- `get_languages()` – Get supported languages
|
|
120
|
+
|
|
121
|
+
### Voices
|
|
122
|
+
- `get_voices()` – List all voices
|
|
123
|
+
|
|
124
|
+
### Music
|
|
125
|
+
Free during beta (no credit check, nothing charged). Each `create()` call
|
|
126
|
+
makes **1 song**, and only **one generation runs at a time per workspace**
|
|
127
|
+
(a second `create()` while one is running returns 429). A song takes about
|
|
128
|
+
1.5-2.5 minutes.
|
|
129
|
+
- `music.create(prompt, lyrics_file=None, **params)` – Create a song (async)
|
|
130
|
+
- `music.list(**params)` – List songs (limit, offset, q, status, type, liked, sort)
|
|
131
|
+
- `music.get(song_id)` – Get a song (includes lyrics)
|
|
132
|
+
- `music.update(song_id, liked=None, played=None)` – Update flags
|
|
133
|
+
- `music.delete(song_id)` – Move a song to trash
|
|
134
|
+
- `music.download(song_id)` – Download the MP3 (bytes)
|
|
135
|
+
- `music.wait_for_completion(song_id, interval=4, timeout=600)` – Poll until succeeded/failed
|
|
136
|
+
- `music.list_voices()` – List catalog + saved voices
|
|
137
|
+
- `music.create_voice(name, file)` – Save a voice from an audio clip
|
|
138
|
+
- `music.health()` – Song service status
|
|
139
|
+
|
|
140
|
+
### Judge
|
|
141
|
+
|
|
142
|
+
Scores content against a rubric you define, and parses conversational turns.
|
|
143
|
+
A classifier, not a generator — answers are probability distributions over
|
|
144
|
+
your own options.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
run = client.judge.evaluate(
|
|
148
|
+
state=call_transcript,
|
|
149
|
+
questions={
|
|
150
|
+
"tone": {"type": "choice",
|
|
151
|
+
"criteria": {"professional": "Calm", "dismissive": "Brushes off",
|
|
152
|
+
"unknown": "Not clear"}}, # always add an escape hatch
|
|
153
|
+
"satisfaction": {"type": "score", "criteria": ["Angry", "Neutral", "Happy"]},
|
|
154
|
+
"resolved": {"type": "noul"},
|
|
155
|
+
},
|
|
156
|
+
)
|
|
157
|
+
run["answers"]["tone"]["choice"] # 'dismissive'
|
|
158
|
+
run["answers"]["satisfaction"]["score"] # 1.87 — weighted, not an index
|
|
159
|
+
run["answers"]["resolved"]["noul"] # 0.28 — probability of true, not a confidence
|
|
160
|
+
run["min_confidence"] # under 0.85 → send to a human
|
|
161
|
+
|
|
162
|
+
rubric = client.judge.rubrics.create(name="Call QA", questions=questions)
|
|
163
|
+
client.judge.evaluate(state=transcript, rubric_id=rubric["id"])
|
|
164
|
+
|
|
165
|
+
turn = client.judge.extract(
|
|
166
|
+
text="move my 10am appointment to friday",
|
|
167
|
+
schema={"intents": {"booking": "Wants to change a booking"},
|
|
168
|
+
"operations": {"reschedule": "Move it"},
|
|
169
|
+
"entities": {"date": "A calendar date"}},
|
|
170
|
+
)
|
|
171
|
+
turn["intent"]["label"] # 'booking'
|
|
172
|
+
turn["entities"] # [{'label': 'date', 'text': 'friday', 'start': 28, 'end': 34, ...}]
|
|
173
|
+
|
|
174
|
+
client.judge.runs.list(needs_review=True) # the low-confidence review queue
|
|
175
|
+
client.judge.models() # authoritative model list
|
|
176
|
+
client.judge.usage("current_month") # spend and run counts
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Entity offsets are Unicode code points** — slice `list(text)[start:end]`,
|
|
180
|
+
not `text[start:end]`, or an emoji earlier in the turn shifts every span.
|
|
181
|
+
|
|
182
|
+
**Pricing:** per input token; the shared state is re-encoded once per
|
|
183
|
+
question. Context is 8K tokens **per question**. Failed runs are refunded.
|
|
184
|
+
|
|
185
|
+
### Dialer
|
|
186
|
+
Not free: a number costs **$6.00/month**, calls cost **$0.003/min**. Most
|
|
187
|
+
calls need a finished trunk setup (dashboard) and approved dialer KYC
|
|
188
|
+
(also done in the dashboard, not exposed by this SDK). `calls.reserve()`
|
|
189
|
+
does **not** dial — it only pre-authorizes a call id for a SIP client
|
|
190
|
+
(softphone/PBX) to use.
|
|
191
|
+
- `dialer.status()` – Provisioning status
|
|
192
|
+
- `dialer.numbers.search()` / `.buy(number=None, **params)` / `.list()` / `.release(e164)` / `.set_caller_id(e164)` – `buy()` requires approved KYC done in the 60db app, otherwise 403 `DIALER_KYC_REQUIRED`/`DIALER_KYC_PENDING`/`DIALER_KYC_REJECTED`; charges $6.00 now, then $6.00/month
|
|
193
|
+
- `dialer.calls.list(limit=None, offset=None)` / `.get(call_id)` / `.live()` / `.line_status()` / `.reserve(to, from_number, sip_call_id, direction="outbound")` – `reserve()` does not dial
|
|
194
|
+
- `dialer.recordings.list(**params)` / `.playback_url(id)` / `.transcript(id)` / `.delete(id)` / `.set_enabled(enabled)`
|
|
195
|
+
- `dialer.billing.subscriptions()` / `.usage(limit=None)`
|
|
196
|
+
- `dialer.webhooks.list()` / `.create(**params)` / `.update(id, **params)` / `.delete(id)` / `.rotate_secret(id)` / `.test(id)` / `.deliveries(id)`
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Example: Speech to Text
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
from sixtydb import SixtyDBClient
|
|
204
|
+
|
|
205
|
+
client = SixtyDBClient("your-api-key")
|
|
206
|
+
|
|
207
|
+
try:
|
|
208
|
+
with open("output.mp3", "rb") as file:
|
|
209
|
+
result = client.speech_to_text(file, language="en")
|
|
210
|
+
|
|
211
|
+
if result.get("success"):
|
|
212
|
+
print("Transcription:", result["data"]["text"])
|
|
213
|
+
else:
|
|
214
|
+
print("STT Error:", result.get("message"))
|
|
215
|
+
|
|
216
|
+
except Exception as exc:
|
|
217
|
+
print("Error during transcription:", exc)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
sixtydb-1.1.0/README.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# 60db
|
|
2
|
+
|
|
3
|
+
Official 60db SDK for Python
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install sixtydb
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from sixtydb import SixtyDBClient
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def fetch_and_display_voices(client: SixtyDBClient) -> str:
|
|
18
|
+
"""
|
|
19
|
+
Fetch all available voices and print their details.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
str: Selected voice_id
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
response = client.get_voices()
|
|
26
|
+
except Exception as exc:
|
|
27
|
+
print("Error fetching voices:", exc)
|
|
28
|
+
raise
|
|
29
|
+
|
|
30
|
+
if not response.get("success"):
|
|
31
|
+
raise Exception(response.get("message"))
|
|
32
|
+
|
|
33
|
+
voices = response["data"]["built_in_voices"]
|
|
34
|
+
|
|
35
|
+
if not voices:
|
|
36
|
+
raise Exception("No voices available.")
|
|
37
|
+
|
|
38
|
+
print("\nAvailable Voices:\n" + "-" * 40)
|
|
39
|
+
|
|
40
|
+
for voice in voices:
|
|
41
|
+
print(
|
|
42
|
+
f"Name: {voice.get('name')} | "
|
|
43
|
+
f"Voice ID: {voice.get('voice_id')} | "
|
|
44
|
+
f"Language: {voice.get('language_name')} | "
|
|
45
|
+
f"Gender: {voice.get('gender')}"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return voices[0]["voice_id"]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def generate_speech(client: SixtyDBClient, voice_id: str) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Generate speech and save to file.
|
|
54
|
+
"""
|
|
55
|
+
try:
|
|
56
|
+
audio = client.text_to_speech(
|
|
57
|
+
text="Hello, world!",
|
|
58
|
+
voice_id=voice_id,
|
|
59
|
+
speed=1.0
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
with open("output.mp3", "wb") as file:
|
|
63
|
+
file.write(audio)
|
|
64
|
+
|
|
65
|
+
print("\nAudio saved to output.mp3")
|
|
66
|
+
|
|
67
|
+
except Exception as exc:
|
|
68
|
+
print("Error generating speech:", exc)
|
|
69
|
+
raise
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def main() -> None:
|
|
73
|
+
try:
|
|
74
|
+
client = SixtyDBClient("your-api-key")
|
|
75
|
+
except Exception as exc:
|
|
76
|
+
print("Error creating client:", exc)
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
voice_id = fetch_and_display_voices(client)
|
|
81
|
+
generate_speech(client, voice_id)
|
|
82
|
+
except Exception as exc:
|
|
83
|
+
print("Operation failed:", exc)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
if __name__ == "__main__":
|
|
87
|
+
main()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## API Methods
|
|
93
|
+
|
|
94
|
+
### Text-to-Speech
|
|
95
|
+
- `text_to_speech(text, voice_id=None, **params)` – Convert text to speech
|
|
96
|
+
|
|
97
|
+
### Speech-to-Text
|
|
98
|
+
- `speech_to_text(audio_file, language=None)` – Transcribe audio
|
|
99
|
+
- `get_languages()` – Get supported languages
|
|
100
|
+
|
|
101
|
+
### Voices
|
|
102
|
+
- `get_voices()` – List all voices
|
|
103
|
+
|
|
104
|
+
### Music
|
|
105
|
+
Free during beta (no credit check, nothing charged). Each `create()` call
|
|
106
|
+
makes **1 song**, and only **one generation runs at a time per workspace**
|
|
107
|
+
(a second `create()` while one is running returns 429). A song takes about
|
|
108
|
+
1.5-2.5 minutes.
|
|
109
|
+
- `music.create(prompt, lyrics_file=None, **params)` – Create a song (async)
|
|
110
|
+
- `music.list(**params)` – List songs (limit, offset, q, status, type, liked, sort)
|
|
111
|
+
- `music.get(song_id)` – Get a song (includes lyrics)
|
|
112
|
+
- `music.update(song_id, liked=None, played=None)` – Update flags
|
|
113
|
+
- `music.delete(song_id)` – Move a song to trash
|
|
114
|
+
- `music.download(song_id)` – Download the MP3 (bytes)
|
|
115
|
+
- `music.wait_for_completion(song_id, interval=4, timeout=600)` – Poll until succeeded/failed
|
|
116
|
+
- `music.list_voices()` – List catalog + saved voices
|
|
117
|
+
- `music.create_voice(name, file)` – Save a voice from an audio clip
|
|
118
|
+
- `music.health()` – Song service status
|
|
119
|
+
|
|
120
|
+
### Judge
|
|
121
|
+
|
|
122
|
+
Scores content against a rubric you define, and parses conversational turns.
|
|
123
|
+
A classifier, not a generator — answers are probability distributions over
|
|
124
|
+
your own options.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
run = client.judge.evaluate(
|
|
128
|
+
state=call_transcript,
|
|
129
|
+
questions={
|
|
130
|
+
"tone": {"type": "choice",
|
|
131
|
+
"criteria": {"professional": "Calm", "dismissive": "Brushes off",
|
|
132
|
+
"unknown": "Not clear"}}, # always add an escape hatch
|
|
133
|
+
"satisfaction": {"type": "score", "criteria": ["Angry", "Neutral", "Happy"]},
|
|
134
|
+
"resolved": {"type": "noul"},
|
|
135
|
+
},
|
|
136
|
+
)
|
|
137
|
+
run["answers"]["tone"]["choice"] # 'dismissive'
|
|
138
|
+
run["answers"]["satisfaction"]["score"] # 1.87 — weighted, not an index
|
|
139
|
+
run["answers"]["resolved"]["noul"] # 0.28 — probability of true, not a confidence
|
|
140
|
+
run["min_confidence"] # under 0.85 → send to a human
|
|
141
|
+
|
|
142
|
+
rubric = client.judge.rubrics.create(name="Call QA", questions=questions)
|
|
143
|
+
client.judge.evaluate(state=transcript, rubric_id=rubric["id"])
|
|
144
|
+
|
|
145
|
+
turn = client.judge.extract(
|
|
146
|
+
text="move my 10am appointment to friday",
|
|
147
|
+
schema={"intents": {"booking": "Wants to change a booking"},
|
|
148
|
+
"operations": {"reschedule": "Move it"},
|
|
149
|
+
"entities": {"date": "A calendar date"}},
|
|
150
|
+
)
|
|
151
|
+
turn["intent"]["label"] # 'booking'
|
|
152
|
+
turn["entities"] # [{'label': 'date', 'text': 'friday', 'start': 28, 'end': 34, ...}]
|
|
153
|
+
|
|
154
|
+
client.judge.runs.list(needs_review=True) # the low-confidence review queue
|
|
155
|
+
client.judge.models() # authoritative model list
|
|
156
|
+
client.judge.usage("current_month") # spend and run counts
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Entity offsets are Unicode code points** — slice `list(text)[start:end]`,
|
|
160
|
+
not `text[start:end]`, or an emoji earlier in the turn shifts every span.
|
|
161
|
+
|
|
162
|
+
**Pricing:** per input token; the shared state is re-encoded once per
|
|
163
|
+
question. Context is 8K tokens **per question**. Failed runs are refunded.
|
|
164
|
+
|
|
165
|
+
### Dialer
|
|
166
|
+
Not free: a number costs **$6.00/month**, calls cost **$0.003/min**. Most
|
|
167
|
+
calls need a finished trunk setup (dashboard) and approved dialer KYC
|
|
168
|
+
(also done in the dashboard, not exposed by this SDK). `calls.reserve()`
|
|
169
|
+
does **not** dial — it only pre-authorizes a call id for a SIP client
|
|
170
|
+
(softphone/PBX) to use.
|
|
171
|
+
- `dialer.status()` – Provisioning status
|
|
172
|
+
- `dialer.numbers.search()` / `.buy(number=None, **params)` / `.list()` / `.release(e164)` / `.set_caller_id(e164)` – `buy()` requires approved KYC done in the 60db app, otherwise 403 `DIALER_KYC_REQUIRED`/`DIALER_KYC_PENDING`/`DIALER_KYC_REJECTED`; charges $6.00 now, then $6.00/month
|
|
173
|
+
- `dialer.calls.list(limit=None, offset=None)` / `.get(call_id)` / `.live()` / `.line_status()` / `.reserve(to, from_number, sip_call_id, direction="outbound")` – `reserve()` does not dial
|
|
174
|
+
- `dialer.recordings.list(**params)` / `.playback_url(id)` / `.transcript(id)` / `.delete(id)` / `.set_enabled(enabled)`
|
|
175
|
+
- `dialer.billing.subscriptions()` / `.usage(limit=None)`
|
|
176
|
+
- `dialer.webhooks.list()` / `.create(**params)` / `.update(id, **params)` / `.delete(id)` / `.rotate_secret(id)` / `.test(id)` / `.deliveries(id)`
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Example: Speech to Text
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from sixtydb import SixtyDBClient
|
|
184
|
+
|
|
185
|
+
client = SixtyDBClient("your-api-key")
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
with open("output.mp3", "rb") as file:
|
|
189
|
+
result = client.speech_to_text(file, language="en")
|
|
190
|
+
|
|
191
|
+
if result.get("success"):
|
|
192
|
+
print("Transcription:", result["data"]["text"])
|
|
193
|
+
else:
|
|
194
|
+
print("STT Error:", result.get("message"))
|
|
195
|
+
|
|
196
|
+
except Exception as exc:
|
|
197
|
+
print("Error during transcription:", exc)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sixtydb"
|
|
7
|
+
version = "1.1.0"
|
|
8
|
+
description = "Official 60db SDK for Python"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
keywords = ["60db", "tts", "stt", "voice", "ai"]
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "60db"}
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.8",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"requests>=2.28.0",
|
|
28
|
+
"typing-extensions>=4.0.0"
|
|
29
|
+
]
|
sixtydb-1.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
60db Python SDK
|
|
3
|
+
Official Python client for the 60db API
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .client import SixtyDBClient
|
|
7
|
+
from .music import MusicResource
|
|
8
|
+
from .judge import JudgeResource, JudgeRubricsResource, JudgeRunsResource
|
|
9
|
+
from .dialer import (
|
|
10
|
+
DialerResource,
|
|
11
|
+
DialerNumbersResource,
|
|
12
|
+
DialerCallsResource,
|
|
13
|
+
DialerRecordingsResource,
|
|
14
|
+
DialerBillingResource,
|
|
15
|
+
DialerWebhooksResource,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__version__ = "1.1.0"
|
|
19
|
+
__all__ = [
|
|
20
|
+
"SixtyDBClient",
|
|
21
|
+
"MusicResource",
|
|
22
|
+
"JudgeResource",
|
|
23
|
+
"JudgeRubricsResource",
|
|
24
|
+
"JudgeRunsResource",
|
|
25
|
+
"DialerResource",
|
|
26
|
+
"DialerNumbersResource",
|
|
27
|
+
"DialerCallsResource",
|
|
28
|
+
"DialerRecordingsResource",
|
|
29
|
+
"DialerBillingResource",
|
|
30
|
+
"DialerWebhooksResource",
|
|
31
|
+
]
|