poe.com api (gpt-4) [updated api.py]

This commit is contained in:
t.me/xtekky 2023-04-18 16:16:09 +01:00
parent 3388d70696
commit 05f3695e27
2 changed files with 160 additions and 6 deletions

View File

@ -28,13 +28,16 @@ import queue
import threading import threading
import traceback import traceback
import hashlib import hashlib
import string
import random
import requests.adapters
import websocket import websocket
from pathlib import Path from pathlib import Path
from urllib.parse import urlparse from urllib.parse import urlparse
parent_path = Path(__file__).resolve().parent parent_path = Path(__file__).resolve().parent
queries_path = parent_path / "graphql" queries_path = parent_path / "poe_graphql"
queries = {} queries = {}
logging.basicConfig() logging.basicConfig()
@ -80,6 +83,10 @@ class Client:
def __init__(self, token, proxy=None): def __init__(self, token, proxy=None):
self.proxy = proxy self.proxy = proxy
self.session = requests.Session() self.session = requests.Session()
self.adapter = requests.adapters.HTTPAdapter(
pool_connections=100, pool_maxsize=100)
self.session.mount("http://", self.adapter)
self.session.mount("https://", self.adapter)
if proxy: if proxy:
self.session.proxies = { self.session.proxies = {
@ -143,12 +150,12 @@ class Client:
if overwrite_vars: if overwrite_vars:
self.formkey = self.extract_formkey(r.text) self.formkey = self.extract_formkey(r.text)
self.viewer = next_data["props"]["pageProps"]["payload"]["viewer"] self.viewer = next_data["props"]["pageProps"]["payload"]["viewer"]
self.next_data = next_data
return next_data return next_data
def get_bot(self, display_name): def get_bot(self, display_name):
url = f'https://poe.com/_next/data/{self.next_data["buildId"]}/{display_name}.json' url = f'https://poe.com/_next/data/{self.next_data["buildId"]}/{display_name}.json'
logger.info("Downloading "+url)
r = request_with_retries(self.session.get, url) r = request_with_retries(self.session.get, url)
@ -156,8 +163,9 @@ class Client:
return chat_data return chat_data
def get_bots(self, download_next_data=True): def get_bots(self, download_next_data=True):
logger.info("Downloading all bots...")
if download_next_data: if download_next_data:
next_data = self.get_next_data() next_data = self.get_next_data(overwrite_vars=True)
else: else:
next_data = self.next_data next_data = self.next_data
@ -165,11 +173,23 @@ class Client:
raise RuntimeError("Invalid token or no bots are available.") raise RuntimeError("Invalid token or no bots are available.")
bot_list = self.viewer["availableBots"] bot_list = self.viewer["availableBots"]
threads = []
bots = {} bots = {}
for bot in bot_list:
def get_bot_thread(bot):
chat_data = self.get_bot(bot["displayName"]) chat_data = self.get_bot(bot["displayName"])
bots[chat_data["defaultBotObject"]["nickname"]] = chat_data bots[chat_data["defaultBotObject"]["nickname"]] = chat_data
for bot in bot_list:
thread = threading.Thread(
target=get_bot_thread, args=(bot,), daemon=True)
threads.append(thread)
for thread in threads:
thread.start()
for thread in threads:
thread.join()
self.bots = bots self.bots = bots
self.bot_names = self.get_bot_names() self.bot_names = self.get_bot_names()
return bots return bots
@ -181,6 +201,10 @@ class Client:
bot_names[bot_nickname] = bot_obj["displayName"] bot_names[bot_nickname] = bot_obj["displayName"]
return bot_names return bot_names
def get_remaining_messages(self, chatbot):
chat_data = self.get_bot(self.bot_names[chatbot])
return chat_data["defaultBotObject"]["messageLimit"]["numMessagesRemaining"]
def get_channel_data(self, channel=None): def get_channel_data(self, channel=None):
logger.info("Downloading channel data...") logger.info("Downloading channel data...")
r = request_with_retries(self.session.get, self.settings_url) r = request_with_retries(self.session.get, self.settings_url)
@ -447,5 +471,62 @@ class Client:
last_messages = self.get_message_history(chatbot, count=50)[::-1] last_messages = self.get_message_history(chatbot, count=50)[::-1]
logger.info(f"No more messages left to delete.") logger.info(f"No more messages left to delete.")
def create_bot(self, handle, prompt="", base_model="chinchilla", description="",
intro_message="", api_key=None, api_bot=False, api_url=None,
prompt_public=True, pfp_url=None, linkification=False,
markdown_rendering=True, suggested_replies=False, private=False):
result = self.send_query("PoeBotCreateMutation", {
"model": base_model,
"handle": handle,
"prompt": prompt,
"isPromptPublic": prompt_public,
"introduction": intro_message,
"description": description,
"profilePictureUrl": pfp_url,
"apiUrl": api_url,
"apiKey": api_key,
"isApiBot": api_bot,
"hasLinkification": linkification,
"hasMarkdownRendering": markdown_rendering,
"hasSuggestedReplies": suggested_replies,
"isPrivateBot": private
})
data = result["data"]["poeBotCreate"]
if data["status"] != "success":
raise RuntimeError(
f"Poe returned an error while trying to create a bot: {data['status']}")
self.get_bots()
return data
def edit_bot(self, bot_id, handle, prompt="", base_model="chinchilla", description="",
intro_message="", api_key=None, api_url=None, private=False,
prompt_public=True, pfp_url=None, linkification=False,
markdown_rendering=True, suggested_replies=False):
result = self.send_query("PoeBotEditMutation", {
"baseBot": base_model,
"botId": bot_id,
"handle": handle,
"prompt": prompt,
"isPromptPublic": prompt_public,
"introduction": intro_message,
"description": description,
"profilePictureUrl": pfp_url,
"apiUrl": api_url,
"apiKey": api_key,
"hasLinkification": linkification,
"hasMarkdownRendering": markdown_rendering,
"hasSuggestedReplies": suggested_replies,
"isPrivateBot": private
})
data = result["data"]["poeBotEdit"]
if data["status"] != "success":
raise RuntimeError(
f"Poe returned an error while trying to edit a bot: {data['status']}")
self.get_bots()
return data
load_queries() load_queries()

View File

@ -0,0 +1,73 @@
mutation CreateBotMain_poeBotCreate_Mutation(
$model: String!
$handle: String!
$prompt: String!
$isPromptPublic: Boolean!
$introduction: String!
$description: String!
$profilePictureUrl: String
$apiUrl: String
$apiKey: String
$isApiBot: Boolean
$hasLinkification: Boolean
$hasMarkdownRendering: Boolean
$hasSuggestedReplies: Boolean
$isPrivateBot: Boolean
) {
poeBotCreate(model: $model, handle: $handle, promptPlaintext: $prompt, isPromptPublic: $isPromptPublic, introduction: $introduction, description: $description, profilePicture: $profilePictureUrl, apiUrl: $apiUrl, apiKey: $apiKey, isApiBot: $isApiBot, hasLinkification: $hasLinkification, hasMarkdownRendering: $hasMarkdownRendering, hasSuggestedReplies: $hasSuggestedReplies, isPrivateBot: $isPrivateBot) {
status
bot {
id
...BotHeader_bot
}
}
}
fragment BotHeader_bot on Bot {
displayName
messageLimit {
dailyLimit
}
...BotImage_bot
...BotLink_bot
...IdAnnotation_node
...botHelpers_useViewerCanAccessPrivateBot
...botHelpers_useDeletion_bot
}
fragment BotImage_bot on Bot {
displayName
...botHelpers_useDeletion_bot
...BotImage_useProfileImage_bot
}
fragment BotImage_useProfileImage_bot on Bot {
image {
__typename
... on LocalBotImage {
localName
}
... on UrlBotImage {
url
}
}
...botHelpers_useDeletion_bot
}
fragment BotLink_bot on Bot {
displayName
}
fragment IdAnnotation_node on Node {
__isNode: __typename
id
}
fragment botHelpers_useDeletion_bot on Bot {
deletionState
}
fragment botHelpers_useViewerCanAccessPrivateBot on Bot {
isPrivateBot
viewerIsCreator
}