Code and Life

Programming, electronics and other cool tech stuff

Supported by

Supported by Picotech

Stop Writing Scripts: Create and automatically run ChatGPT generated Python code

I previously covered how to run your own ChatGPT script with Python and Golang. But what if you want to create a script that automatically runs the ChatGPT generated code? That is what I will cover in this post. The idea is really simple:

  1. Create a script that asks for user input
  2. Pass the input to ChatGPT
  3. Run the ChatGPT generated code

NOTE: Please read the caveats at the end of the post before using this!

Calling The OpenAI API

First step is simple, just call the OpenAI API with the user input. If "-v" is given as the first argument, print the raw answer and usage statistics as well.

#!/usr/bin/python3

import openai
import sys

openai.api_key = 'sk-xxx'

verbose = sys.argv[1] == '-v'
prompt = ' '.join(sys.argv[2 if verbose else 1:])

resp = openai.ChatCompletion.create(
  model="gpt-3.5-turbo",
  messages=[
        {"role": "system", "content": "You are Python code generator. Answer with just the Python code."},
        {"role": "user", "content": prompt},
    ]
)

data = resp['choices'][0]['message']['content']

if verbose: print(data, 'Usage was:', resp['usage'], sep='\n')

Parsing the Code From Response

A rather simplistic implementation looks for set of start tokens and end tokens and returns the code between them. This is not perfect, but it works as long as the ChatGPT response does not contain multiple code blocks.

# Extract lines of code from the response tagged with ``` or ```python
lines = []
ok_start = ['```', '```python', '```py', '```python3', '```py3']
started = False
for line in data.splitlines():
    if not started:
        if line.strip() in ok_start:
            started = True
    else:
        if line.strip() == '```': break
        lines.append(line)

Running The Code

The code is then written to a temporary file and executed. After running, the file is deleted.

import os
import tempfile

# Create a temporary file
with tempfile.NamedTemporaryFile(mode='w', delete=False) as tf:
    tf.write("#!/usr/bin/env python3\n")

    # Write lines to the file
    for line in lines:
        tf.write(line + '\n')

# Make the file executable
os.chmod(tf.name, 0o755)

# Run the file with python3
os.system(tf.name)

# Delete the file
os.unlink(tf.name)

Trying It Out

The whole script is available here for your convenience. If you are on Linux, you can chmod +x the script and run it directly. Otherwise, you can run it with python3 pyai.py:

$ pyai -v simple hello world app
print("Hello, world!")
Usage was:
{
  "completion_tokens": 6,
  "prompt_tokens": 30,
  "total_tokens": 36
}
Hello, world!

Omitting the -v argument will only run the generated code:

$ pyai print out 10 first primes
2
3
5
7
11
13
17
19
23
29
$ pyai calculate sha1 checksum of file pyai
SHA1 checksum of pyai: db5ab334ca2af7508460d5ade8dac7fedd48bcf0
$ sha1sum pyai
db5ab334ca2af7508460d5ade8dac7fedd48bcf0  pyai

Python has pretty powerful libraries, so you can access the web as well:

$ pyai print out longest h1 tag content text from https://codeandlife.com
Using a Soundcard as an Oscilloscope to Decode 433 MHz Smart Power Plug Remote Control Signals
$ # If you want to know what the code (and usage) was, use -v in the beginning
$ pyai -v print out longest h1 tag content text from https://codeandlife.com
```python
import requests
from bs4 import BeautifulSoup

url = "https://codeandlife.com"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")

h1_list = soup.find_all("h1")
longest_h1 = max(h1_list, key=lambda x: len(x.text))

print(longest_h1.text.strip())
```
Usage was:
{
  "completion_tokens": 76,
  "prompt_tokens": 41,
  "total_tokens": 117
}
Using a Soundcard as an Oscilloscope to Decode 433 MHz Smart Power Plug Remote Control Signals

Yes you can read files too:

$ pyai print out contents of /etc/passwd
# And the contents of /etc/passwd come here :D

$ pyai read /etc/passwd, split by colon and print the largest 3rd entry value
65534

Conclusions and Caveats

While the code is simple and has many limitations, it is staggeringly powerful. You can do pretty much anything you can do with Python with this. But the downside is it's like the "I'm feeling lucky" version of scripting. You don't know what the code is going to do. You can't even see the code before running it. So, use this with caution! Potential drawbacks may include, but are not limited to:

  1. Racking up your OpenAI API usage and costing you money
  2. ChatGPT getting it wrong and the code not working
  3. Code working but doing something you didn't expect
  4. Overwriting (important) files
  5. Getting really malicious code that does something bad

Currently code injection to LLMs is pretty hard, but it is not unthinkable that someone will find a way to do it. So, please be careful when using this. I am not responsible for any damage caused by this script!