scenesfromtomorrow / helper_functions.py
aliss77777's picture
using literal.ai data layer instead of local csv
70201ee
import os
import json
import pandas as pd
import requests
from openai import OpenAI
from datetime import date
from datetime import datetime
from dotenv import load_dotenv
import sys
import io
import base64
import urllib
from PIL import Image
import io
import cv2
from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image # DiffusionPipeline
import torch
#import matplotlib.pyplot as plt
import prompts as pr
pf_api_url = "https://graphql.probablefutures.org"
#pf_token_audience = "https://graphql.probablefutures.com"
#pf_token_url = "https://probablefutures.us.auth0.com/oauth/token"
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
client = OpenAI(api_key=api_key)
model = "gpt-4o" #"gpt-4-0125-preview" # gpt-4 #gpt-3.5-turbo-16k
pipeline_text2image = AutoPipelineForText2Image.from_pretrained("stabilityai/sdxl-turbo", torch_dtype=torch.float16, variant="fp16") # digiplay/Landscape_PhotoReal_v1
pipeline_image2image = AutoPipelineForImage2Image.from_pretrained("stabilityai/sdxl-turbo", torch_dtype=torch.float16, variant="fp16") # digiplay/Landscape_PhotoReal_v1
pipeline_text2image.to("cuda")
pipeline_image2image.to("cuda")
def convert_to_iso8601(date_str):
try:
# Parse the date string to a datetime object
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
# Format the datetime object to ISO 8601 format with timezone offset
iso8601_date = date_obj.strftime("%Y-%m-%dT%H:%M:%S+00:00")
return iso8601_date
except ValueError:
# Return the original string if it's not in the expected date format
return date_str
def get_pf_token():
client_id = os.getenv("CLIENT_ID")
client_secret = os.getenv("CLIENT_SECRET")
url = 'https://graphql.probablefutures.org/auth/token'
# Encode the client credentials
encoded_credentials = base64.b64encode(f"{client_id}:{client_secret}".encode()).decode()
headers = {
'Authorization': 'Basic ' + encoded_credentials
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # This will raise an exception for HTTP errors
data = response.json()
access_token = data['access_token']
return access_token
except requests.exceptions.RequestException as e:
print('There was a problem with your request:', e)
return None
def json_to_dataframe(json_data, address, country):
# Extract the relevant part of the JSON data
json_data = json.loads(json_data)
data = json_data['data']['getDatasetStatistics']['datasetStatisticsResponses']
# Convert to a DataFrame
df = pd.DataFrame(data)
# Normalize the 'info' column if needed
#if not df['info'].apply(lambda x: x == {}).all():
# info_df = pd.json_normalize(df['info'])
# df = df.drop(columns=['info']).join(info_df)
df['address'] = address
df['country'] = country
df = df[['address', 'country', 'name', 'midValue', 'highValue', 'unit', 'mapCategory']]
#df = df[df['name'].str.contains('Change')]
df = df[~((df['midValue'] == '0.0') & (df['highValue'] == '0.0'))]
df.reset_index(drop=True, inplace=True)
return df
def summary_completion(address, country, output, user_question):
content = f"Please answer the user question {user_question} for the location of {address} {country}. Use the information that was just provided previously to the user: {output}"
print(content)
completion = client.chat.completions.create(
model=model, #"gpt-4-0125-preview", # gpt-4 #gpt-3.5-turbo-16k
messages=[
{"role": "system", "content": pr.user_question_prompt},
{"role": "user", "content": content}
],
stream=True
)
return completion#.choices[0].message.content
# the 'content' object is a dataframe so it's wrapped in a str(to_json()) call
def story_completion(story_system_prompt, units, content):
completion = client.chat.completions.create(
model=model, #"gpt-4-0125-preview", # gpt-4 #gpt-3.5-turbo-16k
messages=[
{"role": "system", "content": str(story_system_prompt + ". Be sure to describe the result using the following temperature scale: " + units)},
{"role": "user", "content": str(content.to_json())}
],
stream=True
)
return completion#.choices[0].message.content
# need GPU to run this part; uncomment lines 31 & 32
def get_image_response_SDXL(prompt, image_path=None, filtered_keywords=None): #i'm passing a file path to image when using inpainting; FOR NOW
print('starting SDXL') # Check here for prompt language tips: https://stable-diffusion-art.com/sdxl-prompts/
if image_path is None:
# Generate image from text
# using flash attention for memory optimization
# https://huggingface.co/docs/diffusers/en/optimization/memory#memory-efficient-attention
#with torch.inference_mode():
result_image = pipeline_text2image(
prompt=prompt, num_inference_steps=2, guidance_scale=0.0).images[0] # Assuming default image dimensions or specify if required
else:
# Load the image from the path
#img = Image.open(image_path)
#plt.imshow(img)
#plt.title("Loaded Image")
#plt.show()
#if strength == None:
# strength = 0.51
# adding inpaiting keywords for 2.0 and 3.0 warming scenarios
modified_prompt = filtered_keywords if filtered_keywords else prompt
print(modified_prompt)
# Modify existing image based on new prompt
# using flash attention https://huggingface.co/docs/diffusers/en/optimization/memory#memory-efficient-attention
#with torch.inference_mode():
result_image = pipeline_image2image(
prompt=modified_prompt, image=image_path, strength=0.55, guidance_scale=0.0, num_inference_steps=2).images[0] # negative_prompt="deformed faces, distorted faces, mangled hands, extra legs",
# Save the image to a byte buffer
buffer = io.BytesIO()
result_image.save(buffer, format='PNG')
image_bytes = buffer.getvalue()
return result_image, image_bytes
def summarizer(content, inpainting=None):
if inpainting is None:
system_prompt = pr.summarizer_prompt
else:
system_prompt = pr.summarizer_prompt_inpainting
completion = client.chat.completions.create(
model=model, #"gpt-3.5-turbo-16k", # gpt-4 #gpt-4-0125-preview
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": content}
],
stream=False
)
print(str(completion.choices[0].message.content))# + " Photorealism, Sharp Image, wide shot")
return str(completion.choices[0].message.content)# + " realistic humans " #" long exposure, blurred motion, streaks of light, surreal, dreamy, ghosting effect, highly detailed"
def generate_inpainting_keywords(data_changes):
# Check if the DataFrame is empty or missing the necessary columns
if data_changes.empty or 'midValue' not in data_changes.columns:
return ["no significant change"]
data_changes['name'] = data_changes['name'].str.replace('“', '', regex=False).str.replace('”', '', regex=False).str.replace('"', '', regex=False)
print(data_changes)
# Example: Select the change with the highest 'midValue' as the most significant
# Find the index of the row with the highest 'midValue'
idx_max_midValue = data_changes['midValue'].astype('float').abs().idxmax()
# Retrieve the 'name' from the row with the highest 'midValue'
most_significant_change_name = data_changes.loc[idx_max_midValue, 'name']
print(most_significant_change_name)
#change_name = most_significant_change['name'] # Assuming the name of the change is in the 'name' column
#impact = 'increase' if most_significant_change['midValue'] > 0 else 'decrease'
# Mapping of change types to potential keywords
climate_change_qualifiers = {
'Change in total annual precipitation': 'heavy rain, flooding, gloomy skies',
'Change in wettest 90 days': 'increased rainfall, frequent storms, saturated grounds',
'Change in dry hot days': 'intense sunlight, heat haze, dry atmosphere',
'Change in frequency of 1-in-100-year storm': 'severe storms, extreme weather events, damaged infrastructure',
'Change in precipitation 1-in-100-year storm': 'torrential rain, flash floods, overflowing rivers',
'Likelihood of year-plus extreme drought': 'faded colors, heat mirages, stark shadows',
'Likelihood of year-plus drought': 'heat haze, dusty air, sun-bleached surfaces',
'Change in wildfire danger days': 'smoky haze, distant glow of fires, ash particles in air'
}
# Retrieve qualifiers for the most significant change category
qualifiers = climate_change_qualifiers.get(most_significant_change_name, ["change not specified"])
#qualifiers_string = ", ".join([str(qualifier) for qualifier in qualifiers])
print(qualifiers)
return qualifiers