Merge pull request #504 from MIDORIBIN/main

Support for new authentication methods in forefront
pull/392/merge
t.me/xtekky 1 year ago committed by GitHub
commit 46bc0e99a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,15 +2,18 @@
```python ```python
from gpt4free import forefront from gpt4free import forefront
# create an account # create an account
token = forefront.Account.create(logging=False) account_data = forefront.Account.create(logging=False)
print(token)
# get a response # get a response
for response in forefront.StreamingCompletion.create( for response in forefront.StreamingCompletion.create(
token=token, account_data=account_data,
prompt='hello world', prompt='hello world',
model='gpt-4' model='gpt-4'
): ):
print(response.choices[0].text, end='') print(response.choices[0].text, end='')
print("") print("")
``` ```

@ -1,20 +1,24 @@
import hashlib
from base64 import b64encode
from json import loads from json import loads
from re import findall from re import findall
from time import time, sleep from time import time, sleep
from typing import Generator, Optional from typing import Generator, Optional
from uuid import uuid4 from uuid import uuid4
from mailgw_temporary_email import Email from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from fake_useragent import UserAgent from fake_useragent import UserAgent
from mailgw_temporary_email import Email
from requests import post from requests import post
from tls_client import Session from tls_client import Session
from .typing import ForeFrontResponse from .typing import ForeFrontResponse, AccountData
class Account: class Account:
@staticmethod @staticmethod
def create(proxy: Optional[str] = None, logging: bool = False): def create(proxy: Optional[str] = None, logging: bool = False) -> AccountData:
proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else False proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else False
start = time() start = time()
@ -34,14 +38,13 @@ class Account:
'https://clerk.forefront.ai/v1/client/sign_ups?_clerk_js_version=4.38.4', 'https://clerk.forefront.ai/v1/client/sign_ups?_clerk_js_version=4.38.4',
data={'email_address': mail_address}, data={'email_address': mail_address},
) )
print(response.json()['response']['id'])
try: try:
trace_token = response.json()['response']['id'] trace_token = response.json()['response']['id']
if logging: if logging:
print(trace_token) print(trace_token)
except KeyError: except KeyError:
return 'Failed to create account!' raise RuntimeError('Failed to create account!')
response = client.post( response = client.post(
f'https://clerk.forefront.ai/v1/client/sign_ups/{trace_token}/prepare_verification?_clerk_js_version=4.38.4', f'https://clerk.forefront.ai/v1/client/sign_ups/{trace_token}/prepare_verification?_clerk_js_version=4.38.4',
@ -55,27 +58,26 @@ class Account:
print(response.text) print(response.text)
if 'sign_up_attempt' not in response.text: if 'sign_up_attempt' not in response.text:
return 'Failed to create account!' raise RuntimeError('Failed to create account!')
while True: while True:
sleep(5) sleep(5)
message_id = mail_client.message_list()[0]['id'] message_id = mail_client.message_list()[0]['id']
message = mail_client.message(message_id) message = mail_client.message(message_id)
verification_url = findall(r'https:\/\/clerk\.forefront\.ai\/v1\/verify\?token=\w.+', message["text"])[0]
new_message: Message = message
verification_url = findall(r'https:\/\/clerk\.forefront\.ai\/v1\/verify\?token=\w.+', new_message["text"])[0]
if verification_url: if verification_url:
break break
if logging: if logging:
print(verification_url) print(verification_url)
client.get(verification_url)
response = client.get(verification_url) response = client.get('https://clerk.forefront.ai/v1/client?_clerk_js_version=4.38.4').json()
session_data = response['response']['sessions'][0]
response = client.get('https://clerk.forefront.ai/v1/client?_clerk_js_version=4.38.4')
token = response.json()['response']['sessions'][0]['last_active_token']['jwt'] user_id = session_data['user']['id']
session_id = session_data['id']
token = session_data['last_active_token']['jwt']
with open('accounts.txt', 'a') as f: with open('accounts.txt', 'a') as f:
f.write(f'{mail_address}:{token}\n') f.write(f'{mail_address}:{token}\n')
@ -83,32 +85,32 @@ class Account:
if logging: if logging:
print(time() - start) print(time() - start)
return token return AccountData(token=token, user_id=user_id, session_id=session_id)
class StreamingCompletion: class StreamingCompletion:
@staticmethod @staticmethod
def create( def create(
token=None, prompt: str,
account_data: AccountData,
chat_id=None, chat_id=None,
prompt='',
action_type='new', action_type='new',
default_persona='607e41fe-95be-497e-8e97-010a59b2e2c0', # default default_persona='607e41fe-95be-497e-8e97-010a59b2e2c0', # default
model='gpt-4', model='gpt-4',
proxy=None proxy=None
) -> Generator[ForeFrontResponse, None, None]: ) -> Generator[ForeFrontResponse, None, None]:
if not token: token = account_data.token
raise Exception('Token is required!')
if not chat_id: if not chat_id:
chat_id = str(uuid4()) chat_id = str(uuid4())
proxies = { 'http': 'http://' + proxy, 'https': 'http://' + proxy } if proxy else None proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else None
base64_data = b64encode((account_data.user_id + default_persona + chat_id).encode()).decode()
encrypted_signature = StreamingCompletion.__encrypt(base64_data, account_data.session_id)
headers = { headers = {
'authority': 'chat-server.tenant-forefront-default.knative.chi.coreweave.com', 'authority': 'chat-server.tenant-forefront-default.knative.chi.coreweave.com',
'accept': '*/*', 'accept': '*/*',
'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3', 'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
'authorization': 'Bearer ' + token,
'cache-control': 'no-cache', 'cache-control': 'no-cache',
'content-type': 'application/json', 'content-type': 'application/json',
'origin': 'https://chat.forefront.ai', 'origin': 'https://chat.forefront.ai',
@ -120,6 +122,8 @@ class StreamingCompletion:
'sec-fetch-dest': 'empty', 'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors', 'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site', 'sec-fetch-site': 'cross-site',
'authorization': f"Bearer {token}",
'X-Signature': encrypted_signature,
'user-agent': UserAgent().random, 'user-agent': UserAgent().random,
} }
@ -133,7 +137,7 @@ class StreamingCompletion:
} }
for chunk in post( for chunk in post(
'https://chat-server.tenant-forefront-default.knative.chi.coreweave.com/chat', 'https://streaming.tenant-forefront-default.knative.chi.coreweave.com/chat',
headers=headers, headers=headers,
proxies=proxies, proxies=proxies,
json=json_data, json=json_data,
@ -160,13 +164,28 @@ class StreamingCompletion:
} }
) )
@staticmethod
def __encrypt(data: str, key: str) -> str:
hash_key = hashlib.sha256(key.encode()).digest()
iv = get_random_bytes(16)
cipher = AES.new(hash_key, AES.MODE_CBC, iv)
encrypted_data = cipher.encrypt(StreamingCompletion.__pad_data(data.encode()))
return iv.hex() + encrypted_data.hex()
@staticmethod
def __pad_data(data: bytes) -> bytes:
block_size = AES.block_size
padding_size = block_size - len(data) % block_size
padding = bytes([padding_size] * padding_size)
return data + padding
class Completion: class Completion:
@staticmethod @staticmethod
def create( def create(
token=None, prompt: str,
account_data: AccountData,
chat_id=None, chat_id=None,
prompt='',
action_type='new', action_type='new',
default_persona='607e41fe-95be-497e-8e97-010a59b2e2c0', # default default_persona='607e41fe-95be-497e-8e97-010a59b2e2c0', # default
model='gpt-4', model='gpt-4',
@ -175,7 +194,7 @@ class Completion:
text = '' text = ''
final_response = None final_response = None
for response in StreamingCompletion.create( for response in StreamingCompletion.create(
token=token, account_data=account_data,
chat_id=chat_id, chat_id=chat_id,
prompt=prompt, prompt=prompt,
action_type=action_type, action_type=action_type,
@ -190,6 +209,6 @@ class Completion:
if final_response: if final_response:
final_response.text = text final_response.text = text
else: else:
raise Exception('Unable to get the response, Please try again') raise RuntimeError('Unable to get the response, Please try again')
return final_response return final_response

@ -24,3 +24,9 @@ class ForeFrontResponse(BaseModel):
choices: List[Choice] choices: List[Choice]
usage: Usage usage: Usage
text: str text: str
class AccountData(BaseModel):
token: str
user_id: str
session_id: str

@ -13,6 +13,6 @@ https://github.com/AI-Yash/st-chat/archive/refs/pull/24/head.zip
pydantic pydantic
pymailtm pymailtm
Levenshtein Levenshtein
xtempmail retrying
faker mailgw_temporary_email
retrying pycryptodome

Loading…
Cancel
Save