File size: 9,443 Bytes
d698941
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# prompt: create a function with documentation for connect to GPT4o and ask for the weather
# Note: the above uses the old API, so I look up the current API update the code.
# Manual: Update to horoscopes templates
# prompt: print out the zodiac signs

import datetime
import openai
import os
from openai import OpenAI
client = OpenAI()
#
# Set your OpenAI API key
#
openai.api_key = os.getenv("OPENAI_API_KEY")  # OpenAI API key: https://platform.openai.com/api-keys
#
# For convience to access to the Zodiac signs
#
zodiac_signs = [
  "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
  "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"
]
#
now = datetime.datetime.now()
today = f"{now.strftime('%A')}, {now.strftime('%B')} {now.strftime('%d')}, {now.strftime('%Y')}"
#
# Define the horoscope function
#
def fetch_horoscope(zodiac_sign=zodiac_signs[3],

  name="Hanna",

  person="teen girl",

  focus="in school",

  nationality="American",

  model="gpt-4o"):
  """Connects to GPT-4 and asks for the Horoscope.



  Args:

    zodiac_sign: (string) one of the 12 zodiac signs.

    name: (string) the name of the person.

    person: (string) the person's description.

    focus: (string) the person's focus.

    model: (string) the model to use.

  Raises:

    Exception: If the OpenAI API call fails.

  Returns:

    A string containing the horoscope and if errors return an error message.

  """
  #
  # model choice, "gpt-4o", "gpt-4o-mini"
  # more choice at: https://platform.openai.com/docs/models/gpt-4o-mini
  # model = "gpt-4o"
  #
  # create prompt templates (Prompt Engineering)
  #
  msg1 = {"role": "system", "content": "You are a helpful assistant."}
  #
  _input = f"Generate a daily horoscope for {zodiac_sign} for {today} with a focus on career and relationships. Include {zodiac_sign}'s traits, and mention any relevant celestial events or planetary alignments. Provide practical advice that aligns with the day’s energy. Incorporate lucky elements such as a color, number, or time of day to enhance personalization. Ensure the tone is witty, positive, uplifting, and inspiring."
  #
  _output = f"The output is a story with age appropiate tone to {name}, a {person}, {focus}, and nationality is {nationality}. No bullet points, no heading."
  #
  msg2 = {"role": "user", "content": f"{_input} {_output}"}
  #
  prompt_template = [msg1, msg2]
  #
  # Ask GPT4
  #
  try:
    completion = client.chat.completions.create(
      model=model,
      messages=prompt_template
    )
    # print(completion.choices[0].message)
    horoscope_info = completion.choices[0].message
    return horoscope_info.content
  #
  except Exception as e:
    return f"An error occurred: {e}"
#
# Example usage:
# horoscope_reading = fetch_horoscope(zodiac_signs[0])
# print(f"Your horoscopes for today is:\n\n {horoscope_reading.content}")


# prompt: write a function with documentation to use GPT4 to generate an image
# Note: add in prompt template (prompt engineer)

import os
import openai
from openai import OpenAI

def fetch_image(prompt, n=1, size="1024x1024", model_image="dall-e-3"):
  """Generates an image using OpenAI's DALL-E 2 API based on a given text prompt.



  Args:

    prompt: (string) A text description of the desired image.

    n: (int) The number of images to generate (default is 1).

    size: (string) The size of the generated images (default is 1024x1024).

          Other options include "256x256" and "512x512" and more.

    model: (string) The model to use for image generation (default is "dall-e-3") or dall-e-2.

  Raises:

    Exception: If the OpenAI API call fails.



  Returns:

    A list of image URLs, or an error message if the API call fails.

  """
  #
  # Define the prompt template
  #
  prompt_template = f"Draw a realism beautiful watercolor image in pastel tone with no text, no writing, and no wording for the person in the following horoscope: {prompt}"
  #
  # Request to generate image
  #
  try:
    client = OpenAI()
    response = client.images.generate(
      model=model_image,
      prompt=prompt_template,
      n=n,
      size=size
    )
    image_urls = [image.url for image in response.data]
    return image_urls
  except Exception as e:
    return f"An unexpected error occurred: {e}"


# prompt: write a python function to take the output of OpenAI client.images.generate() function url and using PIL to create an image from it.
# prompt: have error: Error downloading image: No connection adapters were found for "['https://oaidalleapiprodscus.blob.core.windows.net/private/org-A0exPbLvAU5v7R8klVyjjESv/user-N17uY5bUcWfRy95Xxs6huBmQ/img-QF2y2rPhSjGoJO25XeUdLqLD.png?st=2024-11-08T05%3A59%3A14Z&se=2024-11-08T07%3A59%3A14Z&sp=r&sv=2024-08-04&sr=b&rscd=inline&rsct=image/png&skoid=d505667d-d6c1-4a0a-bac7-5c84a87759f8&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-11-07T10%3A09%3A58Z&ske=2024-11-08T10%3A09%3A58Z&sks=b&skv=2024-08-04&sig=bJziZ5sNTiIyl77YfNoFMfc/KB/NL9zHBHSsv2SnlGY%3D']"

import requests
from PIL import Image
from io import BytesIO

def generate_image_from_url(image_url):
    """

    Downloads an image from a URL and creates a PIL Image object.



    Args:

        image_url (str): The URL of the image.



    Returns:

        PIL.Image.Image: A PIL Image object created from the downloaded image.

    """
    try:
        # Ensure the URL is a string and strip any extraneous characters
        if isinstance(image_url, list) and len(image_url) == 1:
            image_url = image_url[0]  # Extract URL if it's in a list
        if not isinstance(image_url, str):
            raise ValueError("The image_url must be a string.")

        # Fetch the image data from the URL
        response = requests.get(image_url)
        response.raise_for_status()  # Ensure the request was successful

        # Load the image into a PIL Image object
        image = Image.open(BytesIO(response.content))
        return image

    except requests.exceptions.RequestException as e:
        print(f"Error fetching the image from URL: {e}")
        return None
    except Exception as e:
        print(f"Error processing the image: {e}")
        return None

# prompt: write tell_me function with inline documentation using *args, **kwargs calling fetch_horoscope and use the output to call fetch_image function return both horoscope text and image link
# Note: minor manual debug
from logging import error
#
def tell_me(*args, **kwargs):
  """Fetches a horoscope and generates an image based on it.



  This function combines the functionality of fetch_horoscope and fetch_image.

  It takes the same arguments as fetch_horoscope, fetches the horoscope,

  and then uses the horoscope text as a prompt for fetch_image to generate an image.



  Args:

    *args: Variable length argument list. Passed to fetch_horoscope.

    **kwargs: Arbitrary keyword arguments. Passed to fetch_horoscope.



  Returns:

    A dictionary containing the horoscope_text and image_url.

    Returns an error message if either API call fails.

  """
  try:
    horoscope_text = fetch_horoscope(
      zodiac_sign=kwargs.get('zodiac_sign', 'Aquarius'),
      name=kwargs.get('name', "Hanna"),
      person=kwargs.get('person', "teen girl"),
      focus=kwargs.get('focus', "in school"),
      model=kwargs.get('model', "gpt-4o"))

    image_url = fetch_image(
      prompt=kwargs.get('prompt', horoscope_text),
      n=kwargs.get('n', 1),
      size=kwargs.get('size', "1024x1024"),
      model_image=kwargs.get('model_image', "dall-e-3")
    )
    return {"horoscope_text":horoscope_text, "image_url":image_url}
  except Exception as e:
    error_message = f"An unexpected error occurred in tell_me(): {e}"
    return {"horoscope_text":error_message, "image_url":"no_url"}

# # Example usage
# json_output = tell_me(zodiac_sign="Taurus")
# print(f"Horoscopes:\n{json_output.horoscope_text}:\n\nImage URL:\n{json_output.image_url}")



# prompt: create a gradio code for input 5 item, person_name, horoscope_sign, job, focus, and nationality, and output has text and image

import gradio

# ... (rest of your existing code) ...

def gradio_tell_me(person_name, horoscope_sign, job, focus, nationality):

    # HARD-CODE to test
    # horoscope_text = dragon_flying
    # image_url = dragon_img_url
    data=tell_me(zodiac_sign=horoscope_sign,
      name=person_name,person=job,focus=focus,nationality=nationality)
    horoscope_text=data['horoscope_text']
    image_url=data['image_url']
    try:
        image = generate_image_from_url(image_url)
    except Exception as e:
      print(f"Error generating image: {e}")
      image = None # Return None if error happens

    return horoscope_text, image

iface = gradio.Interface(
    fn=gradio_tell_me,
    inputs=[
        gradio.Textbox(label="Person Name"),
        gradio.Dropdown(choices=zodiac_signs, label="Horoscope Sign"),
        gradio.Textbox(label="Job"),
        gradio.Textbox(label="Focus"),
        gradio.Textbox(label="Nationality"),
    ],
    outputs=[
        gradio.Textbox(label="Horoscope"),
        gradio.Image(label="Horoscope Image")
    ],
    title="Horoscope Generator",
    description="Generate a personalized horoscope and image."
)

iface.launch()