ChatGPT Festivus

Table of contents

ChatGPT Festivus
Categories : Holiday Projects

Abstract

Speaking gizmo gets festive quotes from OpenAI / ChatGPT

ChatGPT Talks

My Festivus gizmo connects to ChatGPT to ask it for "artificial intelligence generated" festivus quotes. It will then (try to Slight smile ) turn the received reply into voice, and say the message. 
Consistent with this "artificial content generation" theme: the logo is generated by Nightcafe. I asked it to create "chatgpt logo in christmas style".

Example quote:

Look and Feel

It's a plain looking device (yeah - I know - not very Holiday compliant). A box with a button, a speaker and a wall plug. When the bored partygoers want some distraction, they can push the button. They will get energised by a new intelligent festive thought.

image

Technology and Flow

Simplicity and off-the-shelf are the key words. I want to use existing assets.

  • OpenAI's Chat API
  • Python and shell scripts
  • OpenAI's Text To Speech API
  • Raspberry Pi
  • Little amplifier and speaker
  • Button

When the button is pushed, my scripts will run to call the API. The API returns a quote that's handed over to the speech module.

Artificial Intelligence content:

  • the gizmo quotes are generated by OpenAI
  • all speech is generated by OpenAI
  • all art in this article is generated by Nightcafe

Button Listener

todo

OpenAI API

This section describes how to get access to the API and use it as a query / response unit.

Key provisioning

Get yourself a ChaTGPT / OpenAI account. The standard free one will do. You can then request a secret API key.

image

image

Copy the key to a safe store. Don't share it. Note to self: also don't put it in source code that is uploaded to the forum.

Install OpenAI library

execute this command:

pip3 install -q openai

Code

I based the initial version on OpenAI's Assistant example.

Set the environment variable OPENAI_API_KEY

$Env:OPENAI_API_KEY = "<api key>"

Test with minimal changes to example:

# ---
assistant = client.beta.assistants.create(
    name="Festivus",
    instructions="You are a festivus narrator. Generate a random festivus quote when asked.",
    tools=[{"type": "code_interpreter"}],
    model="gpt-3.5-turbo",
)

# ---

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Please generate a new random festive quote",
)

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Be merry. Always generate a fresh quote.",
)

# ---

Result

PS > & python3.9.exe openai_festivus.py
checking assistant status.
in progress...
done!
messages:
{'role': 'assistant', 'message': 'Of course! Here\'s a merry quote just for you:\n\n"May your days be merry and bright, and may all your troubles be out of sight."'}
{'role': 'user', 'message': 'Please generate a new random quote'}
PS > & python3.9.exe openai_festivus.py
checking assistant status.
in progress...
in progress...
done!
messages:
{'role': 'assistant', 'message': 'Of course! Here\'s a new random quote just for you:\n\n"Believe you can and you\'re halfway there." - Theodore Roosevelt'}
{'role': 'user', 'message': 'Please generate a new random quote'}

Early success!

Train OpenAI to give only the quote. No confirmation or comments.

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Be merry. Always generate a fresh quote. Do not include any explanation.",
)

Result:

messages:
{'role': 'assistant', 'message': '"May your days be merry and bright."'}
{'role': 'user', 'message': 'Please generate a new random festive quote'}

Better!

Get the actual quote:

            if message.role == "assistant" :
                print(message.content[0].text.value)

'Tis the season to be jolly!

Best!

Speech

OpenAI has a speech module. You send it a text, and it can generate an mp3 file. I pass the part of the payload that represents the quote:

from pathlib import Path

# ---

speech_file_path = Path(__file__).parent / "speech.mp3"

# ---

            if message.role == "assistant" :
                response = openai.audio.speech.create(model="tts-1", voice="alloy", input=message.content[0].text.value)
                response.stream_to_file(speech_file_path)

# ---

Example result:

'Tis the season to be jolly!

Success!

Hardware Hookup

todo

Software Hookup

Almost everything is contained into a single python script. OpenAI does the majority of the work in the cloud: "get quote, turn to speech, say it".

#!/usr/bin/env python

from pathlib import Path
import time
import openai
from playsound import playsound


# gets API Key from environment variable OPENAI_API_KEY
client = openai.OpenAI()

speech_file_path = Path(__file__).parent

assistant = client.beta.assistants.create(
    name="Festivus",
    instructions="You are a festivus narrator. Generate a random festivus quote when asked.",
    tools=[{"type": "code_interpreter"}],
    model="gpt-3.5-turbo",
)

thread = client.beta.threads.create()

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Please generate a new random festive quote",
)

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Be merry. Always generate a fresh quote. Do not include any explanation.",
)

#print("checking assistant status. ")
while True:
    run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)

    if run.status == "completed":
        #print("done!")
        messages = client.beta.threads.messages.list(thread_id=thread.id)

        #print("messages: ")
        for message in messages:
            assert message.content[0].type == "text"
            if message.role == "assistant" :
                print(message.content[0].text.value)
                response = openai.audio.speech.create(model="tts-1", voice="alloy", input="Ho! Ho! Ho!" + message.content[0].text.value)
                response.stream_to_file(speech_file_path / "speech.mp3")
                playsound('./speech.mp3')
        client.beta.assistants.delete(assistant.id)

        break
    else:
        #print("in progress...")
        time.sleep(5)

I need to create a button listener that executes the python script, when activity is detected.

todo

References

logo AI-generated: https://creator.nightcafe.studio/creation/ADSMAN2hDBg8iRYl1CWj

bored partygoer AI generated: https://creator.nightcafe.studio/creation/fHWqZDYB1ZRNunRenpTo

API I use to talk to OpenAI / ChatGPT: https://www.makeuseof.com/chatgpt-api-complete-guide/

examples I used as a starting point: https://github.com/openai/openai-python/tree/v1.3.4/examples

how to make result only return the quote: https://community.openai.com/t/how-to-let-gpt-do-not-return-any-accompanying-text/324513/8

text to speach: https://github.com/openai/openai-python/blob/v1.3.4/examples/audio.py

audio output for headless raspberry os: https://elinux.org/R-Pi_Troubleshooting#Sound

  • I asked OpenAI to use Oscar Wilde's style

    run = client.beta.threads.runs.create(
        thread_id=thread.id,
        assistant_id=assistant.id,
        instructions="Be merry. Always generate a fresh quote. Avoid religious references. Use the style of Oscar Wilde. Do not include any explanation.",
    )

    "May your holiday season be adorned with laughter, love, and a touch of fairy dust."

  • Progress: quote generated and played out loud

  • Early success 2:

    image

  • If you saw the comment above, can you please tell how you got here?

    • Did you get a notification? If yes: how?
    • Did you see blog or comment on an activity list? If yes: from where?
    • Did you (randomly) surf and land here? If yes: what were you looking for?
    • Other

    Related to this support request:  The holidays member area landing page doesn't show participants blogs 

  • Early success: I acquired an API key and have a festive conversation running

    image

    messages: 
    {'role': 'assistant', 'message': 'Here is a festive quote for you: "Wishing you a season of joy, a season of blessings, and a season of love." Enjoy the holiday season!'}
    {'role': 'user', 'message': 'Please generate a new random festive quote'}
  • I will. I published it now so I can share my ups and downs.

  • I'm looking forward to this one Slight smile I hope you update the post with more detail as you progress! If you were posting about a project idea, it'd be best as a forum thread Slight smile