t.me/xtekky commited on
Commit
05f3695
1 Parent(s): 3388d70

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

Browse files
quora/api.py CHANGED
@@ -1,14 +1,14 @@
1
  # This file was taken from the repository poe-api https://github.com/ading2210/poe-api and is unmodified
2
  # This file is licensed under the GNU GPL v3 and written by @ading2210
3
 
4
- # license:
5
  # ading2210/poe-api: a reverse engineered Python API wrapepr for Quora's Poe
6
  # Copyright (C) 2023 ading2210
7
 
8
  # This program is free software: you can redistribute it and/or modify
9
  # it under the terms of the GNU General Public License as published by
10
  # the Free Software Foundation, either version 3 of the License, or
11
- # (at your option) any later version.
12
 
13
  # This program is distributed in the hope that it will be useful,
14
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -28,13 +28,16 @@ import queue
28
  import threading
29
  import traceback
30
  import hashlib
 
 
 
31
  import websocket
32
  from pathlib import Path
33
  from urllib.parse import urlparse
34
 
35
 
36
  parent_path = Path(__file__).resolve().parent
37
- queries_path = parent_path / "graphql"
38
  queries = {}
39
 
40
  logging.basicConfig()
@@ -80,6 +83,10 @@ class Client:
80
  def __init__(self, token, proxy=None):
81
  self.proxy = proxy
82
  self.session = requests.Session()
 
 
 
 
83
 
84
  if proxy:
85
  self.session.proxies = {
@@ -143,12 +150,12 @@ class Client:
143
  if overwrite_vars:
144
  self.formkey = self.extract_formkey(r.text)
145
  self.viewer = next_data["props"]["pageProps"]["payload"]["viewer"]
 
146
 
147
  return next_data
148
 
149
  def get_bot(self, display_name):
150
  url = f'https://poe.com/_next/data/{self.next_data["buildId"]}/{display_name}.json'
151
- logger.info("Downloading "+url)
152
 
153
  r = request_with_retries(self.session.get, url)
154
 
@@ -156,8 +163,9 @@ class Client:
156
  return chat_data
157
 
158
  def get_bots(self, download_next_data=True):
 
159
  if download_next_data:
160
- next_data = self.get_next_data()
161
  else:
162
  next_data = self.next_data
163
 
@@ -165,11 +173,23 @@ class Client:
165
  raise RuntimeError("Invalid token or no bots are available.")
166
  bot_list = self.viewer["availableBots"]
167
 
 
168
  bots = {}
169
- for bot in bot_list:
 
170
  chat_data = self.get_bot(bot["displayName"])
171
  bots[chat_data["defaultBotObject"]["nickname"]] = chat_data
172
 
 
 
 
 
 
 
 
 
 
 
173
  self.bots = bots
174
  self.bot_names = self.get_bot_names()
175
  return bots
@@ -181,6 +201,10 @@ class Client:
181
  bot_names[bot_nickname] = bot_obj["displayName"]
182
  return bot_names
183
 
 
 
 
 
184
  def get_channel_data(self, channel=None):
185
  logger.info("Downloading channel data...")
186
  r = request_with_retries(self.session.get, self.settings_url)
@@ -447,5 +471,62 @@ class Client:
447
  last_messages = self.get_message_history(chatbot, count=50)[::-1]
448
  logger.info(f"No more messages left to delete.")
449
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
 
451
  load_queries()
 
1
  # This file was taken from the repository poe-api https://github.com/ading2210/poe-api and is unmodified
2
  # This file is licensed under the GNU GPL v3 and written by @ading2210
3
 
4
+ # license:
5
  # ading2210/poe-api: a reverse engineered Python API wrapepr for Quora's Poe
6
  # Copyright (C) 2023 ading2210
7
 
8
  # This program is free software: you can redistribute it and/or modify
9
  # it under the terms of the GNU General Public License as published by
10
  # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
 
13
  # This program is distributed in the hope that it will be useful,
14
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
 
28
  import threading
29
  import traceback
30
  import hashlib
31
+ import string
32
+ import random
33
+ import requests.adapters
34
  import websocket
35
  from pathlib import Path
36
  from urllib.parse import urlparse
37
 
38
 
39
  parent_path = Path(__file__).resolve().parent
40
+ queries_path = parent_path / "poe_graphql"
41
  queries = {}
42
 
43
  logging.basicConfig()
 
83
  def __init__(self, token, proxy=None):
84
  self.proxy = proxy
85
  self.session = requests.Session()
86
+ self.adapter = requests.adapters.HTTPAdapter(
87
+ pool_connections=100, pool_maxsize=100)
88
+ self.session.mount("http://", self.adapter)
89
+ self.session.mount("https://", self.adapter)
90
 
91
  if proxy:
92
  self.session.proxies = {
 
150
  if overwrite_vars:
151
  self.formkey = self.extract_formkey(r.text)
152
  self.viewer = next_data["props"]["pageProps"]["payload"]["viewer"]
153
+ self.next_data = next_data
154
 
155
  return next_data
156
 
157
  def get_bot(self, display_name):
158
  url = f'https://poe.com/_next/data/{self.next_data["buildId"]}/{display_name}.json'
 
159
 
160
  r = request_with_retries(self.session.get, url)
161
 
 
163
  return chat_data
164
 
165
  def get_bots(self, download_next_data=True):
166
+ logger.info("Downloading all bots...")
167
  if download_next_data:
168
+ next_data = self.get_next_data(overwrite_vars=True)
169
  else:
170
  next_data = self.next_data
171
 
 
173
  raise RuntimeError("Invalid token or no bots are available.")
174
  bot_list = self.viewer["availableBots"]
175
 
176
+ threads = []
177
  bots = {}
178
+
179
+ def get_bot_thread(bot):
180
  chat_data = self.get_bot(bot["displayName"])
181
  bots[chat_data["defaultBotObject"]["nickname"]] = chat_data
182
 
183
+ for bot in bot_list:
184
+ thread = threading.Thread(
185
+ target=get_bot_thread, args=(bot,), daemon=True)
186
+ threads.append(thread)
187
+
188
+ for thread in threads:
189
+ thread.start()
190
+ for thread in threads:
191
+ thread.join()
192
+
193
  self.bots = bots
194
  self.bot_names = self.get_bot_names()
195
  return bots
 
201
  bot_names[bot_nickname] = bot_obj["displayName"]
202
  return bot_names
203
 
204
+ def get_remaining_messages(self, chatbot):
205
+ chat_data = self.get_bot(self.bot_names[chatbot])
206
+ return chat_data["defaultBotObject"]["messageLimit"]["numMessagesRemaining"]
207
+
208
  def get_channel_data(self, channel=None):
209
  logger.info("Downloading channel data...")
210
  r = request_with_retries(self.session.get, self.settings_url)
 
471
  last_messages = self.get_message_history(chatbot, count=50)[::-1]
472
  logger.info(f"No more messages left to delete.")
473
 
474
+ def create_bot(self, handle, prompt="", base_model="chinchilla", description="",
475
+ intro_message="", api_key=None, api_bot=False, api_url=None,
476
+ prompt_public=True, pfp_url=None, linkification=False,
477
+ markdown_rendering=True, suggested_replies=False, private=False):
478
+ result = self.send_query("PoeBotCreateMutation", {
479
+ "model": base_model,
480
+ "handle": handle,
481
+ "prompt": prompt,
482
+ "isPromptPublic": prompt_public,
483
+ "introduction": intro_message,
484
+ "description": description,
485
+ "profilePictureUrl": pfp_url,
486
+ "apiUrl": api_url,
487
+ "apiKey": api_key,
488
+ "isApiBot": api_bot,
489
+ "hasLinkification": linkification,
490
+ "hasMarkdownRendering": markdown_rendering,
491
+ "hasSuggestedReplies": suggested_replies,
492
+ "isPrivateBot": private
493
+ })
494
+
495
+ data = result["data"]["poeBotCreate"]
496
+ if data["status"] != "success":
497
+ raise RuntimeError(
498
+ f"Poe returned an error while trying to create a bot: {data['status']}")
499
+ self.get_bots()
500
+ return data
501
+
502
+ def edit_bot(self, bot_id, handle, prompt="", base_model="chinchilla", description="",
503
+ intro_message="", api_key=None, api_url=None, private=False,
504
+ prompt_public=True, pfp_url=None, linkification=False,
505
+ markdown_rendering=True, suggested_replies=False):
506
+
507
+ result = self.send_query("PoeBotEditMutation", {
508
+ "baseBot": base_model,
509
+ "botId": bot_id,
510
+ "handle": handle,
511
+ "prompt": prompt,
512
+ "isPromptPublic": prompt_public,
513
+ "introduction": intro_message,
514
+ "description": description,
515
+ "profilePictureUrl": pfp_url,
516
+ "apiUrl": api_url,
517
+ "apiKey": api_key,
518
+ "hasLinkification": linkification,
519
+ "hasMarkdownRendering": markdown_rendering,
520
+ "hasSuggestedReplies": suggested_replies,
521
+ "isPrivateBot": private
522
+ })
523
+
524
+ data = result["data"]["poeBotEdit"]
525
+ if data["status"] != "success":
526
+ raise RuntimeError(
527
+ f"Poe returned an error while trying to edit a bot: {data['status']}")
528
+ self.get_bots()
529
+ return data
530
+
531
 
532
  load_queries()
quora/graphql/PoeBotCreateMutation.graphql ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mutation CreateBotMain_poeBotCreate_Mutation(
2
+ $model: String!
3
+ $handle: String!
4
+ $prompt: String!
5
+ $isPromptPublic: Boolean!
6
+ $introduction: String!
7
+ $description: String!
8
+ $profilePictureUrl: String
9
+ $apiUrl: String
10
+ $apiKey: String
11
+ $isApiBot: Boolean
12
+ $hasLinkification: Boolean
13
+ $hasMarkdownRendering: Boolean
14
+ $hasSuggestedReplies: Boolean
15
+ $isPrivateBot: Boolean
16
+ ) {
17
+ 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) {
18
+ status
19
+ bot {
20
+ id
21
+ ...BotHeader_bot
22
+ }
23
+ }
24
+ }
25
+
26
+ fragment BotHeader_bot on Bot {
27
+ displayName
28
+ messageLimit {
29
+ dailyLimit
30
+ }
31
+ ...BotImage_bot
32
+ ...BotLink_bot
33
+ ...IdAnnotation_node
34
+ ...botHelpers_useViewerCanAccessPrivateBot
35
+ ...botHelpers_useDeletion_bot
36
+ }
37
+
38
+ fragment BotImage_bot on Bot {
39
+ displayName
40
+ ...botHelpers_useDeletion_bot
41
+ ...BotImage_useProfileImage_bot
42
+ }
43
+
44
+ fragment BotImage_useProfileImage_bot on Bot {
45
+ image {
46
+ __typename
47
+ ... on LocalBotImage {
48
+ localName
49
+ }
50
+ ... on UrlBotImage {
51
+ url
52
+ }
53
+ }
54
+ ...botHelpers_useDeletion_bot
55
+ }
56
+
57
+ fragment BotLink_bot on Bot {
58
+ displayName
59
+ }
60
+
61
+ fragment IdAnnotation_node on Node {
62
+ __isNode: __typename
63
+ id
64
+ }
65
+
66
+ fragment botHelpers_useDeletion_bot on Bot {
67
+ deletionState
68
+ }
69
+
70
+ fragment botHelpers_useViewerCanAccessPrivateBot on Bot {
71
+ isPrivateBot
72
+ viewerIsCreator
73
+ }