How ChatGPT's Codex has transformed the way I code
Security vulnerabilities... code refactoring... readability. Codex is changing the way I code my projects! 🤖
As a solo developer, I'm constantly finding new ways to improve the way I code. Recently, I've started using ChatGPT's Codex to achieve that.
Now, let's not get carried away here, it's not re-writing entire projects for me. I'm not letting it loose on new features or APIs, and the code it generates isn't going into production untested. However, what it is doing is reviewing my code for me. I'm asking it to check specifically for security vulnerabilities, performance issues, typos, and to suggest improvements.
How about I show you an example...
Codex Example
My "lists" app Marvelist relies on a REST API that is currently deployed in Azure, written in Python, and operates on Azure Functions.
Parts of this API server relies on a connection to a backend MySQL database.
I'd noticed recently that when my database server undergoes maintenance or failover, the connection can sometimes fail for a second or two. My current code logic didn't take this into account and just returned an HTTP 500 error when the database connection failed. This felt like a quick and easy task I could delegate to Codex to resolve.
After hooking the GitHub repository for the API server into Codex (and obviously disabling internet access), I fired the following prompt at it.
This repository is for an Azure Functions App, providing REST API services to a mobile app. Currently whenever the database times out (when connecting) an error 500 is produced. The database connection is configured from the [FILE NAME].py file, implement a retry logic.
And away it went...

It reviewed the contents of the database delegate Python file, found the function used to establish a connection to the database server, and then started to implement the retry logic.
Here's what it spat out, and the code I had wrote. (No judgements please).
My Code
@contextmanager
def get_connection():
conn = None
cursor = None
try:
# Get a connection from the pool
conn = mysql.connector.connect(**dbconfig)
cursor = conn.cursor(dictionary=True)
yield conn, cursor
except Exception as e:
logging.error(f"Database connection error: {e}")
raise
finally:
if cursor is not None:
cursor.close()
if conn is not None:
conn.close() # This returns the connection to the pool
Codex's Refactored Code
@contextmanager
def get_connection(max_retries: int = 3, base_delay: float = 1.0):
"""Context manager that returns a MySQL connection and cursor with retry logic.
Args:
max_retries: Number of times to retry the connection on failure.
base_delay: Initial delay (in seconds) before retrying; doubles on each retry.
"""
conn = None
cursor = None
attempt = 0
# Attempt to establish the connection with retries
while True:
try:
conn = mysql.connector.connect(**dbconfig)
cursor = conn.cursor(dictionary=True)
break
except mysql.connector.Error as e:
attempt += 1
if attempt >= max_retries:
logging.error(f"Database connection failed after {attempt} attempts: {e}")
raise
delay = base_delay * (2 ** (attempt - 1))
logging.warning(
f"Database connection failed (attempt {attempt}/{max_retries}). Retrying in {delay} seconds..."
)
time.sleep(delay)
try:
yield conn, cursor
finally:
if cursor is not None:
cursor.close()
if conn is not None:
conn.close() # This returns the connection to the pool
As you can see, given the right prompt, and the specifics I asked for, it implemented the retry logic I asked for. It didn't scrap and rewrite the entire thing; it took what I already had and found a way to compliment it.
I was satisfied with the code it had written. I reviewed it, sense-checked it, and thought "ok, I can see that working how I want it to work". With that, I requested Codex create a pull request for these changes.
Codex then created a new branch in my repository, and a pull request so that the changes could be merged into my main production branch.

With Codex creating a new branch for me, I could very easily switch over to this branch in my local development environment, spin up the server with the changes, and do some thorough testing of the new code. Verifying what happens in the event of a network outage, DNS resolution failures, etc.
The code worked exactly how I wanted it to. I was impressed.
Once I was satisfied my testing was complete, and I approved of the code changes, I merged and closed the pull request and deleted the Codex-created branch.
This commit to the main production branch triggered my continuous integration flows in GitHub Actions and deployed the latest code changes directly to Azure.
Would I recommend Codex?
Absolutely. But only in certain use-cases. It has its pros and cons, as does every AI agent. My testing has found Codex is very helpful with smaller isolated issues and improvements. Tell it to target several files, a class, a module, and it thrives. Tell it to scan the entire repository, it falls down, things get missed, not everything is accounted for.
I will always recommend sense-checking any code that an AI agent produces, and ensure it works for your specific project and use-case. Don't blindly trust. Test and then test again.
I will definitely be using Codex as an assistant to my development efforts in the future, it's proved itself a capable sidekick.
Until next time 👋