Created
July 30, 2023 09:48
-
-
Save ImBIOS/2d6c963a93d67dc52e22ac97f0d52641 to your computer and use it in GitHub Desktop.
Script to unlock GPT-4 in OpenAI API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use pipenv to auto load OPENAI KEY | |
import sys | |
import time | |
import json | |
import signal | |
import openai | |
# Constants | |
TOKENS_PER_MINUTE = 90000 - 100 # 90000 tokens per minute - 100 for safety | |
REQUESTS_PER_MINUTE = 3500 - 100 # 3500 requests per minute - 100 for safety | |
INPUT_COST = 0.0015 / 1000 # Costs per token | |
OUTPUT_COST = 0.002 / 1000 # Costs per token | |
BUDGET = 1.01 # USD budget | |
MAX_TOKENS = 4096 - 10 # Maximum tokens for gpt-3.5-turbo - 10 for safety | |
# File paths | |
COST_FILE_PATH = "total_cost.json" | |
messages = [ | |
{"role": "system", "content": "Generate a poem about TypeScript:"}, | |
{ | |
"role": "user", | |
"content": """ | |
In the realm of code, where logic unfolds, | |
A language emerged, brave and bold. | |
It's TypeScript, they say, with a voice of glee, | |
A superset of JavaScript, as strong as can be. | |
It came from the mind of Anders Hejlsberg, | |
With static types, it purges the scourge. | |
With optional typing and interfaces too, | |
For a JavaScript dev, it's something new. | |
The bugs that lurk in dynamic code, | |
Are caught at compile time, lightening the load. | |
No more undefined is not a function, | |
TypeScript brings order to the junction. | |
The code is clear, no more guess, | |
What types do function arguments possess? | |
With TypeScript, it's clear as day, | |
Helping developers keep bugs at bay. | |
The beast of complexity, it tames, | |
No more playing JavaScript's guessing games. | |
For large scale apps, it's a boon, | |
With TypeScript's tune, they all swoon. | |
In the world of front-end, and Node.js too, | |
TypeScript's influence continues to accrue. | |
With Angular, Vue, and React's might, | |
TypeScript shines in the developer's night. | |
Transpiled down to JavaScript, so fine, | |
Ensuring your code will always align. | |
To older versions, it can descend, | |
Browser compatibility, it does tend. | |
Generics and tuples, so neat, | |
Making your codebase oh so fleet. | |
Enums and namespaces, so divine, | |
In TypeScript's world, we do align. | |
TypeScript, TypeScript, you're a delight, | |
In the world of code, you're a bright light. | |
With your static types and clear intent, | |
My love for you is fervent, never spent. | |
TypeScript, TypeScript, in you we trust, | |
You make our code robust. | |
From the browser to the server, you're there, | |
TypeScript, TypeScript, beyond compare. | |
A toast to TypeScript, long may you reign, | |
In the world of code, you alleviate pain. | |
To the developers, you're a trusted friend, | |
TypeScript, TypeScript, on you we depend. | |
""", | |
}, | |
] | |
def calculate_cost(prompt_tokens, completion_tokens): | |
""" | |
Function to calculate the cost based on the number of prompt and completion tokens. | |
""" | |
return prompt_tokens * INPUT_COST + completion_tokens * OUTPUT_COST | |
def make_request(): | |
""" | |
Function to make a request to the OpenAI API and return the response. | |
""" | |
return openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=messages, | |
) | |
def load_total_cost(): | |
""" | |
Function to load the total cost from a file. | |
""" | |
try: | |
with open(COST_FILE_PATH, "r") as f: | |
total_cost = json.load(f)["total_cost"] | |
except FileNotFoundError: | |
total_cost = 0.0 | |
return total_cost | |
def save_total_cost(total_cost): | |
""" | |
Function to save the total cost to a file. | |
""" | |
with open(COST_FILE_PATH, "w") as f: | |
json.dump({"total_cost": total_cost}, f) | |
def signal_handler(sig, frame): | |
print("You pressed Ctrl+C!") | |
save_total_cost(total_cost) | |
sys.exit(0) | |
signal.signal(signal.SIGINT, signal_handler) | |
def main(): | |
global total_cost # Make total_cost accessible globally so it can be saved upon interrupt | |
total_cost = load_total_cost() | |
while total_cost < BUDGET: | |
try: | |
response = make_request() | |
prompt_tokens = response["usage"]["prompt_tokens"] | |
completion_tokens = response["usage"]["completion_tokens"] | |
round_cost = calculate_cost(prompt_tokens, completion_tokens) | |
# Check if this round would exceed budget | |
if total_cost + round_cost > BUDGET: | |
print("Budget exceeded. Stopping.") | |
break | |
total_cost += round_cost | |
print(f"Total cost so far: {total_cost:.4f}") | |
# Sleep to respect rate limits | |
time.sleep(60 / REQUESTS_PER_MINUTE) | |
except Exception as e: | |
print(f"An error occurred: {e}", file=sys.stderr) | |
print("Retrying in 60 seconds...") | |
time.sleep(60) | |
continue | |
save_total_cost(total_cost) | |
print(f"Total cost: {total_cost}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment