The above image was made by @amberjyang with Midjourney using the prompt 'a python and a holographic hourglass raining computer code.'
Background
Recently I wrote a proof-of-concept vector search app using pyscript. It takes any detailed question or description of any conspiracy-related topic as input and outputs a list of the most relevant news article summaries from the WantToKnow.info news archive. There are about 12,970 valid entries in the archive. Right now, the app looks at vectors of every one of these news articles and compares these to a vector computed from a user query to find a list of the most relevant items. I'd like to then feed these news items into gpt-4o to generate a summary brief of the material. To keep things secure, the user would input their OpenAI API key and click a button to generate and display the brief.
Revising everything
The other day I posted about hitting a roadblock with the OpenAI API. No matter what I did, I kept getting 401 forbidden errors when calling the API from my app. Eventually I became determined to run exactly the same request from my app as I'd successfully run in my Jupyter notebook. The version of pyscript I was building on (2023.5.1) didn't support this, but the newly released version (2024.5.1) seemed like it could work.
My code totally didn't work when I first tried it with 2024.5.1. The first big problem was that the class Element was no longer available to import from pyscript. There was zero documentation on this change that I could find. Eventually I decided just to reintroduce the class directly in my code, right after the imports. I found the class buried deep in the 2023.5.1 file and more or less just used it directly. Here's what it looks like now:
# Re-implementing the Element class
class Element:
def __init__(self, element_id, element=None):
self._id = element_id
self._element = element
@property
def id(self):
return self._id
@property
def element(self):
"""Return the dom element"""
if not self._element:
self._element = js.document.querySelector(f"#{self._id}")
return self._element
@property
def value(self):
return self.element.value
@property
def innerHtml(self):
return self.element.innerHTML
def write(self, value, append=False):
if not append:
self.element.innerHTML = value
else:
self.element.innerHTML += value
def clear(self):
if hasattr(self.element, "value"):
self.element.value = ""
else:
self.write("", append=False)
def select(self, query, from_content=False):
el = self.element
if from_content:
el = el.content
_el = el.querySelector(query)
if _el:
return Element(_el.id, _el)
else:
js.console.warn(f"WARNING: can't find element matching query {query}")
def clone(self, new_id=None, to=None):
if new_id is None:
new_id = self.element.id
clone = self.element.cloneNode(True)
clone.id = new_id
if to:
to.element.appendChild(clone)
# Inject it into the DOM
to.element.after(clone)
else:
# Inject it into the DOM
self.element.after(clone)
return Element(clone.id, clone)
def remove_class(self, classname):
classList = self.element.classList
if isinstance(classname, list):
classList.remove(*classname)
else:
classList.remove(classname)
def add_class(self, classname):
classList = self.element.classList
if isinstance(classname, list):
classList.add(*classname)
else:
self.element.classList.add(classname)
That actually worked great. Now that I had Element back, I was free to enjoy the perks of the latest and greatest pyscript. I was able to install the openai and ssl packages, making it possible for me to do an API reqest from my app in exactly the same way as I'd done the successful API call from Jupyter. Here's how that looked:
async def send(event=None):
userElement = js.document.getElementById('brief')
OPENAI_API_KEY = userElement.value.strip()
client = OpenAI(api_key=OPENAI_API_KEY, timeout=60.0, max_retries=3)
# Convert similar_items to string format
global similar_items
similar_items_str = ""
for index, row in similar_items.iterrows():
similar_items_str += f"Title: {row['Title']} Summary: {row['Summary']} Note: {row['Note']}"
payload = f"Using br html tags instead of /n for line breaks, please generate a 500 word narrative summary of the following information: '''{similar_items_str}'''"
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": payload }
],
model="gpt-4o",
)
# Log the request data for debugging
console.log(f"Data: {messages}")
# Display the response in the summarybrief div
Element('summarybrief').element.innerHTML = chat_completion
# Debugging log
console.log(reply)
Timeout
This request method didn't produce a 401 error, which was progress. But the request did time out every time I tried it. After reading a bunch of forums, I tried adding timeout=60.0, max_retries=3
but this did nothing. The timeout is happening almost instantly, leading me to believe that OpenAI's default 600ms timeout is being applied to my request. It's very likely that I'm not setting the timeout parameter correctly.
Another possibility is that pyscript is doing something to kill my request. The current state of the code seems to be something of a mystery and I couldn't find answers about this anywhere. So I joined the pyscript discord and asked about it. Hopefully someone there can help me. One way or another, I'm going to get this AI integration working. Eventually.
Read Free Mind Gazette on Substack
Read my novels:
- Small Gods of Time Travel is available as a web book on IPFS and as a 41 piece Tezos NFT collection on Objkt.
- The Paradise Anomaly is available in print via Blurb and for Kindle on Amazon.
- Psychic Avalanche is available in print via Blurb and for Kindle on Amazon.
- One Man Embassy is available in print via Blurb and for Kindle on Amazon.
- Flying Saucer Shenanigans is available in print via Blurb and for Kindle on Amazon.
- Rainbow Lullaby is available in print via Blurb and for Kindle on Amazon.
- The Ostermann Method is available in print via Blurb and for Kindle on Amazon.
- Blue Dragon Mississippi is available in print via Blurb and for Kindle on Amazon.
See my NFTs:
- Small Gods of Time Travel is a 41 piece Tezos NFT collection on Objkt that goes with my book by the same name.
- History and the Machine is a 20 piece Tezos NFT collection on Objkt based on my series of oil paintings of interesting people from history.
- Artifacts of Mind Control is a 15 piece Tezos NFT collection on Objkt based on declassified CIA documents from the MKULTRA program.