Make your dev life easier with make
Yes, pun intended. haha
Recently I've done a code challenge for a company, where I've built an API using Python and FastAPI.
When I deliver, I thought that I should have written a docker-compose and simplified the commands that the reviewers would need to run the application, however, I'm so used to using long lines of docker commands, and making use of the history of my console. That I didn't do one.
A week later, I received the news that I did not pass the test. One point is that they were unable to execute my code. This was very strange for me because they should be able to execute it. But, anyway, they raised a few more points, which were fair for the level of code I was able to provide. So, even though I didn't pass the test, I started to work on the points they made and asked a friend for help to understand all the points. The first thing that Caio (thanks!) suggested was to use a Makefile to run all the commands I put in the README. And that was:
I used makefiles, but working with C ++ and CMake. I once saw a Makefile for a Go project, but I didn't think much about it. That says a lot about me and how I am used to working the same way over and over until something shines for me in a blog post or advice from someone. However, I worked hard on how to use Makefile to make my life easier and I hope to have a second chance with this company …
The first thing that I've made was to set up a docker-compose of the application. You will find all the examples in this Gist.
The compose contained the following services: Postgres, PgAdmin4, and the webserver of my FastAPI application.
After that worked, I started to write the Makefile, so I've made the commands to build my app image and start the application within docker-compose.
build:
docker build --tag=partner-api:latest --file=Dockerfile .
run: build
docker-compose up
stop:
docker-compose stop
So that is clean and simple, and you can note that we abstract to the end-user what is running under the hood. To start the compose I could run make a run
, where two commands are run, the building to make sure that my app image is up-to-date, and the compose-up.
Now, anyone should be able to create a clean virtualenv in their machine and have the development environment configured to run the code locally. So I wrote a couple more of make commands:
install:
pip install -r requirements.txt
install-dev:
pip install -r dev-requirements.txt
create_env:
( \
python -m venv .venv; \
source .venv/bin/activate; \
pip install -r requirements.txt; \
pip install -r dev-requirements.txt; \
)
If you use virtualenvwrapper you could just use the make install
and make install-dev
to set up the environment with your active virtualenv.
Now, every project should have tests, when I delivered the code-challenge, I used tox
to handle the test part, but still, the person using should know tox to properly use. So I wrote a command to set up the database image and run the unit and integration tests.
db:
docker run --name pg --env-file .env -p 5432:5432 -d postgis/postgis
echo wait 20 seconds to guarantee that db is ready
sleep 20
delete_db:
docker stop pg
docker rm pg
Now to run the tox testenv's that I've made:
test:
tox -e test
compliance:
tox -e compliance
format:
tox -e format
diff:
tox -e diff
*Check the tox.ini
on the gist.
Last but not least I've updated the Readme with the system requirements, like Docker, Docker-Compose, Tox, Make, and Python, and explained what each of those make commands do.
I do love to automate my workflow, and it's easier to get up to date to the new ways of doing it when you are working in a company (that I hope to be my case anytime soon), however, within this challenged I've learned a lot, thanks to my colleagues that gave me advice, or searching on Google for that matter. And all of these are templates that can be easily reused in any type of Python application development or in your favorite language. If it can make my life easier, I'm all in on doing it. That's why I was so much dragged into DevOps. But man, I do like to code.
That's all folks!