
Refactoring your Python App with 12-Factor Methodology
Streamlined refactoring with Amazon Q Developer and /dev agent
Introduction
In this article, we’ll explore how to refactor a Python task management app using Amazon Q Developer and the /dev agent to better align with the 12-factor methodology. The 12-factor methodology, developed by Heroku, is a set of best practices for building scalable and maintainable software-as-a-service (SaaS) apps.
Amazon Q Developer is an AI-powered tool designed to assist with code analysis, refactoring suggestions, and adherence to best practices. The /dev agent is an AI assistant capable of performing actions in a code workspace based on natural language instructions. By combining these tools, we can streamline the process of enhancing our app to follow the 12-factor principles more closely.
Step 1: Analyzing the Existing Codebase
The first step was to use Amazon Q Developer to review the existing codebase. Our goal was to identify areas where the app could be improved to align more closely with the 12-factor methodology. The 12-factor methodology advocates treating backing services (e.g., databases, message brokers) as attached resources, configured via environment variables, and various other recommendations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# app.py
from flask import Flask, request, jsonify
app = Flask(__name__)
# In-memory storage for tasks
tasks = []
def hello():
return "Welcome to the Task Management App!"
def get_tasks():
return jsonify(tasks)
def add_task():
task = request.json.get("task")
if task:
new_task = {"id": len(tasks) + 1, "task": task, "completed": False}
tasks.append(new_task)
return jsonify(new_task), 201
return jsonify({"error": "Invalid task"}), 400
def update_task(task_id):
task = next((task for task in tasks if task["id"] == task_id), None)
if task:
task["completed"] = request.json.get("completed", task["completed"])
return jsonify(task)
return jsonify({"error": "Task not found"}), 404
def delete_task(task_id):
global tasks
tasks = [task for task in tasks if task["id"] != task_id]
return "", 204
if __name__ == "__main__":
app.run(debug=True)
Since the app is a single file currently, we ask Amazon Q Developer in the chat on it's thoughts about the code with the following prompt:
Explain what the application coded in app.py does and mention briefly on how it can be refactored with the 12 factor app methodology

The analysis from Amazon Q Developer highlighted the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
The application in app.py is a simple Flask-based task management API. Here's a breakdown of its functionality:
1. It creates a Flask application instance.
2. It uses an in-memory list to store tasks (as a temporary solution).
3. It defines several routes:
- A root route ("/") that returns a welcome message.
- A GET route ("/tasks") to retrieve all tasks.
- A POST route ("/tasks") to add a new task.
- A PUT route ("/tasks/<task_id>") to update a task's completion status.
- A DELETE route ("/tasks/<task_id>") to remove a task.
4. Each route handles its respective HTTP method and performs operations on the tasks list.
5. The application runs in debug mode when executed directly.
Regarding refactoring with the 12-factor app methodology, here are some brief suggestions: [1]
1. Codebase: The application is already in a single codebase, which is good.
2. Dependencies: Create a requirements.txt file to explicitly declare and isolate dependencies.
3. Config: Move configuration settings (like debug mode) into environment variables.
4. Backing Services: Replace the in-memory list with a proper database, treated as an attached resource.
5. Build, release, run: Separate these stages clearly in your deployment process.
6. Processes: Ensure the app is stateless, moving the task storage to a backing service.
7. Port binding: The app is already designed to be self-contained, which is good.
8. Concurrency: Ensure the app can scale horizontally by running multiple instances.
9. Disposability: Implement graceful shutdown and startup processes.
10. Dev/prod parity: Keep development, staging, and production environments as similar as possible.
11. Logs: Implement proper logging instead of using print statements.
12. Admin processes: Any admin or management tasks should be run as one-off processes in identical environments.
Implementing these factors would make the application more robust, scalable, and easier to maintain, especially in a cloud environment.
Sources
[1] The 12-Factor App Methodology
blog.mikaeels.comtwelve-factor-app-methodologyNow just with based on these insights we get an idea of where to focus our efforts on improving the app’s ability to seamlessly integrate backing services and improving the parity between development and production environments.
This can be done either by:
- Iterating through each step in the 12 factor app roach manually updating the code or asking Amazon Q Developer to suggest code changes and us taking it into consideration.
- Or, we leverage the /dev agent and let it do the work for us!
Step 2: Refactoring with the /dev Agent
By choosing the /dev agent approach to refactor the code, we leverage the agent to implement changes by providing natural language instructions, streamlining the process. And before implementing the changes Amazon Q Developer provided us the recommendations and asks us to verify and approve the changes. Let's see how that went below!
2.1 First pass of implementing the 12 factor app methodology
Opening a new chat window in the Amazon Q Developer extension in VS Code, and typing the
/dev command activates the Amazon Q Developer agent.
Using the below prompt we get the /dev agent to start analyzing and providing us with concrete steps of what can be changed:
Transform the following project using the 12 factor app approach and also generate a step-by-step instruction in a README.md file after refactoring is complete.

The agent begins by diving into the codebase, analyzing and providing real-time updates on its findings, the modifications it's making, and the specific files involved. It starts by mapping out the codebase, quickly honing in on the critical sections that require changes. With each iteration, the agent refines its modifications, testing and adjusting until it achieves the desired outcome. Once complete, it presents a summary of the changes made, detailing the files that have been updated and the improvements implemented.
How cool is that?!
Modifications in each file can be reviewed in the IDE and decided whether to accept them. If the generated code could be improved, feedback can be provided to the agent and request that it regenerates it.
The other thing to notice is that it also generated a test case to test the functionality which is a great way to enforce verifying functional correctness while refactoring.

2.2 Iteration to improve the deployment piece
One thing that was not mentioned explicitly before hand was the target deployment approach. Since it was asked to refactor using the 12 factor methodology, Amazon Q Developer created a
Proc file that can be used as part of deployment to a Heroku account.But what if we want to containerize this and deploy it elsewhere? Asking Amazon Q Developer to do it for us with the following prompt is the next step:
I'm not using Heroku so can you make an alternative implementation of the Procfile with Docker and Docker Swarm? Update the README.md accordingly.

Apart from the findings and modifications, we see the README.md file is updated. Clicking on the suggestion opens a diff view showing what changes will be applied if we accept the code.
2.3 Running the app
Now with any iterative approach to refactoring we have to test out the code and configurations that was generated. The README.md file generated earlier provided the steps needed to leverage the Docker compose command to build and deploy locally.
1
docker-compose up --buildAnd the images are built and run by Docker!

How do we test this though? Maybe asking Amazon Q Developer to suggest sample payloads should work. Heading over to the IDE and tapping on the + sign in Amazon Q Developer to start a new chat, while having the app.py file open in the IDE, the following prompt is entered:
Give me some sample payloads for the flask API I can test with on http://127.0.0.1:5000

Taking the first example and executing from the command line, and... something is not right. Looking at the container logs it shows the following:

Ah, yes! This app initially was using an in-memory store and now we moved to a Postgres database. While verifying the code we did not notice that a table create script or code logic was missing.
No worries, asking Amazon Q Developer the following in the /dev agent chat brings us back on the right track:
The table is not created in the database. add the required scripts to do this after checking if the table exists or not.


And on testing the requests through the VS Code extension Thunder Client, we have success!


Using Amazon Q Developer, we quickly generated this update and ensured that it accurately described the refactoring process.
Conclusion
By utilizing Amazon Q Developer and the /dev agent, we were able to refactor our task management app to better adhere to the 12-factor methodology. These AI-powered tools provided actionable insights, reduced the manual effort required for refactoring, and ensured that best practices were followed throughout the process. The benefits of this approach include:
- Faster identification of issues: Amazon Q Developer quickly pinpointed areas for improvement.
- Efficient refactoring: The /dev agent allowed us to make significant changes with minimal manual intervention.
- Improved maintainability and scalability: The refactor enhanced the app's flexibility and stability, making it easier to scale.
- Educational insights: The AI tools provided clear explanations of best practices, enhancing our understanding of the principles behind the 12-factor methodology.
Next steps
Check out the Amazon Q on AWS Developer Center and documentation . Engage with AWS Community posts here . Also don’t forget to follow AWS Developers social profiles - YouTube , Twitter/X , LinkedIn , Instagram , and Twitch —to stay updated with the latest news and content!
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article