Spaces:
Runtime error
Runtime error
File size: 4,373 Bytes
88aba82 3dbba32 88aba82 |
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 |
from datetime import date
from typing import cast
import openai
import streamlit as st
import gcal
import google_oauth
st.title(":calendar: Creative Calendar")
st.subheader("Illustrate a month from your Google calendar")
client: openai.OpenAI | None = None
month_date: date | None = None
name: str | None = None
gender: str | None = None
genre: str | None = None
submitted = False
creds = google_oauth.load_creds()
# no Google credentials? we need to authenticate
if creds is None:
flow = google_oauth.get_flow()
url = google_oauth.get_auth_url(flow)
st.link_button("Authenticate with Google", url=url)
auth_code = st.text_input("Google auth code", type="password")
if auth_code:
creds = google_oauth.get_creds(flow, auth_code)
st.rerun()
# we have Google credentials, make sure we have the other things
else:
st.checkbox("Authenticated with Google", value=True, disabled=True)
openapi_key = st.text_input("OpenAI API key", type="password")
if openapi_key:
client = openai.OpenAI(api_key=openapi_key)
with st.form("my_form"):
name = st.text_input("Your name")
gender = st.radio("Your gender", ["Male", "Female"]) or "Male"
genre = st.text_input("Illustration genre", value="fantasy")
month_date = cast(date, st.date_input("Select month"))
submitted = st.form_submit_button("Submit")
def compose_story_prompt(
*,
name: str,
gender: str,
events: list[gcal.Event],
genre: str,
) -> str:
prompt_events = []
for ev in events:
dt = ev.start.strftime("%B %d, %Y")
line = f"{dt}: {ev.title}"
if ev.description:
line += f" ({ev.description})"
prompt_events.append(line)
event_str = "\n".join(["-" + ev for ev in prompt_events])
prompt = f"""Consider the following events from my Google calendar:
{event_str}
Write a description for a short {genre} story that captures the major events
from my calendar. The description should cover only the major themes from my
calendar. Do not write the story itself, just a description of the story. Do
not include any references to a calendar or specific dates, just the major
themes from my calendar.
The main character is a {gender} named {name}.
"""
return prompt
def compose_picture_prompt(story: str, genre: str) -> str:
prompt = f"""For the following short {genre} story description, create a single
{genre}-style image that captures the major events in the story. Do not
include any text in the illustration.
-----
{story}
"""
return prompt
@st.cache_data(show_spinner="Writing the story...")
def write_story(story_prompt):
completion = client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": story_prompt},
],
}
],
)
content = completion.choices[0].message.content
return content
@st.cache_data(show_spinner="Illustrating the cover...")
def draw_picture(picture_prompt: str) -> str:
response = client.images.generate(
model="dall-e-3",
prompt=picture_prompt,
size="1024x1024",
quality="standard",
n=1,
)
image_url = response.data[0].url
return cast(str, image_url)
if client and creds and submitted:
cal_service = gcal.build_calendar_api(creds)
calendars = gcal.get_calendars(cal_service)
month_start, month_end = gcal.get_start_and_end(cast(date, month_date))
events = gcal.get_events(cal_service, month_start, month_end, calendars)
st.write(
f":white_check_mark: Fetched {len(events)} events from "
f"{len(calendars)} calendars"
)
story_prompt = compose_story_prompt(
name=cast(str, name),
gender=cast(str, gender),
events=events,
genre=cast(str, genre),
)
story = write_story(story_prompt)
with st.expander("See the story"):
st.write(story)
st.write(
"Tip: The story and image quality depends on the quality"
" of your calendar events."
)
picture_prompt = compose_picture_prompt(story, genre)
image_url = draw_picture(picture_prompt)
st.image(image_url)
|