elevenlabs / elevenlabs-python

The official Python API for ElevenLabs Text to Speech.
https://elevenlabs.io/docs/api-reference/getting-started
MIT License
2.17k stars 251 forks source link

Make objects json serializable? #391

Open gwpl opened 4 days ago

gwpl commented 4 days ago

Feature Description

Trying to adopt example to pretty print json

#!/usr/bin/env python3

from elevenlabs.client import ElevenLabs
import json

client = ElevenLabs(
#  api_key="YOUR_API_KEY", # Defaults to ELEVEN_API_KEY
)

response = client.voices.get_all()
audio = client.generate(text="Hello there!", voice=response.voices[0])

print(json.dumps(response.voices, indent=2))

currently trying in differnt ways and does not seem to work with json pretty printing...

Use Case

No response

Alternatives Considered

No response

Additional Context

No response

gwpl commented 15 hours ago

I also tried to make output to be JSONL (JSON Lines https://jsonlines.org/ ) and it also failed:

import json                                                  

 for voice in response.voices:                                
     print(json.dumps(voice)) 

error:

Traceback (most recent call last):
  File "/.../elevenlabs_list_available_voices.py", line 14, in <module>
    print(json.dumps(voice))
          ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
dglinyanov commented 13 hours ago

Hi there, as soon as response is Pydantic BaseModel, you can pretty print using .json() method:

print(response.json(indent=2))

Also you can print each of response.voices item the same way, because they are also Pydantic models:

print(response.voices[0].json(indent=2))

Hope that helps!

gwpl commented 12 hours ago

Thanks you!

So, this works:

print(response.json(indent=2))

This does not work ("voices has no attribute json"):

print(response.voices.json(indent=2))

Iterating over voices , works:

for voice in response.voices:
    print(voice.json())

So, looks like each "voice" and "reponse" are Pydantic, but "voices" object is not Pydantic.

dglinyanov commented 11 hours ago

Yes, that's correct. response.voices is a plain list, so it has no .json() method. I am not very familiar with both Pydantic and Fern, so I think it is possible to create Pydantic model for a list of objects, but I do not have any idea if Fern could autogenerate something like that.