First, you need to install the library:
pip install PyCharacterAI
Import the Client class from the library and create a new instance of it:
from PyCharacterAI import Clientclient = Client()Then you need to authenticate client using token:
await client.authenticate("TOKEN")if you want to be able to upload your avatar you also need to specify
web_next_authtoken as an additional argument (only this way for now, this may change in the future):await client.authenticate("TOKEN", web_next_auth="WEB_NEXT_AUTH")
Or you can just call get_client() method:
from PyCharacterAI import get_client
client = await get_client(token="TOKEN", web_next_auth="WEB_NEXT_AUTH")After authentication, we can use all available library methods.
⚠️ WARNING, DO NOT SHARE THESE TOKENS WITH ANYONE! Anyone with your tokens has full access to your account!
This library uses two types of tokens: a common token and web_next_auth. The first one is required for almost all methods here and the second one only and only for upload_avatar() method (may change in the future).
- Open the Character.AI website in your browser
- Open the
developer tools(F12,Ctrl+Shift+I, orCmd+J) - Go to the
Nerworktab - Interact with website in some way, for example, go to your profile and look for
Authorizationin the request header - Copy the value after
Token
For example, token in
https://plus.character.ai/chat/user/public/following/request headers:
- Open the Character.AI website in your browser
- Open the
developer tools(F12,Ctrl+Shift+I, orCmd+J) - Go to the
Storagesection and click onCookies - Look for the
web-next-authkey - Copy its value
Further, in the documentation you can find certain concepts, some of them I want to explain below. Some concepts related to character creation and user personas can be found in the official character book.
Turn is a message in chat. It contains one or more candidates that represent the content of this message. Just keep in mind that turn == message.
Candidate (or TurnCandidate) is the "content" of the message (turn). A message can have several candidates (for example, when you swipe the character's answer on the c.ai website, you create new candidate for the character's message).
Primary candidate - currently selected candidate. When you send a new message to the chat, you reply to this (primary) message candidate. When a new alternative response is generated, primary candidate automatically updates to the newly generated candidate. You can also manually set a specific turn candidate as a primary if you want to reply to a particular message candidate. (Refer to the documentation for more details.)
...to be completed
Here are just some examples of the library's features. If you want to know about all
methodsandtypeswith explanations, go to methods and types documentation sections.
import asyncio
from PyCharacterAI import get_client
from PyCharacterAI.exceptions import SessionClosedError
token = "TOKEN"
character_id = "ID"
async def main():
client = await get_client(token=token)
me = await client.account.fetch_me()
print(f"Authenticated as @{me.username}")
chat, greeting_message = await client.chat.create_chat(character_id)
print(f"{greeting_message.author_name}: {greeting_message.get_primary_candidate().text}")
try:
while True:
# NOTE: input() is blocking function!
message = input(f"[{me.name}]: ")
answer = await client.chat.send_message(character_id, chat.chat_id, message)
print(f"[{answer.author_name}]: {answer.get_primary_candidate().text}")
except SessionClosedError:
print("session closed. Bye!")
finally:
# Don't forget to explicitly close the session
await client.close_session()
asyncio.run(main())A more advanced example. You can use so-called streaming to receive a message in parts, as is done on a website, instead of waiting for it to be completely generated:
import asyncio
from PyCharacterAI import get_client
from PyCharacterAI.exceptions import SessionClosedError
token = "TOKEN"
character_id = "ID"
async def main():
client = await get_client(token=token)
me = await client.account.fetch_me()
print(f'Authenticated as @{me.username}')
chat, greeting_message = await client.chat.create_chat(character_id)
print(f"[{greeting_message.author_name}]: {greeting_message.get_primary_candidate().text}")
try:
while True:
# NOTE: input() is blocking function!
message = input(f"[{me.name}]: ")
answer = await client.chat.send_message(character_id, chat.chat_id, message, streaming=True)
printed_length = 0
async for message in answer:
if printed_length == 0:
print(f"[{message.author_name}]: ", end="")
text = message.get_primary_candidate().text
print(text[printed_length:], end="")
printed_length = len(text)
print("\n")
except SessionClosedError:
print("session closed. Bye!")
finally:
# Don't forget to explicitly close the session
await client.close_session()
asyncio.run(main())# We can generate images by a prompt
# (It will return list of urls)
images = await client.utils.generate_image("prompt")# We can upload an image to use it as an
# avatar for character/persona/profile
# NOTE: This method requires the specified web_next_auth token
avatar_file = "path to file or url"
avatar = await client.utils.upload_avatar(avatar_file)# We can search for voices
voices = await client.utils.search_voices("name")# We can upload the audio as a voice
voice_file = "path to file or url"
voice = await client.utils.upload_voice(voice_file, "voice name")# We can set and unset a voice for character
await client.account.set_voice("character_id", "voice_id")
await client.account.unset_voice("character_id")# And we can use voice to generate speech from the character's messages
speech = await client.utils.generate_speech("chat_id", "turn_id", "candidate_id", "voice_id")
# It will return bytes, so we can use it for example like this:
filepath = "voice.mp3"
with open(filepath, 'wb') as f:
f.write(speech)# or we can get just the url.
speech_url = await client.utils.generate_speech("chat_id", "turn_id", "candidate_id",
"voice_id", return_url=True)
