Comments (3)
Here is the py 3.7 source code that I use
import json
import time
import requests
import random
from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
from bs4 import BeautifulSoup
from websocket import WebSocketApp
from uuid import uuid4
from threading import Thread
def souper(x):
return BeautifulSoup(x, 'lxml')
class Emailnator:
def init(self, headers, cookies, domain=False, plus=False, dot=True, google_mail=False):
self.inbox = []
self.inbox_ads = []
self.s = requests.Session()
self.s.headers.update(headers)
self.s.cookies.update(cookies)
data = {'email': []}
if domain:
data['email'].append('domain')
if plus:
data['email'].append('plusGmail')
if dot:
data['email'].append('dotGmail')
if google_mail:
data['email'].append('googleMail')
response = self.s.post('https://www.emailnator.com/generate-email', json=data).json()
self.email = response['email'][0]
for ads in self.s.post('https://www.emailnator.com/message-list', json={'email': self.email}).json()['messageData']:
self.inbox_ads.append(ads['messageID'])
def reload(self, wait=False, retry_timeout=5):
self.new_msgs = []
while True:
for msg in self.s.post('https://www.emailnator.com/message-list', json={'email': self.email}).json()['messageData']:
if msg['messageID'] not in self.inbox_ads and msg not in self.inbox:
self.new_msgs.append(msg)
if wait and not self.new_msgs:
time.sleep(retry_timeout)
else:
break
self.inbox += self.new_msgs
return self.new_msgs
def open(self, msg_id):
return self.s.post('https://www.emailnator.com/message-list', json={'email': self.email, 'messageID': msg_id}).text
class Client:
def init(self, headers, cookies):
self.session = requests.Session()
self.session.headers.update(headers)
self.session.cookies.update(cookies)
self.session.get(f'https://www.perplexity.ai/search/{str(uuid4())}')
self.t = format(random.getrandbits(32), '08x')
self.sid = json.loads(self.session.get(f'https://www.perplexity.ai/socket.io/?EIO=4&transport=polling&t={self.t}').text[1:])['sid']
self.frontend_uuid = str(uuid4())
self.frontend_session_id = str(uuid4())
self._last_answer = None
self._last_file_upload_info = None
self.copilot = 0
self.file_upload = 0
self.n = 1
assert self.session.post(f'https://www.perplexity.ai/socket.io/?EIO=4&transport=polling&t={self.t}&sid={self.sid}', data='40{"jwt":"anonymous-ask-user"}').text == 'OK'
self.ws = WebSocketApp(
url=f'wss://www.perplexity.ai/socket.io/?EIO=4&transport=websocket&sid={self.sid}',
cookie='; '.join([f'{x}={y}' for x, y in self.session.cookies.get_dict().items()]),
on_open=lambda ws: ws.send('2probe'),
on_message=self.on_message,
on_error=lambda ws, err: print(f'Error: {err}'),
)
Thread(target=self.ws.run_forever).start()
time.sleep(1)
def create_account(self, headers, cookies):
emailnator_cli = Emailnator(headers, cookies, dot=False, google_mail=True)
resp = self.session.post('https://www.perplexity.ai/api/auth/signin/email', data={
'email': emailnator_cli.email,
'csrfToken': self.session.cookies.get_dict()['next-auth.csrf-token'].split('%')[0],
'callbackUrl': 'https://www.perplexity.ai/',
'json': 'true',
})
if resp.ok:
new_msgs = emailnator_cli.reload(wait=True)
new_account_link = souper(emailnator_cli.open(new_msgs[0]['messageID'])).select('a')[1].get('href')
self.session.get(new_account_link)
self.session.get('https://www.perplexity.ai/')
self.copilot = 5
self.file_upload = 3
self.ws.close()
self.t = format(random.getrandbits(32), '08x')
self.sid = json.loads(self.session.get(f'https://www.perplexity.ai/socket.io/?EIO=4&transport=polling&t={self.t}').text[1:])['sid']
assert self.session.post(f'https://www.perplexity.ai/socket.io/?EIO=4&transport=polling&t={self.t}&sid={self.sid}', data='40{"jwt":"anonymous-ask-user"}').text == 'OK'
self.ws = WebSocketApp(
url=f'wss://www.perplexity.ai/socket.io/?EIO=4&transport=websocket&sid={self.sid}',
cookie='; '.join([f'{x}={y}' for x, y in self.session.cookies.get_dict().items()]),
on_open=lambda ws: ws.send('2probe'),
on_message=self.on_message,
on_error=lambda ws, err: print(f'Error: {err}'),
)
Thread(target=self.ws.run_forever).start()
time.sleep(1)
return True
def on_message(self, ws, message):
if message == '2':
ws.send('3')
elif message == '3probe':
ws.send('5')
if message.startswith(str(430 + self.n)):
response = json.loads(message[3:])[0]
if 'text' in response:
response['text'] = json.loads(response['text'])
self._last_answer = response
else:
self._last_file_upload_info = response
def search(self, query, mode='concise', focus='internet', file=None):
assert mode in ['concise', 'copilot'], 'Search modes --> ["concise", "copilot"]'
assert focus in ['internet', 'scholar', 'writing', 'wolfram', 'youtube', 'reddit', 'wikipedia'], 'Search focus modes --> ["internet", "scholar", "writing", "wolfram", "youtube", "reddit", "wikipedia"]'
assert self.copilot > 0 if mode == 'copilot' else True, 'You have used all of your copilots'
assert self.file_upload > 0 if file else True, 'You have used all of your file uploads'
self.copilot = self.copilot - 1 if mode == 'copilot' else self.copilot
self.file_upload = self.file_upload - 1 if file else self.file_upload
self.n += 1
self._last_answer = None
self._last_file_upload_info = None
if file:
self.ws.send(f'{420 + self.n}' + json.dumps([
'get_upload_url',
{
'version': '2.0',
'source': 'default',
'content_type': {'txt': 'text/plain', 'pdf': 'application/pdf'}[file[1]]
}
]))
while not self._last_file_upload_info:
pass
if not self._last_file_upload_info['success']:
raise Exception('File upload error', self._last_file_upload_info)
monitor = MultipartEncoderMonitor(MultipartEncoder(fields={
**self._last_file_upload_info['fields'],
'file': ('myfile', file[0], {'txt': 'text/plain', 'pdf': 'application/pdf'}[file[1]])
}))
upload_resp = requests.post(self._last_file_upload_info['url'], data=monitor, headers={'Content-Type': monitor.content_type})
if not upload_resp.ok:
raise Exception('File upload error', upload_resp)
uploaded_file = self._last_file_upload_info['url'] + self._last_file_upload_info['fields']['key'].replace('${filename}', 'myfile')
self.ws.send(f'{420 + self.n}' + json.dumps([
'perplexity_ask',
query,
{
'attachments': [uploaded_file],
'version': '2.0',
'source': 'default',
'mode': mode,
'last_backend_uuid': None,
'read_write_token': '',
'conversational_enabled': True,
'frontend_session_id': self.frontend_session_id,
'search_focus': focus,
'frontend_uuid': self.frontend_uuid,
'gpt4': False,
'language': 'en-US',
}
]))
else:
self.ws.send(f'{420 + self.n}' + json.dumps([
'perplexity_ask',
query,
{
'version': '2.0',
'source': 'default',
'mode': mode,
'last_backend_uuid': None,
'read_write_token': '',
'conversational_enabled': True,
'frontend_session_id': self.frontend_session_id,
'search_focus': focus,
'frontend_uuid': self.frontend_uuid,
'gpt4': False,
'language': 'en-US',
}
]))
while not self._last_answer:
pass
return self._last_answer
from perplexity-ai.
Never tried in python 3.7 but it should work in python 3.7. 403 (Forbidden) status code means your cookies or headers are not correct or expired. Also you don't need to edit codes to run it in python 3.7. Just tested it yesterday and works like charm (im using python 3.11.3).
Edit: Tested it again and not working, working on a fix.
from perplexity-ai.
Fixed with new repository update.
from perplexity-ai.
Related Issues (20)
- Handshake status 403 Forbidden HOT 2
- Wasn't able to run both versions 'File upload error' & asyncio.run() cannot be called from a running event loop (Solved) New issue : Expecting value: line 1 column 1 (char 0) HOT 4
- Error: Handshake status 400 Bad Request HOT 2
- JSONDecodeError: Expecting value: line 1 column 1 (char 0) HOT 2
- Unable to initialize Client class HOT 6
- Exception has occurred: WebSocketConnectionClosedException socket is already closed. HOT 3
- Follow-up query HOT 1
- File upload in concise mode HOT 2
- Followup after file upload losing context HOT 2
- Not terminating? HOT 1
- Invalid cookie HOT 1
- Cookies not working HOT 11
- issue with public url in s3
- Can't seems to contact with Perplexity HOT 2
- ModuleNotFoundError: No module named 'perplexity' HOT 3
- AssertionError at line 99 in file perplexity.py HOT 2
- Perplexity account creating error: <Response [400]> HOT 5
- "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)" when running labs_cli.ask HOT 10
- How to use claude2/gpt4 HOT 4
- static t token in websocket requests causing issues? HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from perplexity-ai.