DEV Community

loading...

Debugging Python code in the terminal (with examples)

scarlettperry profile image scarlett ・4 min read

For one of my projects, I wrote a new endpoint in a Flask application. My project had many pieces that built on each other, so I wanted to test in various ways and expand my backend debugging tool belt. Here are 3 tools I learned to use and now regularly use for debugging Python code. 🐍

1. curl

curl is a command line tool for making HTTP requests. I like it because it’s a quick way to test endpoints are doing what I expect, but I found writing a curl confusing at first.

Breaking down the anatomy of a curl

curl get request
Example GET request to retrieve a specific student’s info

-v
is optional and stands for verbose. With it, you’ll see all the details of the request and response that are normally hidden, which can be useful for debugging.

-H
stands for header, and it’s how to specify extra headers to include in the request, such as an authentication token. In my example, the endpoint can only be accessed by school employees, so I’ve added a header to indicate that I am making an internal origin request. Otherwise, the request response would say I’m unauthorized. (It's not necessary to know what Envoy is for the example, but here’s more info if you’re curious: 1 & 2)

You don’t always have to specify extra headers (depends on the API or type of request), and you can include many headers in your request.

curl post request
Example POST request to make a new student

-X POST
will perform a POST request. -X allows you to change the HTTP method used because the default is GET.

-d
stands for data. With this option, you can specify what data you’re sending to the HTTP server, in the same way that a browser does when you fill out a form and click the submit button. There are various ways to pass data in a curl POST request; in my example, I’m sending JSON.

Content-Type
Since I’m sending data, I need to let the server know the format of the data.

2. Python Interpreter

The Python interpreter is a tool that comes with your Python installation. It’s an interactive REPL in which you can type and execute Python code. I use it often to import and interact with the files I’ve written.

Getting Acquainted

test db model schema in python interpreter
service_venv ipython
is how I launch the interpreter. But it’s more commonly invoked by typing python or python3 (depending on your installation). Note: IPython provides extra features than the standard Python interpreter, but the examples I’m showing can be performed in the standard interpreter as well.

from app.models.student import *
imports the specific file to use in the interpreter. I am specifying the directory path of the student.py file: there’s a folder app at the top level directory which contains the folder models which contains the file student.py. import * states that I want everything (*) in that file. Note: when importing a file, do not add the file ending.

The import statement is necessary; without it, in my example, StudentModel and .save() would be undefined and the Python interpreter would throw an error message.

Everything’s setup, and now I can test if my code is working as expected!

python method
testing python method in python interpreter

In this example, I'm testing a specific method get_students in the Python interpreter.

What are some investigations I could do? Perhaps I can test what happens when a user passes in a string value. Or I can see what happens if a user passes in a valid integer value but a student with that id doesn't exist. Am I returning a helpful error message? In the method get_students, I haven't done error handling...yet! In my experience, testing in the Python interpreter has been great for "ooooh yeah need to add that" realizations.

3. Pytest

Pytest is a Python testing framework that can be setup quickly to run tests and report the results. It’s also another command line tool!

testing a method with pytest

Here’s an example of an integration test that tests that a GET call returns the expected data.

I learned how to write tests by studying examples, and I was confused by what values were in a test, like json_body. So, I'd take tests a part and add print statements, like in the example below. But when running the test, I wouldn't see the output of the print statements. 🧐

testing a method with pytest

-s

seeing the console output of pytest results

python -m pytest
is how to invoke testing through the Python interpreter. service_venv is specific to my development environment.

tests/integration/test_student_resource.py
is the directory path of the file I want to test.

-s
is the star of this example. Adding this option allows all print statements in tests to get printed in the terminal when the tests is run. Now I'd be able to see the value of print(json_body).

Pytest is a powerful tool with powerful features, but this small -s flag has helped me to debug and learn how to write tests.

And that's it! I'm excited to see what other debugging tools I pick up as I continue to work on backend projects.

that's all folks!

Discussion (8)

pic
Editor guide
Collapse
mrxinu profile image
Steve Klassen (He/Him)

I love it! Have you ever tried using Postman? It's pretty tasty.

Collapse
scarlettperry profile image
scarlett Author • Edited

Thank you, and I love Postman! It's what I used before I learned how to write curl requests.

Collapse
ramuta profile image
Matej Ramuta • Edited

Great blog post, Scarlett! Btw, if you decide to give GUI REST clients another chance, also try Insomnia 😉

Thread Thread
scarlettperry profile image
scarlett Author

Thank you! Hadn't heard of Insomnia, will check it out. Thanks for the rec!

Collapse
iceorfiresite profile image
Ice or Fire

Great recommendation on Pytest!

Collapse
scarlettperry profile image
Collapse
etampro profile image
Edward Tam

I am surprised that pdb did not make it to the list.

Collapse
scarlettperry profile image
scarlett Author

Definitely a lot more ways to debug. Here I'm sharing what I use often. 😊