Skip to content

Instantly share code, notes, and snippets.

@ackviz
Last active August 9, 2023 03:43
Show Gist options
  • Save ackviz/8e97f35f84ec77d4e527f719e3729390 to your computer and use it in GitHub Desktop.
Save ackviz/8e97f35f84ec77d4e527f719e3729390 to your computer and use it in GitHub Desktop.
cli to interact with https://nat.dev/
#!/usr/bin/python3
# Script Author: @chaignc
# https://gist.github.com/ackviz/8e97f35f84ec77d4e527f719e3729390
import sys
import clize
import re
import json
from collections import defaultdict
import requests
from your_secret_config import TOKEN
regex_split = re.compile(r"(event:status|event:infer)\n")
# TOKEN = 'put your JWT token here that you can get using your browser dev tools'
start_index = len("[INITIALIZING]")
end_index = len("[COMPLETED]")
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Authorization': f'Bearer {TOKEN}',
'Content-Type': 'text/plain;charset=UTF-8',
'Origin': 'https://nat.dev',
'DNT': '1',
'Connection': 'keep-alive',
'Referer': 'https://nat.dev/compare',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
}
data = {
"prompt": "say something",
"models": [
# {
# "name": "anthropic:claude",
# "tag": "anthropic:claude",
# "provider": "anthropic",
# "parameters": {
# "temperature": 0,
# "maximum_length": 50,
# "top_p": 1,
# "top_k": 1,
# "presence_penalty": 1,
# "frequency_penalty": 0.08,
# "stop_sequences": []
# }
# },
{
"name": "openai:gpt-4",
"tag": "openai:gpt-4",
"provider": "openai",
"parameters": {
"temperature": 0,
"maximum_length": 2024,
"top_p": 1,
"presence_penalty": 0,
"frequency_penalty": 0,
"stop_sequences": []
}
},
# {
# "name": "openai:gpt-3.5-turbo",
# "tag": "openai:gpt-3.5-turbo",
# "provider": "openai",
# "parameters": {
# "temperature": 0,
# "maximum_length": 1024,
# "top_p": 1,
# "presence_penalty": 0,
# "frequency_penalty": 0,
# "stop_sequences": []
# }
# }
]
}
def request_and_parse(prompt=None):
if prompt is None:
print("Please enter your prompt:")
prompt = sys.stdin.readlines()
prompt = "".join(prompt)
print("[+] Sending request to server")
data["prompt"] = prompt
response = requests.post('https://nat.dev/api/stream', headers=headers, data=json.dumps(data))
parse_and_concat_model_output(response.text)
def parse_events(input_data):
for event in regex_split.split(input_data):
print(".", end="", flush=True)
if event in ["event:status", "event:infer", ""]:
continue
if event.startswith("data:"):
event = event[5:]
yield event
else:
raise Exception("Unexpected output form server")
print()
def parse_and_concat_model_output(file_name):
models_output = defaultdict(str)
for event in parse_events(file_name):
event = json.loads(event)
models_output[event["model_name"]] += event["message"]
if len(models_output) == 0:
print("No output")
for model_name, message in models_output.items():
print(" {} ".rjust(40, "=").format(model_name).ljust(80, "="))
model_output = message[start_index:-end_index]
with open(f"{model_name}.html", "w") as f:
f.write(model_output)
print(model_output)
print()
if __name__ == '__main__':
clize.run(request_and_parse)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment