130 lines
3.1 KiB
Python

import os
from typing import Union
import openai
from dotenv import load_dotenv
from flask import Flask, request
from html5lib import HTMLParser
from htmls import index_html, prompt_html_template
load_dotenv()
app = Flask(__name__)
openai.api_key = os.getenv("OPENAI_KEY")
def format_message(message: str) -> list:
"""
Formats the message to send to chatgpt
Args:
message: The message to send to chatgpt
Returns:
The formatted message in a list
Raises:
None
"""
return [
{
"role": "system",
"content": (
"You are a very knowledgeable person with random knowledge for everything the humanity has ever done"
),
},
{"role": "user", "content": message},
]
def extract_html_from_chatgpt_response(returned_string: str) -> Union[str, None]:
"""
Extracts the HTML from the chatgpt response
Args:
returned_string: The string returned by chatgpt
Returns:
The HTML if it is valid, None otherwise
Raises:
None
"""
validator = HTMLParser(strict=True)
try:
validator.parse(returned_string)
return returned_string
except Exception:
match = returned_string.split("<html>")
if len(match) > 1:
html = "<html>" + match[1]
html_match = html.split("</html>")
if len(html_match) > 1:
html = html_match[0] + "</html>"
try:
validator.parse(html)
return html
except Exception:
return None
def get_chatgpt_response(message: str) -> str:
"""
Gets the response from chatgpt
Args:
message: The message to send to chatgpt
Returns:
The HTML response from chatgpt
Raises:
None
"""
try:
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=format_message(
(
f"Give me information about {message}. Now, given this HTML: \n {prompt_html_template} \n replace "
"(topic) with the name of the selected topic and (topic_info) with 5 parragraphs talking about the "
"topic. Replace (related_links) with 10 links related to the topic. For these links, the href "
"should be '/infinite?topic=(slugified_related_topic_name)' and the text should be the name of the "
"related topic. Respond only the converted code"
)
),
)
except openai.error.RateLimitError:
return get_chatgpt_response(message)
html = extract_html_from_chatgpt_response(completion.choices[0].message.content)
if not html:
return get_chatgpt_response(message)
return html
@app.route("/")
def index():
return index_html
@app.route("/start")
def start():
return get_chatgpt_response("a random topic")
@app.route("/infinite")
def topic():
topic = request.args.get("topic")
return get_chatgpt_response(topic)
if __name__ == "__main__":
app.run()